From d1917149fe33bfb552da712857c5d6eaf88e15e3 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sat, 24 May 2014 16:25:51 +0200 Subject: [PATCH] xbmc: move FM patches to arch specific patches, update FM patches Signed-off-by: Stephan Raue --- .../x86/xbmc-995.01-fernetmenta-fixes.patch | 23667 ++++++++++++++++ ...02-dont-set-_NET_WM_STATE_FULLSCREEN.patch | 0 .../{ => x86}/xbmc-995.03-keymap.patch | 0 ...bmc-995.01-fernetmenta-fixes-b3b79dd.patch | 11231 -------- 4 files changed, 23667 insertions(+), 11231 deletions(-) create mode 100644 packages/mediacenter/xbmc/patches/x86/xbmc-995.01-fernetmenta-fixes.patch rename packages/mediacenter/xbmc/patches/{ => x86}/xbmc-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch (100%) rename packages/mediacenter/xbmc/patches/{ => x86}/xbmc-995.03-keymap.patch (100%) delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch diff --git a/packages/mediacenter/xbmc/patches/x86/xbmc-995.01-fernetmenta-fixes.patch b/packages/mediacenter/xbmc/patches/x86/xbmc-995.01-fernetmenta-fixes.patch new file mode 100644 index 0000000000..913d937d74 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/x86/xbmc-995.01-fernetmenta-fixes.patch @@ -0,0 +1,23667 @@ +From b4096af7aaae5c6090b61b30189d0d79c0dcb6a0 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 18 Jan 2014 12:51:47 +0100 +Subject: [PATCH 001/122] [depends] move ffmpeg to unified deps + +--- + tools/depends/target/Makefile | 4 +- + tools/depends/target/ffmpeg/FFMPEG-VERSION | 5 ++ + tools/depends/target/ffmpeg/Makefile | 80 ++++++++++++++++++++++++++++++ + 3 files changed, 88 insertions(+), 1 deletion(-) + create mode 100644 tools/depends/target/ffmpeg/FFMPEG-VERSION + create mode 100644 tools/depends/target/ffmpeg/Makefile + +diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile +index 4588917..1d5f129 100644 +--- a/tools/depends/target/Makefile ++++ b/tools/depends/target/Makefile +@@ -15,7 +15,7 @@ DEPENDS = \ + python26 afpfs-ng libshairplay \ + libplist libcec libbluray boost tinyxml dummy-libxbmc \ + libamplayer libssh taglib xbmc-pvr-addons libusb libnfs libmp3lame \ +- pythonmodule-pil libxslt ++ pythonmodule-pil libxslt ffmpeg + + ifeq ($(ENABLE_GPLV3),1) + DEPENDS+=samba-gplv3 libcdio-gplv3 +@@ -60,6 +60,7 @@ ifeq ($(OS),linux) + DEPENDS += alsa-lib libsdl linux-system-libs + ALSA_LIB = alsa-lib + LINUX_SYSTEM_LIBS = linux-system-libs ++ FFMPEG_DEPENDS = gnutls + endif + endif + +@@ -96,6 +97,7 @@ nettle: gmp + pythonmodule-pil: $(ZLIB) libjpeg-turbo libpng freetype2 python26 + libsdl: $(LINUX_SYSTEM_LIBS) + libxslt: libgcrypt ++ffmpeg: $(ICONV) $(ZLIB) bzip2 libvorbis $(FFMPEG_DEPENDS) + + .installed-$(PLATFORM): $(DEPENDS) + touch $@ +diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION +new file mode 100644 +index 0000000..850943e +--- /dev/null ++++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION +@@ -0,0 +1,5 @@ ++LIBNAME=ffmpeg ++BASE_URL=https://github.com/FernetMenta/FFmpeg/archive ++VERSION=11086c540305ffb208e6fc17d301db989d3c4151 ++ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz ++ +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +new file mode 100644 +index 0000000..8b95d5c +--- /dev/null ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -0,0 +1,80 @@ ++include ../../Makefile.include ++include FFMPEG-VERSION ++DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ++ ++# set to "yes" to enable patching ++# we don't apply patches until we move to a vanilla ffmpeg tarball ++APPLY_PATCHES=no ++ ++# configuration settings ++ffmpg_config = --prefix=$(PREFIX) ++ffmpg_config += --cc=$(CC) --cxx=$(CXX) ++ffmpg_config += --disable-devices --disable-doc ++ffmpg_config += --disable-ffplay --disable-ffmpeg ++ffmpg_config += --disable-ffprobe --disable-ffserver ++ffmpg_config += --enable-gpl --enable-runtime-cpudetect ++ffmpg_config += --enable-postproc --enable-pthreads ++ffmpg_config += --enable-muxer=spdif --enable-muxer=adts ++ffmpg_config += --enable-muxer=asf --enable-muxer=ipod ++ffmpg_config += --enable-encoder=ac3 --enable-encoder=aac ++ffmpg_config += --enable-encoder=wmav2 --enable-protocol=http ++ifeq ($(CROSS_COMPILING), yes) ++ ffmpg_config += --arch=$(CPU) --enable-cross-compile ++endif ++ifeq ($(OS), linux) ++ ffmpg_config += --target-os=$(OS) --cpu=$(CPU) ++ ffmpg_config += --enable-vdpau --enable-vaapi --enable-gnutls ++ ffmpg_config += --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis ++endif ++ifeq ($(OS), android) ++ ifeq ($(findstring arm, $(CPU)), arm) ++ ffmpg_config += --cpu=cortex-a9 ++ else ++ ffmpg_config += --cpu=i686 --disable-mmx ++ endif ++ ffmpg_config += --target-os=linux ++endif ++ifeq ($(OS), ios) ++ ffmpg_config += --cpu=cortex-a8 --yasmexe=$(NATIVEPREFIX)/bin/yasm ++ ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd ++endif ++ifeq ($(OS), osx) ++ ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd ++endif ++ifeq ($(findstring arm, $(CPU)), arm) ++ ffmpg_config += --enable-pic --disable-armv5te --disable-armv6t2 ++endif ++ifeq ($(Configuration), Release) ++ ffmpg_config += --disable-debug ++endif ++ ++ ++CLEAN_FILES=$(ARCHIVE) $(PLATFORM) ++ ++all: .installed-$(PLATFORM) ++ ++$(TARBALLS_LOCATION)/$(ARCHIVE): ++ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) -Ls --create-dirs -f -o $(TARBALLS_LOCATION)/$(ARCHIVE) $(BASE_URL)/$(VERSION).tar.gz ++ ++$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) ++ rm -rf $(PLATFORM); mkdir -p $(PLATFORM) ++ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) ++ cd $(PLATFORM); sed -i "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig\npkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure ++ cd $(PLATFORM);\ ++ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ ++ ./configure $(ffmpg_config) ++ ++build: $(PLATFORM) ++ $(MAKE) -C $(PLATFORM) ++ ++.installed-$(PLATFORM): build ++ $(MAKE) -C $(PLATFORM) install ++ touch $@ ++ ++clean: ++ $(MAKE) -C $(PLATFORM) clean ++ rm -f .installed-$(PLATFORM) ++ ++distclean:: ++ rm -rf $(PLATFORM) .installed-$(PLATFORM) ++ +-- +1.9.3 + + +From 66d38435ffb7734bfbfdfc5657ba93ff1b61e5ba Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 18 Jan 2014 21:58:35 +0100 +Subject: [PATCH 002/122] [configure] remove internal ffmpeg + +--- + Makefile.in | 14 +- + Makefile.include.in | 3 - + configure.in | 337 ++++++++++--------------------- + tools/depends/target/ffmpeg/autobuild.sh | 166 +++++++++++++++ + 4 files changed, 282 insertions(+), 238 deletions(-) + create mode 100755 tools/depends/target/ffmpeg/autobuild.sh + +diff --git a/Makefile.in b/Makefile.in +index 754f153..bb83339 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -473,13 +473,13 @@ DYNOBJSXBMC+= xbmc/freebsd/freebsd.a + endif + + ifeq (@USE_STATIC_FFMPEG@,1) +-FFMPEGOBJS = lib/ffmpeg/libavcodec/libavcodec.a \ +- lib/ffmpeg/libavfilter/libavfilter.a \ +- lib/ffmpeg/libswresample/libswresample.a \ +- lib/ffmpeg/libavformat/libavformat.a \ +- lib/ffmpeg/libavutil/libavutil.a \ +- lib/ffmpeg/libpostproc/libpostproc.a \ +- lib/ffmpeg/libswscale/libswscale.a ++FFMPEGOBJS = @FFMPEG_LIBDIR@/libavcodec.a \ ++ @FFMPEG_LIBDIR@/libavfilter.a \ ++ @FFMPEG_LIBDIR@/libswresample.a \ ++ @FFMPEG_LIBDIR@/libavformat.a \ ++ @FFMPEG_LIBDIR@/libavutil.a \ ++ @FFMPEG_LIBDIR@/libpostproc.a \ ++ @FFMPEG_LIBDIR@/libswscale.a + DYNOBJSXBMC+= $(FFMPEGOBJS) + LIBS+= @GNUTLS_ALL_LIBS@ @VORBISENC_ALL_LIBS@ @HOGWEED_ALL_LIBS@ + +diff --git a/Makefile.include.in b/Makefile.include.in +index 3452dd9..b409aec 100644 +--- a/Makefile.include.in ++++ b/Makefile.include.in +@@ -44,9 +44,6 @@ INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.addon + INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.pvr + INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.codec + INCLUDES+=$(sort @INCLUDES@) +-ifneq (@USE_EXTERNAL_FFMPEG@,1) +- INCLUDES+=-I@abs_top_srcdir@/lib/ffmpeg +-endif + INCLUDES+=-I@abs_top_srcdir@/xbmc/linux + INCLUDES+=-I@abs_top_srcdir@/xbmc/cores/dvdplayer + DEFINES+= \ +diff --git a/configure.in b/configure.in +index b5ac25e..1a49651 100644 +--- a/configure.in ++++ b/configure.in +@@ -188,13 +188,16 @@ libusb_disabled_udev_found="== libusb disabled. ==" + libcec_enabled="== libcec enabled. ==" + libcec_disabled="== libcec disabled. CEC adapter support will not be available. ==" + +-# External library message strings +-external_libraries_enabled="== Use of all supported external libraries enabled. ==" +-external_libraries_disabled="== Use of all supported external libraries disabled. ==" + dashes="------------------------" + final_message="\n XBMC Configuration:" + final_message="\n$dashes$final_message\n$dashes" + ++AC_ARG_WITH([ffmpeg], ++ [AS_HELP_STRING([--with-ffmpeg], ++ [ffmpeg options: auto (search pkg-config or auto build), force (always build ffmpeg), shared (link dynamically), path_to_ffmpeg [default=force]])], ++ [ffmpeg_dir=$with_ffmpeg], ++ [with_ffmpeg=force]) ++ + AC_ARG_ENABLE([shared-lib], + [AS_HELP_STRING([--enable-shared-lib], + [build libxbmc. helpful for tests (default is no)])], +@@ -207,30 +210,12 @@ AC_ARG_ENABLE([debug], + [use_debug=$enableval], + [use_debug=yes]) + +-AC_ARG_WITH([arch], +- [AS_HELP_STRING([--with-arch], +- [build with given arch passing to internal ffmpeg (default is no, needed for crosscompiling)])], +- [use_arch=$withval], +- [use_arch=no]) +- + AC_ARG_WITH([platform], + [AS_HELP_STRING([--with-platform], + [use a pre-configured config for common arm boards])], + [use_platform=$withval], + [use_platform=none]) + +-AC_ARG_WITH([cpu], +- [AS_HELP_STRING([--with-cpu], +- [build with given cpu passing to ffmpeg (default is no)])], +- [use_cpu=$withval], +- [use_cpu=no]) +- +-AC_ARG_ENABLE([neon], +- [AS_HELP_STRING([--enable-neon], +- [enable neon passing to ffmpeg (default is no)])], +- [use_neon=$enableval], +- [use_neon=no]) +- + AC_ARG_ENABLE([optimizations], + [AS_HELP_STRING([--enable-optimizations], + [enable optimization (default is yes)])], +@@ -423,12 +408,6 @@ AC_ARG_ENABLE([upnp], + [use_upnp=$enableval], + [use_upnp=yes]) + +-AC_ARG_ENABLE([ffmpeg_libvorbis], +- [AS_HELP_STRING([--enable-ffmpeg-libvorbis], +- [enable FFmpeg vorbis encoding (default is no)])], +- [use_ffmpeg_libvorbis=$enableval], +- [use_ffmpeg_libvorbis=no]) +- + AC_ARG_ENABLE([dvdcss], + [AS_HELP_STRING([--enable-dvdcss], + [enable DVDCSS support (default is yes)])], +@@ -562,13 +541,6 @@ AC_ARG_ENABLE([codec], + [add_codecs=$enableval], + [add_codecs=no]) + +-### External libraries options +-AC_ARG_ENABLE([external-libraries], +- [AS_HELP_STRING([--enable-external-libraries], +- [enable use of all supported external libraries (default is no) 'Linux only'])], +- [use_external_libraries=$enableval], +- [use_external_libraries=no]) +- + AC_ARG_ENABLE([libav-compat], + [AS_HELP_STRING([--enable-libav-compat], + [build a wrapper around libav to provide the functions needed by XBMC. This is +@@ -600,17 +572,6 @@ PKG_PROG_PKG_CONFIG + MAKE="${MAKE:-make}" + OBJDUMP="${OBJDUMP:-objdump}" + +-use_external_ffmpeg=no +-use_static_ffmpeg=no +- +-# ffmpeg needs the output of uname -s (e.x. linux, darwin) for the target_os +-# there is no autoconf variable which will give +-# the correct output format when doing cross compilation +-# so we have to use our own var here +-# defaults to the build side target_os +-# and should be overridden for cross below (see android) +-ffmpeg_target_os=$(tolower $(uname -s)) +- + # host detection and setup + case $host in + i*86*-linux-android*) +@@ -618,7 +579,6 @@ case $host in + ARCH="i486-linux" + use_arch="x86" + use_cpu="i686" +- ffmpeg_target_os=linux + use_joystick=no + use_gles=yes + use_optical_drive=no +@@ -632,7 +592,7 @@ case $host in + use_arch="x86" + use_cpu="i686" + fi +- use_static_ffmpeg=yes ++ USE_STATIC_FFMPEG=1 + ;; + x86_64-*-linux-gnu*|x86_64-*-linux-uclibc*) + ARCH="x86_64-linux" +@@ -640,7 +600,7 @@ case $host in + use_arch="x86_64" + use_cpu="x86_64" + fi +- use_static_ffmpeg=yes ++ USE_STATIC_FFMPEG=1 + ;; + i386-*-freebsd*) + ARCH="x86-freebsd" +@@ -689,21 +649,19 @@ case $host in + arm*-*-linux-gnu*|arm*-*-linux-uclibc*) + ARCH="arm" + use_arch="arm" +- ffmpeg_target_os=linux + use_joystick=no + use_neon=yes + use_gles=yes + use_sdl=no + use_x11=no + use_wayland=no +- use_static_ffmpeg=yes ++ USE_STATIC_FFMPEG=1 + ;; + arm*-*linux-android*) + target_platform=target_android + use_arch="arm" + use_cpu=cortex-a9 + ARCH="arm" +- ffmpeg_target_os=linux + use_joystick=no + use_neon=yes + use_gles=yes +@@ -748,7 +706,6 @@ case $use_platform in + USE_OMXLIB=1; AC_DEFINE([HAVE_OMXLIB],[1],["Define to 1 if OMX libs is enabled"]) + CFLAGS="$CFLAGS" + CXXFLAGS="$CXXFLAGS" +- ffmpeg_target_os=linux + ;; + esac + +@@ -824,7 +781,6 @@ if echo "$ARCH" | grep -q "freebsd" ; then + CXXFLAGS="$CXXFLAGS -I$LOCALBASE/include" + CPPFLAGS="$CPPFLAGS -I$LOCALBASE/include" + LDFLAGS="$LDFLAGS -L$LOCALBASE/lib" +- FFMPEG_EXTRACFLAGS="-I$LOCALBASE/include" + fi + if test "$host_vendor" = "apple" ; then + # standard xbmc paths +@@ -845,14 +801,12 @@ if test "$host_vendor" = "apple" ; then + LIBS="$LIBS -framework SystemConfiguration" + LIBS="$LIBS -framework VideoDecodeAcceleration" + fi +- USE_EXTERNAL_FFMPEG=1 + elif test "$target_platform" = "target_raspberry_pi"; then + ARCH="arm" + use_arch="arm" + elif test "$use_arch" = "arm"; then + CFLAGS="$CFLAGS -mno-apcs-stack-check" + CXXFLAGS="$CXXFLAGS -mno-apcs-stack-check" +- FFMPEG_EXTRACFLAGS="" + if test "$use_tegra" = "yes"; then + # Compile for ARMv7a architecture, need to test gcc for vfpv3-d16 support + SAVE_CFLAGS="$CFLAGS" +@@ -861,7 +815,6 @@ elif test "$use_arch" = "arm"; then + [AC_LANG_SOURCE([int foo;])], + [ CFLAGS="$SAVE_CFLAGS -Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" + CXXFLAGS="$CXXFLAGS -Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" +- FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -mtune=cortex-a9 -mfpu=vfpv3-d16" + use_cpu=cortex-a9], + [ CFLAGS="$SAVE_CFLAGS -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork" + CXXFLAGS="$CXXFLAGS -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork" +@@ -870,19 +823,9 @@ elif test "$use_arch" = "arm"; then + if test "$use_neon" = "yes"; then + CFLAGS="$CFLAGS -mfpu=neon -mvectorize-with-neon-quad" + CXXFLAGS="$CXXFLAGS -mfpu=neon -mvectorize-with-neon-quad" +- FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -mfpu=neon" + fi + fi + fi +-if test "$use_static_ffmpeg" = "yes"; then +- USE_STATIC_FFMPEG=1 +- AC_DEFINE([USE_STATIC_FFMPEG], [1], [link ffmpeg statically]) +- # ffmpeg may depend on gnutls and vorbisenc, we add those libs at the end of linker +- # command in order to resolve any missing symbols +- GNUTLS_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors gnutls` +- HOGWEED_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors hogweed nettle` +- VORBISENC_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc` +-fi + + # Checks for library functions. + AC_FUNC_ALLOCA +@@ -1118,7 +1061,7 @@ if test "$gcrypt_headers_available" = "yes"; then + AC_CHECK_LIB([gcrypt],[gcry_control],, AC_MSG_ERROR($missing_library)) + AC_DEFINE([HAVE_GCRYPT],[1],[Define if we have gcrypt]) + fi +-PKG_CHECK_MODULES([GNUTLS], [gnutls], [have_gnutls=yes];AC_DEFINE([HAVE_GNUTLS], [1], [Define if we have gnutls]), AC_MSG_WARN("gnutls not found, ffmpeg TLS support disabled")) ++PKG_CHECK_MODULES([GNUTLS], [gnutls], [have_gnutls=yes];AC_DEFINE([HAVE_GNUTLS], [1], [Define if we have gnutls]), AC_MSG_WARN("gnutls not found")) + + AC_CHECK_LIB([bz2], [main],, AC_MSG_ERROR($missing_library)) + AC_CHECK_LIB([jpeg], [main],, AC_MSG_ERROR($missing_library)) # check for cximage +@@ -1769,40 +1712,108 @@ else + AC_MSG_NOTICE($libcap_disabled) + fi + +-### External libraries checks +- +-# Hacks for supporting libav ++# FFmpeg ++FFMPEG_LIBNAMES="libavcodec >= 55.39.101 ++ libavfilter >= 3.90.100 ++ libavformat >= 55.19.104 ++ libavutil >= 52.48.101 ++ libpostproc >= 52.3.100 ++ libswscale >= 2.5.101 ++ libswresample >= 0.17.104" ++ ++if test "$with_ffmpeg" = "shared"; then ++ # allow linking against shared ffmpeg libs ++ # a proper version must be installed, we won't build ffmpeg ++ USE_STATIC_FFMPEG=0 ++ AC_DEFINE([USE_STATIC_FFMPEG], [0], [FFmpeg linked dynamically]) ++fi ++if test "${USE_STATIC_FFMPEG}" = "1"; then ++ AC_DEFINE([USE_STATIC_FFMPEG], [1], [FFmpeg linked statically]) ++ ff_libs=$(${ECHO} ${FFMPEG_LIBNAMES} | ${AWK} '/lib/{print $1}' ORS=' ') ++ if test -n "${PKG_CONFIG_SYSROOT_DIR}"; then ++ # workaround for cross compiling with buildroot on different buildsystem ++ # Rpi buildroots pkg-config returns static libs with ++ # PKG_CONFIG_SYSROOT_DIR prefixed, OEs does not ++ # so lets make sure we always prefix in case PKG_CONFIG_SYSROOT_DIR is defined ++ pkg_cfg_prefix="${PKG_CONFIG_SYSROOT_DIR}" ++ elif test "${target_platform}" = "target_raspberry_pi" && test "${USE_BUILDROOT}" = "1"; then ++ pkg_cfg_prefix=${SYSROOT} ++ fi + +-USE_LIBAV_HACKS=0 +-if test "$use_libav_hacks" = "yes"; then +- export PKG_CONFIG_PATH="${srcdir}/lib/xbmc-libav-hacks/pkgconfig/:$PKG_CONFIG_PATH" +- USE_LIBAV_HACKS=1 +- AC_DEFINE([USE_LIBAV_HACKS], [1], [Whether to use libav compatibility hacks.]) +-fi ++ if test "$cross_compiling" != "yes"; then ++ ffmpeg_build="${abs_top_srcdir}/tools/depends/target/ffmpeg" ++ if test "$use_debug" != "yes"; then ++ FFMPEG_OPTS="-r" ++ fi ++ if test "$use_optimizations" != "yes"; then ++ FFMPEG_OPTS="${FFMPEG_OPTS} --disable-optimizations" ++ fi + +-# External FFmpeg +-if test "$use_external_ffmpeg" = "yes"; then +- FFMPEG_LIBNAMES="libavcodec libavfilter libavformat libavutil libpostproc libswscale libswresample" ++ if test "$with_ffmpeg" = "auto" || test "$with_ffmpeg" = "yes"; then ++ SAVE_INCLUDES="$INCLUDES" ++ SAVE_LIBS="$LIBS" ++ # check for system installed ffmpeg. We require minimum versions. ++ PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], ++ [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], ++ [FFMPEG_FOUND="false"]) ++ ++ if test "${USE_STATIC_FFMPEG}" = "1" && test "$FFMPEG_FOUND" = "true"; then ++ # we need to check if static libs are available ++ FFMPEG_LIBDIR=$(${PKG_CONFIG} --static --variable=libdir libavcodec) ++ for ff_lib in ${ff_libs}; do ++ if test -f ${FFMPEG_LIBDIR}/${ff_lib}.a; then :; else ++ AC_MSG_NOTICE("${FFMPEG_LIBDIR}/${ff_lib}.a not found") ++ FFMPEG_FOUND="false" ++ # restore includes and libs, the ones we found are invalid ++ INCLUDES="$SAVE_INCLUDES" ++ LIBS="$SAVE_LIBS" ++ unset FFMPEG_LIBS FFMPEG_CFLAGS FFMPEG_LIBDIR ++ fi ++ done ++ fi ++ if test "$with_ffmpeg" = "yes" || test "$FFMPEG_FOUND" = "false"; then ++ # ffmpeg not found with pkg-config, lets install it ++ AC_MSG_NOTICE("Installing FFmpeg") ++ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ${ffmpeg_build}/autobuild.sh ${FFMPEG_OPTS} ++ export PKG_CONFIG_PATH="${ffmpeg_build}/ffmpeg-install/lib/pkgconfig:$PKG_CONFIG_PATH" ++ fi + +- PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], +- [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"], +- AC_MSG_ERROR($missing_library)) ++ elif test "$with_ffmpeg" = "force"; then ++ # always build our ffmpeg ++ AC_MSG_NOTICE("FFmpeg installation forced by user - installing our version") ++ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ${ffmpeg_build}/autobuild.sh ${FFMPEG_OPTS} ++ export PKG_CONFIG_PATH="${ffmpeg_build}/ffmpeg-install/lib/pkgconfig:$PKG_CONFIG_PATH" + +- # in case the headers are in a custom directory +- SAVE_CPPFLAGS="$CPPFLAGS" +- CPPFLAGS="$CPPFLAGS $FFMPEG_CFLAGS" ++ elif test "$with_ffmpeg" != "no"; then ++ # user passed --with-ffmpeg=/some/path, lets use it ++ AC_MSG_NOTICE("using ffmpeg: ${with_ffmpeg}") ++ export PKG_CONFIG_PATH="${with_ffmpeg}/lib/pkgconfig:$PKG_CONFIG_PATH" ++ fi ++ fi ++fi + +- AC_CHECK_HEADERS([libavcodec/avcodec.h libavfilter/avfilter.h libavformat/avformat.h libavutil/avutil.h libpostproc/postprocess.h libswscale/swscale.h],, +- [AC_MSG_ERROR($missing_headers)]) ++if test "$FFMPEG_FOUND" != "true"; then ++ PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], ++ [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], ++ [AC_MSG_ERROR("ffmpeg not found")]) ++fi + +- AC_MSG_NOTICE($external_ffmpeg_enabled) +- USE_EXTERNAL_FFMPEG=1 +- AC_DEFINE([USE_EXTERNAL_FFMPEG], [1], [Whether to use external FFmpeg libraries.]) ++if test "${USE_STATIC_FFMPEG}" = "1"; then ++ # get the libdir for static linking ++ FFMPEG_LIBDIR=${pkg_cfg_prefix}$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --variable=libdir libavcodec) ++ GNUTLS_ALL_LIBS=$(${PKG_CONFIG} --static --libs-only-l --silence-errors gnutls) ++ VORBISENC_ALL_LIBS=$(${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc) + +- CPPFLAGS="$SAVE_CPPFLAGS" +-else +- AC_MSG_NOTICE($external_ffmpeg_disabled) +- USE_EXTERNAL_FFMPEG=0 ++ # check if static libs are available ++ for ff_lib in ${ff_libs}; do ++ if test -f ${FFMPEG_LIBDIR}/${ff_lib}.a; then :; else ++ AC_MSG_ERROR("${FFMPEG_LIBDIR}/${ff_lib}.a not found") ++ fi ++ # filter out libs we link statically ++ filter=$(${ECHO} ${ff_lib} | ${SED} 's/lib/-l/g') ++ LIBS=$(${ECHO} ${LIBS} | ${SED} "s/${filter}//g") ++ done ++ LIBS=$(${ECHO} ${LIBS} | ${SED} ':a;N;$!ba;s/\n/ /g') + fi + + echo "Checking for SWIG installation" +@@ -2482,12 +2493,6 @@ fi + + ### External libraries messages + +-if test "$use_external_ffmpeg" = "yes"; then +- final_message="$final_message\n External FFmpeg:\tYes" +-else +- final_message="$final_message\n External FFmpeg:\tNo" +-fi +- + if test "$host_vendor" = "apple" ; then + # built internal but referenced as external, we link directly to them. + # this MUST be the last thing before OUTPUT_FILES as they do not +@@ -2626,9 +2631,11 @@ AC_SUBST(DISABLE_GOOM) + AC_SUBST(DISABLE_RSXS) + AC_SUBST(DISABLE_FISHBMC) + AC_SUBST(DISABLE_PROJECTM) +-AC_SUBST(USE_SKIN_TOUCHED) +-AC_SUBST(USE_EXTERNAL_FFMPEG) ++AC_SUBST(FFMPEG_LIBDIR) + AC_SUBST(USE_STATIC_FFMPEG) ++AC_SUBST(GNUTLS_ALL_LIBS) ++AC_SUBST(VORBISENC_ALL_LIBS) ++AC_SUBST(USE_SKIN_TOUCHED) + AC_SUBST(USE_LIBAV_HACKS) + AC_SUBST(PYTHON_VERSION) + AC_SUBST(OUTPUT_FILES) +@@ -2728,132 +2735,6 @@ fi + ]) + ]) + +-XB_CONFIG_MODULE([lib/ffmpeg], [ +- if test "$host_vendor" = "apple" ; then +- ffmpg_config="--target-os=$ffmpeg_target_os" +- # handle disables first, we do individual enables later +- ffmpg_config="$ffmpg_config --disable-muxers --disable-encoders" +- ffmpg_config="$ffmpg_config --disable-devices --disable-doc" +- ffmpg_config="$ffmpg_config --disable-ffplay --disable-ffmpeg" +- ffmpg_config="$ffmpg_config --disable-ffprobe --disable-ffserver" +- ffmpg_config="$ffmpg_config --enable-vda --disable-crystalhd" +- ffmpg_config="$ffmpg_config --disable-decoder=mpeg_xvmc" +- +- # handle conditional enables/disables +- if test "$use_debug" = "no"; then +- ffmpg_config="$ffmpg_config --disable-debug" +- fi +- if test "$use_cpu" != "no"; then +- ffmpg_config="$ffmpg_config --cpu=$use_cpu" +- fi +- if test "$use_arch" != "no"; then +- ffmpg_config="$ffmpg_config --arch=$use_arch --enable-cross-compile" +- fi +- if test "$use_arch" = "arm"; then +- ffmpg_config="$ffmpg_config --enable-pic" +- ffmpg_config="$ffmpg_config --disable-armv5te --disable-armv6t2" +- if test "$use_neon" = "yes"; then +- ffmpg_config="$ffmpg_config --enable-neon" +- else +- ffmpg_config="$ffmpg_config --disable-neon" +- fi +- else +- ffmpg_config="$ffmpg_config --disable-amd3dnow" +- fi +- if test "$use_ffmpeg_libvorbis" = "yes"; then +- ffmpg_config="$ffmpg_config --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis" +- else +- ffmpg_config="$ffmpg_config --disable-libvorbis" +- fi +- if test "$have_gnutls" = "yes"; then +- ffmpg_config="$ffmpg_config --enable-gnutls" +- fi +- +- # handle individual enables +- ffmpg_config="$ffmpg_config --enable-gpl" +- ffmpg_config="$ffmpg_config --enable-postproc" +- ffmpg_config="$ffmpg_config --enable-static --enable-pthreads" +- ffmpg_config="$ffmpg_config --enable-muxer=spdif --enable-muxer=adts --enable-muxer=asf --enable-muxer=ipod" +- ffmpg_config="$ffmpg_config --enable-encoder=ac3 --enable-encoder=aac --enable-encoder=wmav2" +- ffmpg_config="$ffmpg_config --enable-protocol=http" +- ffmpg_config="$ffmpg_config --enable-runtime-cpudetect" +- +- # ffmpeg will not compile with llvm-gcc-4.2, use clang instead +- case $CC in +- *llvm-gcc-4.2*) +- ffmpg_config="$ffmpg_config --cc=clang" ;; +- *) +- ffmpg_config="$ffmpg_config --cc=$CC" ;; +- esac +- +- # extra-cflags must be passed alone or it gets expanded wrong by the ffmpeg configure +- FFMPEG_EXTRACFLAGS="$CFLAGS $FFMPEG_EXTRACFLAGS -w -D_DARWIN_C_SOURCE -Dattribute_deprecated=" +- +- LDFLAGS="$LDFLAGS" ./configure --extra-cflags="$FFMPEG_EXTRACFLAGS" $ffmpg_config --as="$AS" +- +- # if using llvm-gcc-4.2 as assembler, -MMD is not enough to generate +- # dependency files in the right place, replace it with something that works +- case $AS in +- *llvm-gcc-4.2*) +- sed -ie "s#AS_DEPFLAGS=-MMD#AS_DEPFLAGS=-MMD -MF \$(\@:.o=.d) -MT \$\@#" config.mak ;; +- esac +- +- # ffmpeg will use yasm found at ${prefix}/bin during configure +- # but then hardcodes 'yasm' in config.mak, fix it. +- sed -ie "s#YASM=yasm#YASM=${YASM}#" config.mak +- sed -ie "s#YASMDEP=yasm#YASMDEP=${YASM}#" config.mak +- sed -ie "s# -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 # #" config.mak +- else +- CFLAGS="" \ +- CPPFLAGS="" \ +- CXXFLAGS="" \ +- LDFLAGS="$(echo "$LDFLAGS" | sed "s/-Wl,-Bsymbolic-functions//g")" \ +- ./configure \ +- --extra-cflags="$PASSED_CFLAGS $FFMPEG_EXTRACFLAGS" \ +- `if test "$use_debug" = "no"; then echo --disable-debug; fi` \ +- `if test "$cross_compiling" = "yes"; then echo --enable-cross-compile; fi` \ +- `if test "$use_arch" != "no"; then echo --arch=$use_arch; fi`\ +- `if test "$use_cpu" != "no"; then echo --cpu=$use_cpu; fi`\ +- `if test "$use_neon" = "yes"; then echo --enable-neon; else echo --disable-neon; fi`\ +- --target-os=$ffmpeg_target_os \ +- --disable-muxers \ +- --enable-muxer=spdif \ +- --enable-muxer=adts \ +- --enable-muxer=asf \ +- --enable-muxer=ipod \ +- --disable-encoders \ +- --enable-encoder=ac3 \ +- --enable-encoder=aac \ +- --enable-encoder=wmav2 \ +- `if test "$use_ffmpeg_libvorbis" = "yes"; then echo --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis; else echo --disable-libvorbis; fi` \ +- --disable-decoder=mpeg_xvmc \ +- --disable-devices \ +- --disable-ffprobe \ +- --disable-ffplay \ +- --disable-ffserver \ +- --disable-ffmpeg \ +- --disable-crystalhd \ +- `if test "$use_static_ffmpeg" = "yes"; then echo --enable-static --disable-shared; else echo --disable-static --enable-shared; fi` \ +- --disable-doc \ +- --enable-postproc \ +- --enable-gpl \ +- `if test "x$use_vdpau" != "xno"; then echo --enable-vdpau; else echo --disable-vdpau; fi` \ +- `if test "x$use_vaapi" != "xno"; then echo --enable-vaapi; else echo --disable-vaapi; fi` \ +- `if test "$use_optimizations" != "no"; then echo --enable-optimizations; else echo --disable-optimizations; fi` \ +- --enable-protocol=http \ +- `if test "$have_gnutls" = "yes"; then echo --enable-gnutls; fi` \ +- --enable-pthreads \ +- --enable-runtime-cpudetect \ +- `if test "$use_hardcoded_tables" = "yes"; then echo --enable-hardcoded-tables; else echo --disable-hardcoded-tables; fi`\ +- `if test "$target_platform" = "target_android"; then echo "--custom-libname-with-major=\\$(SLIBPREF)\\$(FULLNAME)-\\$(LIBMAJOR)-${ARCH}\\$(SLIBSUF)"; \ +- else echo "--custom-libname-with-major=\\$(FULLNAME)-\\$(LIBMAJOR)-${ARCH}\\$(SLIBSUF)"; fi` \ +- `case $host_cpu in i?86*) echo --disable-pic ;; *) echo --enable-pic ;; esac` \ +- --cc="$CC" && +- sed -i -e "s#define HAVE_SYMVER 1#define HAVE_SYMVER 0#" config.h && +- sed -i -e "s#define HAVE_SYMVER_GNU_ASM 1#define HAVE_SYMVER_GNU_ASM 0#" config.h +- fi +-], [$USE_EXTERNAL_FFMPEG]) +- + XB_CONFIG_MODULE([lib/libdvd/libdvdcss], [ + ./configure \ + CC="$CC" \ +diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh +new file mode 100755 +index 0000000..b7a1ba6 +--- /dev/null ++++ b/tools/depends/target/ffmpeg/autobuild.sh +@@ -0,0 +1,166 @@ ++#!/bin/bash ++# ++# Copyright (C) 2005-2013 Team XBMC ++# http://xbmc.org ++# ++# This Program 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, or (at your option) ++# any later version. ++# ++# This Program 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 XBMC; see the file COPYING. If not, see ++# . ++# ++ ++ ++MYDIR=$(cd $(dirname $0); pwd) ++cd $MYDIR ++FFMPEG_PREFIX=${MYDIR}/ffmpeg-install ++ ++BASE_URL=$(grep "BASE_URL=" FFMPEG-VERSION | sed 's/BASE_URL=//g') ++VERSION=$(grep "VERSION=" FFMPEG-VERSION | sed 's/VERSION=//g') ++ARCHIVE=ffmpeg-${VERSION}.tar.gz ++ ++function usage { ++ echo "usage $(basename $0) ++ [-p | --prefix] ... ffmepg install prefix ++ [-d | --download] ... no build, download tarfile only ++ [-r | --release] ... disable debugging symbols ++ [-j] ... make concurrency level ++ [--cpu=CPU] ... minimum required CPU ++ [--arch=ARCH] ... select architecture ++ [--disable-optimizations] ++ " ++} ++ ++while : ++do ++ case $1 in ++ -h | --help) ++ usage ++ exit 0 ++ ;; ++ -p | --prefix) ++ FFMPEG_PREFIX=$2 ++ shift 2 ++ ;; ++ --prefix=*) ++ FFMPEG_PREFIX=${1#*=} ++ shift ++ ;; ++ -d | --download) ++ downloadonly=true ++ shift ++ ;; ++ -r | --release) ++ FLAGS="$FLAGS --disable-debug" ++ shift ++ ;; ++ --disable-optimizations) ++ FLAGS="$FLAGS --disable-optimizations" ++ shift ++ ;; ++ --cpu=*) ++ FLAGS="$FLAGS --cpu=${1#*=}" ++ shift ++ ;; ++ --arch=*) ++ FLAGS="$FLAGS --arch=${1#*=}" ++ shift ++ ;; ++ --extra-cflags=*) ++ FLAGS="$FLAGS --extra-cflags=\"${1#*=}\"" ++ shift ++ ;; ++ --extra-cxxflags=*) ++ FLAGS="$FLAGS --extra-cxxflags=\"${1#*=}\"" ++ shift ++ ;; ++ -j) ++ BUILDTHREADS=$2 ++ shift 2 ++ ;; ++ --) ++ shift ++ break ++ ;; ++ -*) ++ echo "WARN: Unknown option (ignored): $1" >&2 ++ shift ++ ;; ++ *) ++ break ++ ;; ++ esac ++done ++ ++BUILDTHREADS=${BUILDTHREADS:-$(grep -c processor /proc/cpuinfo)} ++ ++[ -z ${VERSION} ] && exit 3 ++if [ -f ${FFMPEG_PREFIX}/lib/pkgconfig/libavcodec.pc ] && [ -f .ffmpeg-installed ] ++then ++ CURVER=$(cat .ffmpeg-installed) ++ [ "$VERSION" == "$CURVER" ] && exit 0 ++fi ++ ++[ -f ${ARCHIVE} ] || curl -Ls --create-dirs -f -o ${ARCHIVE} ${BASE_URL}/${VERSION}.tar.gz ++[ $downloadonly ] && exit 0 ++ ++[ -d ffmpeg-${VERSION} ] && rm -rf ffmpeg-${VERSION} && rm .ffmpeg-installed >/dev/null 2>&1 ++if [ -d ${FFMPEG_PREFIX} ] ++then ++ [ -w ${FFMPEG_PREFIX} ] || SUDO="sudo" ++else ++ [ -w $(dirname ${FFMPEG_PREFIX}) ] || SUDO="sudo" ++fi ++ ++mkdir ffmpeg-${VERSION} ++cd ffmpeg-${VERSION} || exit 2 ++tar --strip-components=1 -xf ../${ARCHIVE} ++ ++CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" \ ++./configure --prefix=$FFMPEG_PREFIX \ ++ --disable-devices \ ++ --disable-ffplay \ ++ --disable-ffmpeg \ ++ --disable-ffprobe \ ++ --disable-ffserver \ ++ --disable-doc \ ++ --enable-gpl \ ++ --enable-runtime-cpudetect \ ++ --enable-postproc \ ++ --enable-vaapi \ ++ --enable-vdpau \ ++ --enable-bzlib \ ++ --enable-gnutls \ ++ --enable-muxer=spdif \ ++ --enable-muxer=adts \ ++ --enable-muxer=asf \ ++ --enable-muxer=ipod \ ++ --enable-encoder=ac3 \ ++ --enable-encoder=aac \ ++ --enable-encoder=wmav2 \ ++ --enable-protocol=http \ ++ --enable-libvorbis \ ++ --enable-muxer=ogg \ ++ --enable-encoder=libvorbis \ ++ --enable-nonfree \ ++ --enable-pthreads \ ++ --enable-zlib \ ++ ${FLAGS} ++ ++make -j ${BUILDTHREADS} ++if [ $? -eq 0 ] ++then ++ [ ${SUDO} ] && echo "Root priviledges are required to install to ${FFMPEG_PREFIX}" ++ ${SUDO} make install && echo "$VERSION" > ../.ffmpeg-installed ++else ++ echo "ERROR: building ffmpeg failed" ++ exit 1 ++fi +-- +1.9.3 + + +From 3872359c850f3053aacaca95319819dead320738 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 22 Jan 2014 11:45:48 +0100 +Subject: [PATCH 003/122] ffmpeg: remove dll wrappers + +--- + Makefile.in | 6 - + configure.in | 1 - + lib/DllAvCodec.h | 281 ------------- + lib/DllAvFilter.h | 313 -------------- + lib/DllAvFormat.h | 322 --------------- + lib/DllAvUtil.h | 291 ------------- + lib/DllPostProc.h | 129 ------ + lib/DllSwResample.h | 131 ------ + lib/DllSwScale.h | 153 ------- + lib/Makefile.in | 103 ----- + lib/xbmc-dll-symbols/DllAvFormat.c | 126 ------ + lib/xbmc-dll-symbols/Makefile | 6 - + lib/xbmc-libav-hacks/Makefile | 6 - + lib/xbmc-libav-hacks/accessors.c | 35 -- + lib/xbmc-libav-hacks/alloc_output_context2.c | 80 ---- + lib/xbmc-libav-hacks/buffersink.c | 36 -- + lib/xbmc-libav-hacks/graphparser.c | 451 --------------------- + lib/xbmc-libav-hacks/libav_hacks.h | 96 ----- + lib/xbmc-libav-hacks/pkgconfig/libswresample.pc | 4 - + lib/xbmc-libav-hacks/swresample.c | 80 ---- + xbmc/addons/AddonCallbacksCodec.cpp | 22 +- + xbmc/cdrip/EncoderFFmpeg.cpp | 162 ++++---- + xbmc/cdrip/EncoderFFmpeg.h | 15 +- + .../cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 61 ++- + xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h | 12 +- + .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 71 ++-- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h | 13 +- + .../AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h | 7 +- + .../Engines/ActiveAE/ActiveAEResample.cpp | 66 +-- + .../Engines/ActiveAE/ActiveAEResample.h | 9 +- + .../AudioEngine/Engines/ActiveAE/ActiveAESound.cpp | 7 +- + .../AudioEngine/Engines/ActiveAE/ActiveAESound.h | 2 +- + xbmc/cores/AudioEngine/Interfaces/AEEncoder.h | 5 +- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 9 +- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.h | 10 +- + xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 35 +- + xbmc/cores/VideoRenderers/LinuxRendererGL.h | 3 - + xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 20 +- + xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 4 - + xbmc/cores/VideoRenderers/WinRenderer.cpp | 2 +- + xbmc/cores/VideoRenderers/WinRenderer.h | 3 - + xbmc/cores/dvdplayer/DVDAudio.h | 4 +- + .../dvdplayer/DVDCodecs/Audio/DVDAudioCodec.h | 5 +- + .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 57 ++- + .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.h | 15 +- + xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 20 +- + .../DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp | 39 +- + .../DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h | 11 +- + .../DVDCodecs/Overlay/DVDOverlayCodecText.h | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp | 16 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 6 +- + .../DVDCodecs/Video/DVDVideoCodecCrystalHD.cpp | 4 +- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 205 +++------- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 27 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp | 25 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h | 2 - + .../DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp | 164 ++++---- + .../DVDCodecs/Video/DVDVideoCodecVideoToolBox.h | 5 - + .../dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp | 15 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.h | 4 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 2 + + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 7 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 11 +- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 5 +- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 134 +++--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 15 +- + .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 25 +- + .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h | 10 +- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp | 5 +- + xbmc/cores/dvdplayer/DVDFileInfo.cpp | 15 +- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 +- + xbmc/cores/dvdplayer/DVDStreamInfo.h | 5 +- + xbmc/cores/omxplayer/OMXAudio.cpp | 11 +- + xbmc/cores/omxplayer/OMXAudio.h | 8 +- + xbmc/cores/omxplayer/OMXAudioCodec.h | 2 +- + xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 65 ++- + xbmc/cores/omxplayer/OMXAudioCodecOMX.h | 14 +- + xbmc/cores/omxplayer/OMXPlayer.cpp | 2 +- + xbmc/linux/OMXCore.h | 2 +- + xbmc/music/karaoke/karaokevideobackground.cpp | 12 +- + xbmc/pictures/Picture.cpp | 14 +- + xbmc/utils/BitstreamConverter.cpp | 118 +++--- + xbmc/utils/BitstreamConverter.h | 13 +- + xbmc/video/FFmpegVideoDecoder.cpp | 89 ++-- + xbmc/video/FFmpegVideoDecoder.h | 11 +- + 89 files changed, 742 insertions(+), 3677 deletions(-) + delete mode 100644 lib/DllAvCodec.h + delete mode 100644 lib/DllAvFilter.h + delete mode 100644 lib/DllAvFormat.h + delete mode 100644 lib/DllAvUtil.h + delete mode 100644 lib/DllPostProc.h + delete mode 100644 lib/DllSwResample.h + delete mode 100644 lib/DllSwScale.h + delete mode 100644 lib/Makefile.in + delete mode 100644 lib/xbmc-dll-symbols/DllAvFormat.c + delete mode 100644 lib/xbmc-dll-symbols/Makefile + delete mode 100644 lib/xbmc-libav-hacks/Makefile + delete mode 100644 lib/xbmc-libav-hacks/accessors.c + delete mode 100644 lib/xbmc-libav-hacks/alloc_output_context2.c + delete mode 100644 lib/xbmc-libav-hacks/buffersink.c + delete mode 100644 lib/xbmc-libav-hacks/graphparser.c + delete mode 100644 lib/xbmc-libav-hacks/libav_hacks.h + delete mode 100644 lib/xbmc-libav-hacks/pkgconfig/libswresample.pc + delete mode 100644 lib/xbmc-libav-hacks/swresample.c + +diff --git a/Makefile.in b/Makefile.in +index bb83339..5339447 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -35,7 +35,6 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \ + lib/libXDAAP/libxdaap.a \ + lib/libhts/libhts.a \ + lib/libsquish/libsquish.a \ +- lib/xbmc-dll-symbols/dll-symbols.a \ + xbmc/addons/addons.a \ + xbmc/cdrip/cdrip.a \ + xbmc/cores/AudioEngine/audioengine.a \ +@@ -187,10 +186,6 @@ ifeq (@USE_OMXPLAYER@,1) + DIRECTORY_ARCHIVES += xbmc/cores/omxplayer/omxplayer.a + endif + +-ifeq (@USE_LIBAV_HACKS@,1) +-DIRECTORY_ARCHIVES += lib/xbmc-libav-hacks/dll-libavhacks.a +-endif +- + PAPCODECS_DIRS= \ + lib/nosefart \ + lib/timidity \ +@@ -393,7 +388,6 @@ libaddon: exports + $(MAKE) -C lib/addons/library.xbmc.gui + $(MAKE) -C lib/addons/library.xbmc.pvr + dvdpcodecs: dllloader +- $(MAKE) -C lib + $(MAKE) -C lib/libdvd + + ifeq (@USE_LIBSTAGEFRIGHT@,1) +diff --git a/configure.in b/configure.in +index 1a49651..a324a0d 100644 +--- a/configure.in ++++ b/configure.in +@@ -2524,7 +2524,6 @@ OUTPUT_FILES="Makefile \ + xbmc/cores/Makefile \ + xbmc/cores/VideoRenderers/Makefile \ + xbmc/cores/dvdplayer/Makefile \ +- lib/Makefile \ + lib/libdvd/Makefile \ + xbmc/cores/DllLoader/Makefile \ + xbmc/cores/DllLoader/exports/Makefile \ +diff --git a/lib/DllAvCodec.h b/lib/DllAvCodec.h +deleted file mode 100644 +index af13a15..0000000 +--- a/lib/DllAvCodec.h ++++ /dev/null +@@ -1,281 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "DllAvUtil.h" +-#include "utils/log.h" +- +-extern "C" { +-#ifndef HAVE_MMX +-#define HAVE_MMX +-#endif +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS +-#endif +- +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +- +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +-#else +- #include "libavcodec/avcodec.h" +-#endif +-} +- +-#include "threads/SingleLock.h" +- +-class DllAvCodecInterface +-{ +-public: +- virtual ~DllAvCodecInterface() {} +- virtual void avcodec_register_all(void)=0; +- virtual void avcodec_flush_buffers(AVCodecContext *avctx)=0; +- virtual int avcodec_open2_dont_call(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)=0; +- virtual AVCodec *avcodec_find_decoder(enum AVCodecID id)=0; +- virtual AVCodec *avcodec_find_encoder(enum AVCodecID id)=0; +- virtual int avcodec_close_dont_call(AVCodecContext *avctx)=0; +- virtual AVFrame *avcodec_alloc_frame(void)=0; +- virtual int avpicture_fill(AVPicture *picture, uint8_t *ptr, PixelFormat pix_fmt, int width, int height)=0; +- virtual int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)=0; +- virtual int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)=0; +- virtual int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt)=0; +- virtual int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)=0; +- virtual int avpicture_get_size(PixelFormat pix_fmt, int width, int height)=0; +- virtual AVCodecContext *avcodec_alloc_context3(AVCodec *codec)=0; +- virtual void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)=0; +- virtual void avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec)=0; +- virtual AVCodecParserContext *av_parser_init(int codec_id)=0; +- virtual int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, +- const uint8_t *buf, int buf_size, +- int64_t pts, int64_t dts, int64_t pos)=0; +- virtual void av_parser_close(AVCodecParserContext *s)=0; +- virtual AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)=0; +- virtual int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, +- AVCodecContext *avctx, const char *args, +- uint8_t **poutbuf, int *poutbuf_size, +- const uint8_t *buf, int buf_size, int keyframe) =0; +- virtual void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) =0; +- virtual void avpicture_free(AVPicture *picture)=0; +- virtual void av_free_packet(AVPacket *pkt)=0; +- virtual int avpicture_alloc(AVPicture *picture, PixelFormat pix_fmt, int width, int height)=0; +- virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt)=0; +- virtual AVCodec *av_codec_next(AVCodec *c)=0; +- virtual int av_dup_packet(AVPacket *pkt)=0; +- virtual void av_init_packet(AVPacket *pkt)=0; +- virtual int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) = 0; +- virtual void avcodec_free_frame(AVFrame **frame)=0; +- virtual int av_codec_is_decoder(const AVCodec *codec)=0; +- virtual AVDictionary* av_frame_get_metadata(const AVFrame* frame)=0; +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +- +-// Use direct layer +-class DllAvCodec : public DllDynamic, DllAvCodecInterface +-{ +-public: +- static CCriticalSection m_critSection; +- +- virtual ~DllAvCodec() {} +- virtual void avcodec_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- ::avcodec_register_all(); +- } +- virtual void avcodec_flush_buffers(AVCodecContext *avctx) { ::avcodec_flush_buffers(avctx); } +- virtual int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avcodec_open2(avctx, codec, options); +- } +- virtual int avcodec_open2_dont_call(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { *(volatile int *)0x0 = 0; return 0; } +- virtual int avcodec_close_dont_call(AVCodecContext *avctx) { *(volatile int *)0x0 = 0; return 0; } +- virtual AVCodec *avcodec_find_decoder(enum AVCodecID id) { return ::avcodec_find_decoder(id); } +- virtual AVCodec *avcodec_find_encoder(enum AVCodecID id) { return ::avcodec_find_encoder(id); } +- virtual int avcodec_close(AVCodecContext *avctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avcodec_close(avctx); +- } +- virtual AVFrame *avcodec_alloc_frame() { return ::avcodec_alloc_frame(); } +- virtual int avpicture_fill(AVPicture *picture, uint8_t *ptr, PixelFormat pix_fmt, int width, int height) { return ::avpicture_fill(picture, ptr, pix_fmt, width, height); } +- virtual int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) { return ::avcodec_decode_video2(avctx, picture, got_picture_ptr, avpkt); } +- virtual int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { return ::avcodec_decode_audio4(avctx, frame, got_frame_ptr, avpkt); } +- virtual int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { return ::avcodec_decode_subtitle2(avctx, sub, got_sub_ptr, avpkt); } +- virtual int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { return ::avcodec_encode_audio2(avctx, avpkt, frame, got_packet_ptr); } +- virtual int avpicture_get_size(PixelFormat pix_fmt, int width, int height) { return ::avpicture_get_size(pix_fmt, width, height); } +- virtual AVCodecContext *avcodec_alloc_context3(AVCodec *codec) { return ::avcodec_alloc_context3(codec); } +- virtual void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { ::avcodec_string(buf, buf_size, enc, encode); } +- virtual void avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec) { ::avcodec_get_context_defaults3(s, codec); } +- +- virtual AVCodecParserContext *av_parser_init(int codec_id) { return ::av_parser_init(codec_id); } +- virtual int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, +- const uint8_t *buf, int buf_size, +- int64_t pts, int64_t dts, int64_t pos) +- { +- return ::av_parser_parse2(s, avctx, poutbuf, poutbuf_size, buf, buf_size, pts, dts, pos); +- } +- virtual void av_parser_close(AVCodecParserContext *s) { ::av_parser_close(s); } +- +- virtual AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) { return ::av_bitstream_filter_init(name); } +- virtual int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, +- AVCodecContext *avctx, const char *args, +- uint8_t **poutbuf, int *poutbuf_size, +- const uint8_t *buf, int buf_size, int keyframe) { return ::av_bitstream_filter_filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); } +- virtual void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) { ::av_bitstream_filter_close(bsfc); } +- +- virtual void avpicture_free(AVPicture *picture) { ::avpicture_free(picture); } +- virtual void av_free_packet(AVPacket *pkt) { ::av_free_packet(pkt); } +- virtual int avpicture_alloc(AVPicture *picture, PixelFormat pix_fmt, int width, int height) { return ::avpicture_alloc(picture, pix_fmt, width, height); } +- virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt) { return ::avcodec_default_get_format(s, fmt); } +- virtual AVCodec *av_codec_next(AVCodec *c) { return ::av_codec_next(c); } +- +- virtual int av_dup_packet(AVPacket *pkt) { return ::av_dup_packet(pkt); } +- virtual void av_init_packet(AVPacket *pkt) { return ::av_init_packet(pkt); } +- virtual int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) { return ::avcodec_fill_audio_frame(frame, nb_channels, sample_fmt, buf, buf_size, align); } +- virtual void avcodec_free_frame(AVFrame **frame) { return ::avcodec_free_frame(frame); }; +- virtual int av_codec_is_decoder(const AVCodec *codec) { return ::av_codec_is_decoder(codec); } +- virtual AVDictionary* av_frame_get_metadata(const AVFrame* frame) { return ::av_frame_get_metadata(frame); } +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllAvCodec: Using libavcodec system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +-}; +-#else +-class DllAvCodec : public DllDynamic, DllAvCodecInterface +-{ +- DECLARE_DLL_WRAPPER(DllAvCodec, DLL_PATH_LIBAVCODEC) +- DEFINE_FUNC_ALIGNED1(void, __cdecl, avcodec_flush_buffers, AVCodecContext*) +- DEFINE_FUNC_ALIGNED3(int, __cdecl, avcodec_open2_dont_call, AVCodecContext*, AVCodec *, AVDictionary **) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_video2, AVCodecContext*, AVFrame*, int*, AVPacket*) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_audio4, AVCodecContext*, AVFrame*, int*, AVPacket*) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_subtitle2, AVCodecContext*, AVSubtitle*, int*, AVPacket*) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_encode_audio2, AVCodecContext*, AVPacket*, const AVFrame*, int*) +- DEFINE_FUNC_ALIGNED1(AVCodecContext*, __cdecl, avcodec_alloc_context3, AVCodec *) +- DEFINE_FUNC_ALIGNED1(AVCodecParserContext*, __cdecl, av_parser_init, int) +- DEFINE_FUNC_ALIGNED9(int, __cdecl, av_parser_parse2, AVCodecParserContext*,AVCodecContext*, uint8_t**, int*, const uint8_t*, int, int64_t, int64_t, int64_t) +- DEFINE_METHOD1(int, av_dup_packet, (AVPacket *p1)) +- DEFINE_METHOD1(void, av_init_packet, (AVPacket *p1)) +- +- LOAD_SYMBOLS(); +- +- DEFINE_METHOD0(void, avcodec_register_all_dont_call) +- DEFINE_METHOD1(AVCodec*, avcodec_find_decoder, (enum AVCodecID p1)) +- DEFINE_METHOD1(AVCodec*, avcodec_find_encoder, (enum AVCodecID p1)) +- DEFINE_METHOD1(int, avcodec_close_dont_call, (AVCodecContext *p1)) +- DEFINE_METHOD0(AVFrame*, avcodec_alloc_frame) +- DEFINE_METHOD5(int, avpicture_fill, (AVPicture *p1, uint8_t *p2, PixelFormat p3, int p4, int p5)) +- DEFINE_METHOD3(int, avpicture_get_size, (PixelFormat p1, int p2, int p3)) +- DEFINE_METHOD4(void, avcodec_string, (char *p1, int p2, AVCodecContext *p3, int p4)) +- DEFINE_METHOD2(void, avcodec_get_context_defaults3, (AVCodecContext *p1, AVCodec *p2)) +- DEFINE_METHOD1(void, av_parser_close, (AVCodecParserContext *p1)) +- DEFINE_METHOD1(void, avpicture_free, (AVPicture *p1)) +- DEFINE_METHOD1(AVBitStreamFilterContext*, av_bitstream_filter_init, (const char *p1)) +- DEFINE_METHOD8(int, av_bitstream_filter_filter, (AVBitStreamFilterContext* p1, AVCodecContext* p2, const char* p3, uint8_t** p4, int* p5, const uint8_t* p6, int p7, int p8)) +- DEFINE_METHOD1(void, av_bitstream_filter_close, (AVBitStreamFilterContext *p1)) +- DEFINE_METHOD1(void, av_free_packet, (AVPacket *p1)) +- DEFINE_METHOD4(int, avpicture_alloc, (AVPicture *p1, PixelFormat p2, int p3, int p4)) +- DEFINE_METHOD2(enum PixelFormat, avcodec_default_get_format, (struct AVCodecContext *p1, const enum PixelFormat *p2)) +- DEFINE_METHOD6(int, avcodec_fill_audio_frame, (AVFrame* p1, int p2, enum AVSampleFormat p3, const uint8_t* p4, int p5, int p6)) +- DEFINE_METHOD1(void, avcodec_free_frame, (AVFrame **p1)) +- DEFINE_METHOD1(AVCodec*, av_codec_next, (AVCodec *p1)) +- DEFINE_METHOD1(int, av_codec_is_decoder, (const AVCodec *p1)) +- DEFINE_METHOD1(AVDictionary*, av_frame_get_metadata, (const AVFrame* p1)) +- +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD(avcodec_flush_buffers) +- RESOLVE_METHOD_RENAME(avcodec_open2,avcodec_open2_dont_call) +- RESOLVE_METHOD_RENAME(avcodec_close,avcodec_close_dont_call) +- RESOLVE_METHOD(avcodec_find_decoder) +- RESOLVE_METHOD(avcodec_find_encoder) +- RESOLVE_METHOD(avcodec_alloc_frame) +- RESOLVE_METHOD_RENAME(avcodec_register_all, avcodec_register_all_dont_call) +- RESOLVE_METHOD(avpicture_fill) +- RESOLVE_METHOD(avcodec_decode_video2) +- RESOLVE_METHOD(avcodec_decode_audio4) +- RESOLVE_METHOD(avcodec_decode_subtitle2) +- RESOLVE_METHOD(avcodec_encode_audio2) +- RESOLVE_METHOD(avpicture_get_size) +- RESOLVE_METHOD(avcodec_alloc_context3) +- RESOLVE_METHOD(avcodec_string) +- RESOLVE_METHOD(avcodec_get_context_defaults3) +- RESOLVE_METHOD(av_parser_init) +- RESOLVE_METHOD(av_parser_parse2) +- RESOLVE_METHOD(av_parser_close) +- RESOLVE_METHOD(av_bitstream_filter_init) +- RESOLVE_METHOD(av_bitstream_filter_filter) +- RESOLVE_METHOD(av_bitstream_filter_close) +- RESOLVE_METHOD(avpicture_free) +- RESOLVE_METHOD(avpicture_alloc) +- RESOLVE_METHOD(av_free_packet) +- RESOLVE_METHOD(avcodec_default_get_format) +- RESOLVE_METHOD(av_codec_next) +- RESOLVE_METHOD(av_dup_packet) +- RESOLVE_METHOD(av_init_packet) +- RESOLVE_METHOD(avcodec_fill_audio_frame) +- RESOLVE_METHOD(avcodec_free_frame) +- RESOLVE_METHOD(av_codec_is_decoder) +- RESOLVE_METHOD(av_frame_get_metadata) +- END_METHOD_RESOLVE() +- +- /* dependencies of libavcodec */ +- DllAvUtil m_dllAvUtil; +- +-public: +- static CCriticalSection m_critSection; +- int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avcodec_open2_dont_call(avctx,codec, options); +- } +- int avcodec_close(AVCodecContext *avctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avcodec_close_dont_call(avctx); +- } +- void avcodec_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- avcodec_register_all_dont_call(); +- } +- virtual bool Load() +- { +- if (!m_dllAvUtil.Load()) +- return false; +- return DllDynamic::Load(); +- } +-}; +- +-#endif +diff --git a/lib/DllAvFilter.h b/lib/DllAvFilter.h +deleted file mode 100644 +index 6ef603a..0000000 +--- a/lib/DllAvFilter.h ++++ /dev/null +@@ -1,313 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +-#include "DllSwResample.h" +-#include "utils/log.h" +- +-extern "C" { +-#ifndef HAVE_MMX +-#define HAVE_MMX +-#endif +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +- +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +- +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +- #include +- #include +-#if LIBAVFILTER_VERSION_MICRO >= 100 && LIBAVFILTER_VERSION_INT < AV_VERSION_INT(3,43,100) +- #include +-#endif +- #include +-#else +- #include "libavfilter/avfilter.h" +- #include "libavfilter/avfiltergraph.h" +- #include "libavfilter/buffersink.h" +-#if LIBAVFILTER_VERSION_MICRO >= 100 && LIBAVFILTER_VERSION_INT < AV_VERSION_INT(3,43,100) +- #include "libavfilter/avcodec.h" +-#endif +- #include "libavfilter/buffersrc.h" +-#endif +-} +- +-#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,43,100) +-#define LIBAVFILTER_AVFRAME_BASED +-#endif +- +-#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,78,100) +- #define HAVE_AVFILTER_GRAPH_PARSE_PTR +-#endif +- +-#include "threads/SingleLock.h" +- +-class DllAvFilterInterface +-{ +-public: +- virtual ~DllAvFilterInterface() {} +- virtual void avfilter_free(AVFilterContext *filter)=0; +- virtual void avfilter_graph_free(AVFilterGraph **graph)=0; +- virtual int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)=0; +- virtual AVFilter *avfilter_get_by_name(const char *name)=0; +- virtual AVFilterGraph *avfilter_graph_alloc(void)=0; +- virtual AVFilterInOut *avfilter_inout_alloc()=0; +- virtual void avfilter_inout_free(AVFilterInOut **inout)=0; +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- virtual int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx)=0; +-#else +- virtual int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx)=0; +-#endif +- virtual int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)=0; +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersrc_add_frame(AVFilterContext *buffer_filter, AVFrame *frame)=0; +-#else +- virtual int av_buffersrc_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int flags)=0; +- virtual void avfilter_unref_buffer(AVFilterBufferRef *ref)=0; +-#endif +- virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)=0; +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) = 0; +-#else +- virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags)=0; +-#endif +- virtual AVBufferSinkParams *av_buffersink_params_alloc()=0; +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersink_poll_frame(AVFilterContext *ctx)=0; +-#endif +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +-// Use direct mapping +-class DllAvFilter : public DllDynamic, DllAvFilterInterface +-{ +-public: +- virtual ~DllAvFilter() {} +- virtual void avfilter_free(AVFilterContext *filter) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- ::avfilter_free(filter); +- } +- virtual void avfilter_graph_free(AVFilterGraph **graph) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- ::avfilter_graph_free(graph); +- } +- void avfilter_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- ::avfilter_register_all(); +- } +- virtual int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx) { return ::avfilter_graph_create_filter(filt_ctx, filt, name, args, opaque, graph_ctx); } +- virtual AVFilter *avfilter_get_by_name(const char *name) { return ::avfilter_get_by_name(name); } +- virtual AVFilterGraph *avfilter_graph_alloc() { return ::avfilter_graph_alloc(); } +- virtual AVFilterInOut *avfilter_inout_alloc() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avfilter_inout_alloc(); +- } +- virtual void avfilter_inout_free(AVFilterInOut **inout) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- ::avfilter_inout_free(inout); +- } +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- virtual int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avfilter_graph_parse_ptr(graph, filters, inputs, outputs, log_ctx); +- } +-#else +- virtual int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avfilter_graph_parse(graph, filters, inputs, outputs, log_ctx); +- } +-#endif +- virtual int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx) +- { +- return ::avfilter_graph_config(graphctx, log_ctx); +- } +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersrc_add_frame(AVFilterContext *buffer_filter, AVFrame* frame) { return ::av_buffersrc_add_frame(buffer_filter, frame); } +-#else +- virtual int av_buffersrc_add_frame(AVFilterContext *buffer_filter, AVFrame* frame, int flags) { return ::av_buffersrc_add_frame(buffer_filter, frame, flags); } +- virtual void avfilter_unref_buffer(AVFilterBufferRef *ref) { ::avfilter_unref_buffer(ref); } +-#endif +- virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) { return ::avfilter_link(src, srcpad, dst, dstpad); } +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) { return ::av_buffersink_get_frame(ctx, frame); } +-#else +- virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags) { return ::av_buffersink_get_buffer_ref(buffer_sink, bufref, flags); } +-#endif +- virtual AVBufferSinkParams *av_buffersink_params_alloc() { return ::av_buffersink_params_alloc(); } +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- virtual int av_buffersink_poll_frame(AVFilterContext *ctx) { return ::av_buffersink_poll_frame(ctx); } +-#endif +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllAvFilter: Using libavfilter system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +-}; +-#else +-class DllAvFilter : public DllDynamic, DllAvFilterInterface +-{ +- DECLARE_DLL_WRAPPER(DllAvFilter, DLL_PATH_LIBAVFILTER) +- +- LOAD_SYMBOLS() +- +- DEFINE_METHOD1(void, avfilter_free_dont_call, (AVFilterContext *p1)) +- DEFINE_METHOD1(void, avfilter_graph_free_dont_call, (AVFilterGraph **p1)) +- DEFINE_METHOD0(void, avfilter_register_all_dont_call) +- DEFINE_METHOD6(int, avfilter_graph_create_filter, (AVFilterContext **p1, AVFilter *p2, const char *p3, const char *p4, void *p5, AVFilterGraph *p6)) +- DEFINE_METHOD1(AVFilter*, avfilter_get_by_name, (const char *p1)) +- DEFINE_METHOD0(AVFilterGraph*, avfilter_graph_alloc) +- DEFINE_METHOD0(AVFilterInOut*, avfilter_inout_alloc_dont_call) +- DEFINE_METHOD1(void, avfilter_inout_free_dont_call, (AVFilterInOut **p1)) +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- DEFINE_FUNC_ALIGNED5(int, __cdecl, avfilter_graph_parse_ptr_dont_call, AVFilterGraph *, const char *, AVFilterInOut **, AVFilterInOut **, void *) +-#else +- DEFINE_FUNC_ALIGNED5(int, __cdecl, avfilter_graph_parse_dont_call, AVFilterGraph *, const char *, AVFilterInOut **, AVFilterInOut **, void *) +-#endif +- DEFINE_FUNC_ALIGNED2(int, __cdecl, avfilter_graph_config_dont_call, AVFilterGraph *, void *) +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- DEFINE_METHOD2(int, av_buffersrc_add_frame, (AVFilterContext *p1, AVFrame *p2)) +-#else +- DEFINE_METHOD3(int, av_buffersrc_add_frame, (AVFilterContext *p1, AVFrame *p2, int p3)) +- DEFINE_METHOD1(void, avfilter_unref_buffer, (AVFilterBufferRef *p1)) +-#endif +- DEFINE_METHOD4(int, avfilter_link, (AVFilterContext *p1, unsigned p2, AVFilterContext *p3, unsigned p4)) +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- DEFINE_FUNC_ALIGNED2(int , __cdecl, av_buffersink_get_frame, AVFilterContext *, AVFrame *); +-#else +- DEFINE_FUNC_ALIGNED3(int , __cdecl, av_buffersink_get_buffer_ref, AVFilterContext *, AVFilterBufferRef **, int); +-#endif +- DEFINE_FUNC_ALIGNED0(AVBufferSinkParams*, __cdecl, av_buffersink_params_alloc); +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- DEFINE_FUNC_ALIGNED1(int , __cdecl, av_buffersink_poll_frame, AVFilterContext *); +-#endif +- +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD_RENAME(avfilter_free, avfilter_free_dont_call) +- RESOLVE_METHOD_RENAME(avfilter_graph_free, avfilter_graph_free_dont_call) +- RESOLVE_METHOD_RENAME(avfilter_register_all, avfilter_register_all_dont_call) +- RESOLVE_METHOD(avfilter_graph_create_filter) +- RESOLVE_METHOD(avfilter_get_by_name) +- RESOLVE_METHOD(avfilter_graph_alloc) +- RESOLVE_METHOD_RENAME(avfilter_inout_alloc, avfilter_inout_alloc_dont_call) +- RESOLVE_METHOD_RENAME(avfilter_inout_free, avfilter_inout_free_dont_call) +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- RESOLVE_METHOD_RENAME(avfilter_graph_parse_ptr, avfilter_graph_parse_ptr_dont_call) +-#else +- RESOLVE_METHOD_RENAME(avfilter_graph_parse, avfilter_graph_parse_dont_call) +-#endif +- RESOLVE_METHOD_RENAME(avfilter_graph_config, avfilter_graph_config_dont_call) +- RESOLVE_METHOD(av_buffersrc_add_frame) +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- RESOLVE_METHOD(avfilter_unref_buffer) +-#endif +- RESOLVE_METHOD(avfilter_link) +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- RESOLVE_METHOD(av_buffersink_get_frame) +-#else +- RESOLVE_METHOD(av_buffersink_get_buffer_ref) +-#endif +- RESOLVE_METHOD(av_buffersink_params_alloc) +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- RESOLVE_METHOD(av_buffersink_poll_frame) +-#endif +- END_METHOD_RESOLVE() +- +- /* dependencies of libavfilter */ +- DllAvUtil m_dllAvUtil; +- DllSwResample m_dllSwResample; +- DllAvFormat m_dllAvFormat; +- +-public: +- void avfilter_free(AVFilterContext *filter) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- avfilter_free_dont_call(filter); +- } +- void avfilter_graph_free(AVFilterGraph **graph) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- avfilter_graph_free_dont_call(graph); +- } +- void avfilter_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- avfilter_register_all_dont_call(); +- } +- AVFilterInOut* avfilter_inout_alloc() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avfilter_inout_alloc_dont_call(); +- } +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avfilter_graph_parse_ptr_dont_call(graph, filters, inputs, outputs, log_ctx); +- } +-#else +- int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avfilter_graph_parse_dont_call(graph, filters, inputs, outputs, log_ctx); +- } +-#endif +- void avfilter_inout_free(AVFilterInOut **inout) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- avfilter_inout_free_dont_call(inout); +- } +- int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avfilter_graph_config_dont_call(graphctx, log_ctx); +- } +- virtual bool Load() +- { +- if (!m_dllAvUtil.Load()) +- return false; +- if (!m_dllSwResample.Load()) +- return false; +- if (!m_dllAvFormat.Load()) +- return false; +- return DllDynamic::Load(); +- } +-}; +-#endif +diff --git a/lib/DllAvFormat.h b/lib/DllAvFormat.h +deleted file mode 100644 +index fc7e166..0000000 +--- a/lib/DllAvFormat.h ++++ /dev/null +@@ -1,322 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "DllAvCodec.h" +- +-extern "C" { +-#ifndef HAVE_MMX +-#define HAVE_MMX +-#endif +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +- /* xbmc_read_frame_flush() is defined for us in lib/xbmc-dll-symbols/DllAvFormat.c */ +- void xbmc_read_frame_flush(AVFormatContext *s); +-#else +- #include "libavformat/avformat.h" +- #if defined(TARGET_DARWIN) || defined(USE_STATIC_FFMPEG) +- void ff_read_frame_flush(AVFormatContext *s); // internal replacement +- #define xbmc_read_frame_flush ff_read_frame_flush +- #endif +-#endif +-} +- +-/* Flag introduced without a version bump */ +-#ifndef AVSEEK_FORCE +-#define AVSEEK_FORCE 0x20000 +-#endif +- +-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55,12,100) +-#define AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE +-#endif +- +-typedef int64_t offset_t; +- +-class DllAvFormatInterface +-{ +-public: +- virtual ~DllAvFormatInterface() {} +- virtual void av_register_all_dont_call(void)=0; +- virtual void avformat_network_init_dont_call(void)=0; +- virtual void avformat_network_deinit_dont_call(void)=0; +- virtual AVInputFormat *av_find_input_format(const char *short_name)=0; +- virtual void avformat_close_input(AVFormatContext **s)=0; +- virtual int av_read_frame(AVFormatContext *s, AVPacket *pkt)=0; +- virtual void av_read_frame_flush(AVFormatContext *s)=0; +- virtual int av_read_play(AVFormatContext *s)=0; +- virtual int av_read_pause(AVFormatContext *s)=0; +- virtual int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)=0; +-#if (!defined USE_EXTERNAL_FFMPEG) && (!defined TARGET_DARWIN) && (!defined USE_STATIC_FFMPEG) +- virtual int avformat_find_stream_info_dont_call(AVFormatContext *ic, AVDictionary **options)=0; +-#endif +- virtual int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)=0; +- virtual AVIOContext *avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, +- int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), +- int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), +- offset_t (*seek)(void *opaque, offset_t offset, int whence))=0; +- virtual AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)=0; +- virtual AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)=0; +- virtual int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size)=0; +- virtual void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)=0; +- virtual int avio_open(AVIOContext **s, const char *filename, int flags)=0; +- virtual int avio_close(AVIOContext *s)=0; +- virtual int avio_open_dyn_buf(AVIOContext **s)=0; +- virtual int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)=0; +- virtual offset_t avio_seek(AVIOContext *s, offset_t offset, int whence)=0; +- virtual int avio_read(AVIOContext *s, unsigned char *buf, int size)=0; +- virtual void avio_w8(AVIOContext *s, int b)=0; +- virtual void avio_write(AVIOContext *s, const unsigned char *buf, int size)=0; +- virtual void avio_wb24(AVIOContext *s, unsigned int val)=0; +- virtual void avio_wb32(AVIOContext *s, unsigned int val)=0; +- virtual void avio_wb16(AVIOContext *s, unsigned int val)=0; +- virtual AVFormatContext *avformat_alloc_context(void)=0; +- virtual int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename) = 0; +- virtual AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)=0; +- virtual AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type)=0; +- virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options)=0; +- virtual int av_write_trailer(AVFormatContext *s)=0; +- virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt)=0; +-#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- virtual AVRational av_stream_get_r_frame_rate(const AVStream *s)=0; +-#endif +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +- +-// Use direct mapping +-class DllAvFormat : public DllDynamic, DllAvFormatInterface +-{ +-public: +- virtual ~DllAvFormat() {} +- virtual void av_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::av_register_all(); +- } +- virtual void av_register_all_dont_call() { *(volatile int* )0x0 = 0; } +- virtual void avformat_network_init_dont_call() { *(volatile int* )0x0 = 0; } +- virtual void avformat_network_deinit_dont_call() { *(volatile int* )0x0 = 0; } +- virtual AVInputFormat *av_find_input_format(const char *short_name) { return ::av_find_input_format(short_name); } +- virtual void avformat_close_input(AVFormatContext **s) { ::avformat_close_input(s); } +- virtual int av_read_frame(AVFormatContext *s, AVPacket *pkt) { return ::av_read_frame(s, pkt); } +- virtual void av_read_frame_flush(AVFormatContext *s) { ::xbmc_read_frame_flush(s); } +- virtual int av_read_play(AVFormatContext *s) { return ::av_read_play(s); } +- virtual int av_read_pause(AVFormatContext *s) { return ::av_read_pause(s); } +- virtual int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { return ::av_seek_frame(s, stream_index, timestamp, flags); } +- virtual int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return ::avformat_find_stream_info(ic, options); +- } +- virtual int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) +- { return ::avformat_open_input(ps, filename, fmt, options); } +- virtual AVIOContext *avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, +- int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), +- int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), +- offset_t (*seek)(void *opaque, offset_t offset, int whence)) { return ::avio_alloc_context(buffer, buffer_size, write_flag, opaque, read_packet, write_packet, seek); } +- virtual AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) {return ::av_probe_input_format(pd, is_opened); } +- virtual AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max) {*score_max = 100; return ::av_probe_input_format(pd, is_opened); } // Use av_probe_input_format, this is not exported by ffmpeg's headers +- virtual int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { return ::av_probe_input_buffer(pb, fmt, filename, logctx, offset, max_probe_size); } +- virtual void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output) { ::av_dump_format(ic, index, url, is_output); } +- virtual int avio_open(AVIOContext **s, const char *filename, int flags) { return ::avio_open(s, filename, flags); } +- virtual int avio_close(AVIOContext *s) { return ::avio_close(s); } +- virtual int avio_open_dyn_buf(AVIOContext **s) { return ::avio_open_dyn_buf(s); } +- virtual int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { return ::avio_close_dyn_buf(s, pbuffer); } +- virtual offset_t avio_seek(AVIOContext *s, offset_t offset, int whence) { return ::avio_seek(s, offset, whence); } +- virtual int avio_read(AVIOContext *s, unsigned char *buf, int size) { return ::avio_read(s, buf, size); } +- virtual void avio_w8(AVIOContext *s, int b) { ::avio_w8(s, b); } +- virtual void avio_write(AVIOContext *s, const unsigned char *buf, int size) { ::avio_write(s, buf, size); } +- virtual void avio_wb24(AVIOContext *s, unsigned int val) { ::avio_wb24(s, val); } +- virtual void avio_wb32(AVIOContext *s, unsigned int val) { ::avio_wb32(s, val); } +- virtual void avio_wb16(AVIOContext *s, unsigned int val) { ::avio_wb16(s, val); } +- virtual AVFormatContext *avformat_alloc_context() { return ::avformat_alloc_context(); } +- virtual int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename){ return ::avformat_alloc_output_context2(ctx,oformat,format_name,filename); } +- virtual AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c) { return ::avformat_new_stream(s, c); } +- virtual AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type) { return ::av_guess_format(short_name, filename, mime_type); } +- virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options) { return ::avformat_write_header (s, options); } +- virtual int av_write_trailer(AVFormatContext *s) { return ::av_write_trailer(s); } +- virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt) { return ::av_write_frame(s, pkt); } +-#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- virtual AVRational av_stream_get_r_frame_rate(const AVStream *s) { return ::av_stream_get_r_frame_rate(s); } +-#endif +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllAvFormat: Using libavformat system library"); +-#endif +- CSingleLock lock(DllAvCodec::m_critSection); +- if (++m_avformat_refcnt == 1) +- ::avformat_network_init(); +- return true; +- } +- virtual void Unload() { +- CSingleLock lock(DllAvCodec::m_critSection); +- if (--m_avformat_refcnt == 0) +- ::avformat_network_deinit(); +- } +- +-protected: +- static int m_avformat_refcnt; +-}; +- +-#else +- +-class DllAvFormat : public DllDynamic, DllAvFormatInterface +-{ +- DECLARE_DLL_WRAPPER(DllAvFormat, DLL_PATH_LIBAVFORMAT) +- +- LOAD_SYMBOLS() +- +- DEFINE_METHOD0(void, av_register_all_dont_call) +- DEFINE_METHOD0(void, avformat_network_init_dont_call) +- DEFINE_METHOD0(void, avformat_network_deinit_dont_call) +- DEFINE_METHOD1(AVInputFormat*, av_find_input_format, (const char *p1)) +- DEFINE_METHOD1(void, avformat_close_input, (AVFormatContext **p1)) +- DEFINE_METHOD1(int, av_read_play, (AVFormatContext *p1)) +- DEFINE_METHOD1(int, av_read_pause, (AVFormatContext *p1)) +- DEFINE_METHOD1(void, av_read_frame_flush, (AVFormatContext *p1)) +- DEFINE_FUNC_ALIGNED2(int, __cdecl, av_read_frame, AVFormatContext *, AVPacket *) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, av_seek_frame, AVFormatContext*, int, int64_t, int) +- DEFINE_FUNC_ALIGNED2(int, __cdecl, avformat_find_stream_info_dont_call, AVFormatContext*, AVDictionary **) +- DEFINE_FUNC_ALIGNED4(int, __cdecl, avformat_open_input, AVFormatContext **, const char *, AVInputFormat *, AVDictionary **) +- DEFINE_FUNC_ALIGNED2(AVInputFormat*, __cdecl, av_probe_input_format, AVProbeData*, int) +- DEFINE_FUNC_ALIGNED3(AVInputFormat*, __cdecl, av_probe_input_format2, AVProbeData*, int, int*) +- DEFINE_FUNC_ALIGNED6(int, __cdecl, av_probe_input_buffer, AVIOContext *, AVInputFormat **, const char *, void *, unsigned int, unsigned int) +- DEFINE_FUNC_ALIGNED3(int, __cdecl, avio_read, AVIOContext*, unsigned char *, int) +- DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_w8, AVIOContext*, int) +- DEFINE_FUNC_ALIGNED3(void, __cdecl, avio_write, AVIOContext*, const unsigned char *, int) +- DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb24, AVIOContext*, unsigned int) +- DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb32, AVIOContext*, unsigned int) +- DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb16, AVIOContext*, unsigned int) +- DEFINE_METHOD7(AVIOContext *, avio_alloc_context, (unsigned char *p1, int p2, int p3, void *p4, +- int (*p5)(void *opaque, uint8_t *buf, int buf_size), +- int (*p6)(void *opaque, uint8_t *buf, int buf_size), +- offset_t (*p7)(void *opaque, offset_t offset, int whence))) +- DEFINE_METHOD4(void, av_dump_format, (AVFormatContext *p1, int p2, const char *p3, int p4)) +- DEFINE_METHOD3(int, avio_open, (AVIOContext **p1, const char *p2, int p3)) +- DEFINE_METHOD1(int, avio_close, (AVIOContext *p1)) +- DEFINE_METHOD1(int, avio_open_dyn_buf, (AVIOContext **p1)) +- DEFINE_METHOD2(int, avio_close_dyn_buf, (AVIOContext *p1, uint8_t **p2)) +- DEFINE_METHOD3(offset_t, avio_seek, (AVIOContext *p1, offset_t p2, int p3)) +- DEFINE_METHOD0(AVFormatContext *, avformat_alloc_context) +- DEFINE_METHOD4(int, avformat_alloc_output_context2, (AVFormatContext **p1, AVOutputFormat *p2, const char *p3, const char *p4)) +- DEFINE_METHOD2(AVStream *, avformat_new_stream, (AVFormatContext *p1, AVCodec *p2)) +- DEFINE_METHOD3(AVOutputFormat *, av_guess_format, (const char *p1, const char *p2, const char *p3)) +- DEFINE_METHOD2(int, avformat_write_header , (AVFormatContext *p1, AVDictionary **p2)) +- DEFINE_METHOD1(int, av_write_trailer, (AVFormatContext *p1)) +- DEFINE_METHOD2(int, av_write_frame , (AVFormatContext *p1, AVPacket *p2)) +-#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- DEFINE_METHOD1(AVRational, av_stream_get_r_frame_rate, (const AVStream *p1)) +-#endif +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD_RENAME(av_register_all, av_register_all_dont_call) +- RESOLVE_METHOD_RENAME(avformat_network_init, avformat_network_init_dont_call) +- RESOLVE_METHOD_RENAME(avformat_network_deinit, avformat_network_deinit_dont_call) +- RESOLVE_METHOD(av_find_input_format) +- RESOLVE_METHOD(avformat_close_input) +- RESOLVE_METHOD(av_read_frame) +- RESOLVE_METHOD(av_read_play) +- RESOLVE_METHOD(av_read_pause) +- RESOLVE_METHOD(av_read_frame_flush) +- RESOLVE_METHOD(av_seek_frame) +- RESOLVE_METHOD_RENAME(avformat_find_stream_info, avformat_find_stream_info_dont_call) +- RESOLVE_METHOD(avformat_open_input) +- RESOLVE_METHOD(avio_alloc_context) +- RESOLVE_METHOD(av_probe_input_format) +- RESOLVE_METHOD(av_probe_input_format2) +- RESOLVE_METHOD(av_probe_input_buffer) +- RESOLVE_METHOD(av_dump_format) +- RESOLVE_METHOD(avio_open) +- RESOLVE_METHOD(avio_close) +- RESOLVE_METHOD(avio_open_dyn_buf) +- RESOLVE_METHOD(avio_close_dyn_buf) +- RESOLVE_METHOD(avio_seek) +- RESOLVE_METHOD(avio_read) +- RESOLVE_METHOD(avio_w8) +- RESOLVE_METHOD(avio_write) +- RESOLVE_METHOD(avio_wb24) +- RESOLVE_METHOD(avio_wb32) +- RESOLVE_METHOD(avio_wb16) +- RESOLVE_METHOD(avformat_alloc_context) +- RESOLVE_METHOD(avformat_alloc_output_context2) +- RESOLVE_METHOD(avformat_new_stream) +- RESOLVE_METHOD(av_guess_format) +- RESOLVE_METHOD(avformat_write_header) +- RESOLVE_METHOD(av_write_trailer) +- RESOLVE_METHOD(av_write_frame) +-#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- RESOLVE_METHOD(av_stream_get_r_frame_rate) +-#endif +- END_METHOD_RESOLVE() +- +- /* dependencies of libavformat */ +- DllAvCodec m_dllAvCodec; +- // DllAvUtil loaded implicitely by m_dllAvCodec +- +-public: +- void av_register_all() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- av_register_all_dont_call(); +- } +- int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- return avformat_find_stream_info_dont_call(ic, options); +- } +- +- virtual bool Load() +- { +- if (!m_dllAvCodec.Load()) +- return false; +- bool loaded = DllDynamic::Load(); +- +- CSingleLock lock(DllAvCodec::m_critSection); +- if (++m_avformat_refcnt == 1 && loaded) +- avformat_network_init_dont_call(); +- return loaded; +- } +- +- virtual void Unload() +- { +- CSingleLock lock(DllAvCodec::m_critSection); +- if (--m_avformat_refcnt == 0 && DllDynamic::IsLoaded()) +- avformat_network_deinit_dont_call(); +- +- DllDynamic::Unload(); +- } +- +-protected: +- static int m_avformat_refcnt; +-}; +- +-#endif +diff --git a/lib/DllAvUtil.h b/lib/DllAvUtil.h +deleted file mode 100644 +index 0fcdf10..0000000 +--- a/lib/DllAvUtil.h ++++ /dev/null +@@ -1,291 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "utils/log.h" +- +-#ifndef __GNUC__ +-#pragma warning(push) +-#pragma warning(disable:4244) +-#endif +- +-extern "C" { +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +- // for av_get_default_channel_layout +- #include +- #include +- #include +- // for LIBAVCODEC_VERSION_INT: +- #include +- // for enum AVSampleFormat +- #include +- #include +- #include +- #include +- #if (defined USE_LIBAV_HACKS) +- #include "xbmc-libav-hacks/libav_hacks.h" +- #endif +-#else +- #include "libavutil/avutil.h" +- //for av_get_default_channel_layout +- #include "libavutil/audioconvert.h" +- #include "libavutil/crc.h" +- #include "libavutil/opt.h" +- #include "libavutil/mem.h" +- #include "libavutil/fifo.h" +- // for enum AVSampleFormat +- #include "libavutil/samplefmt.h" +-#endif +-} +- +-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52,29,100) +-#define AVFRAME_IN_LAVU +-#endif +- +-#ifndef __GNUC__ +-#pragma warning(pop) +-#endif +- +-// calback used for logging +-void ff_avutil_log(void* ptr, int level, const char* format, va_list va); +- +-class DllAvUtilInterface +-{ +-public: +- virtual ~DllAvUtilInterface() {} +- virtual void av_log_set_callback(void (*)(void*, int, const char*, va_list))=0; +- virtual void *av_malloc(unsigned int size)=0; +- virtual void *av_mallocz(unsigned int size)=0; +- virtual void *av_realloc(void *ptr, unsigned int size)=0; +- virtual void av_free(void *ptr)=0; +- virtual void av_freep(void *ptr)=0; +- virtual int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding)=0; +- virtual int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)=0; +- virtual int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)=0; +- virtual const AVCRC* av_crc_get_table(AVCRCId crc_id)=0; +- virtual uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)=0; +- virtual int av_opt_set(void *obj, const char *name, const char *val, int search_flags)=0; +- virtual int av_opt_set_double(void *obj, const char *name, double val, int search_flags)=0; +- virtual int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)=0; +- virtual AVFifoBuffer *av_fifo_alloc(unsigned int size) = 0; +- virtual void av_fifo_free(AVFifoBuffer *f) = 0; +- virtual void av_fifo_reset(AVFifoBuffer *f) = 0; +- virtual int av_fifo_size(AVFifoBuffer *f) = 0; +- virtual int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)) = 0; +- virtual int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) = 0; +- virtual char *av_strdup(const char *s)=0; +- virtual int av_get_bytes_per_sample(enum AVSampleFormat p1) = 0; +- virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) = 0; +- virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)=0; +- virtual void av_dict_free(AVDictionary **pm) = 0; +- virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0; +- virtual int64_t av_get_default_channel_layout(int nb_channels)=0; +- virtual int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0; +- virtual int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) = 0; +- virtual int av_get_channel_layout_channel_index (uint64_t channel_layout, uint64_t channel) = 0; +- virtual int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, const uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0; +- virtual int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt) = 0; +- virtual uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index) = 0; +-#if defined(AVFRAME_IN_LAVU) +- virtual void av_frame_free(AVFrame **frame)=0; +- virtual AVFrame *av_frame_alloc(void)=0; +- virtual void av_frame_unref(AVFrame *frame)=0; +- virtual void av_frame_move_ref(AVFrame *dst, AVFrame *src)=0; +-#endif +-}; +- +-#if defined (USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +-// Use direct layer +-class DllAvUtilBase : public DllDynamic, DllAvUtilInterface +-{ +-public: +- +- virtual ~DllAvUtilBase() {} +- virtual void av_log_set_callback(void (*foo)(void*, int, const char*, va_list)) { ::av_log_set_callback(foo); } +- virtual void *av_malloc(unsigned int size) { return ::av_malloc(size); } +- virtual void *av_mallocz(unsigned int size) { return ::av_mallocz(size); } +- virtual void *av_realloc(void *ptr, unsigned int size) { return ::av_realloc(ptr, size); } +- virtual void av_free(void *ptr) { ::av_free(ptr); } +- virtual void av_freep(void *ptr) { ::av_freep(ptr); } +- virtual int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding d) { return ::av_rescale_rnd(a, b, c, d); } +- virtual int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) { return ::av_rescale_q(a, bq, cq); } +- virtual int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) { return ::av_crc_init(ctx, le, bits, poly, ctx_size); } +- virtual const AVCRC* av_crc_get_table(AVCRCId crc_id) { return ::av_crc_get_table(crc_id); } +- virtual uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length) { return ::av_crc(ctx, crc, buffer, length); } +- virtual int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { return ::av_opt_set(obj, name, val, search_flags); } +- virtual int av_opt_set_double(void *obj, const char *name, double val, int search_flags) { return ::av_opt_set_double(obj, name, val, search_flags); } +- virtual int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) { return ::av_opt_set_int(obj, name, val, search_flags); } +- virtual AVFifoBuffer *av_fifo_alloc(unsigned int size) {return ::av_fifo_alloc(size); } +- virtual void av_fifo_free(AVFifoBuffer *f) { ::av_fifo_free(f); } +- virtual void av_fifo_reset(AVFifoBuffer *f) { ::av_fifo_reset(f); } +- virtual int av_fifo_size(AVFifoBuffer *f) { return ::av_fifo_size(f); } +- virtual int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)) +- { return ::av_fifo_generic_read(f, dest, buf_size, func); } +- virtual int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) +- { return ::av_fifo_generic_write(f, src, size, func); } +- virtual char *av_strdup(const char *s) { return ::av_strdup(s); } +- virtual int av_get_bytes_per_sample(enum AVSampleFormat p1) +- { return ::av_get_bytes_per_sample(p1); } +- virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags){ return ::av_dict_get(m, key, prev, flags); } +- virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) { return ::av_dict_set(pm, key, value, flags); } +- virtual void av_dict_free(AVDictionary **pm) { ::av_dict_free(pm); } +- virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) +- { return ::av_samples_get_buffer_size(linesize, nb_channels, nb_samples, sample_fmt, align); } +- virtual int64_t av_get_default_channel_layout(int nb_channels) { return ::av_get_default_channel_layout(nb_channels); } +- virtual int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) +- { return ::av_samples_alloc(audio_data, linesize, nb_channels, nb_samples, sample_fmt, align); } +- virtual int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) { return ::av_sample_fmt_is_planar(sample_fmt); } +- virtual int av_get_channel_layout_channel_index (uint64_t channel_layout, uint64_t channel) { return ::av_get_channel_layout_channel_index(channel_layout, channel); } +- virtual int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, const uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) +- { return ::av_samples_fill_arrays(audio_data, linesize, buf, nb_channels, nb_samples, sample_fmt, align); } +- virtual int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt) +- { return ::av_samples_copy(dst, src, dst_offset, src_offset, nb_samples, nb_channels, sample_fmt); } +- virtual uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index) +- { return ::av_channel_layout_extract_channel(channel_layout, index); } +-#if defined(AVFRAME_IN_LAVU) +- virtual void av_frame_free(AVFrame **frame) { return ::av_frame_free(frame); } +- virtual AVFrame *av_frame_alloc() { return ::av_frame_alloc(); } +- virtual void av_frame_unref(AVFrame *frame) { return ::av_frame_unref(frame); } +- virtual void av_frame_move_ref(AVFrame *dst, AVFrame *src) { return ::av_frame_move_ref(dst,src); } +-#endif +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllAvUtilBase: Using libavutil system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +-}; +- +-#else +- +-class DllAvUtilBase : public DllDynamic, DllAvUtilInterface +-{ +- DECLARE_DLL_WRAPPER(DllAvUtilBase, DLL_PATH_LIBAVUTIL) +- +- LOAD_SYMBOLS() +- +- DEFINE_METHOD1(void, av_log_set_callback, (void (*p1)(void*, int, const char*, va_list))) +- DEFINE_METHOD1(void*, av_malloc, (unsigned int p1)) +- DEFINE_METHOD1(void*, av_mallocz, (unsigned int p1)) +- DEFINE_METHOD2(void*, av_realloc, (void *p1, unsigned int p2)) +- DEFINE_METHOD1(void, av_free, (void *p1)) +- DEFINE_METHOD1(void, av_freep, (void *p1)) +- DEFINE_METHOD4(int64_t, av_rescale_rnd, (int64_t p1, int64_t p2, int64_t p3, enum AVRounding p4)); +- DEFINE_METHOD3(int64_t, av_rescale_q, (int64_t p1, AVRational p2, AVRational p3)); +- DEFINE_METHOD1(const AVCRC*, av_crc_get_table, (AVCRCId p1)) +- DEFINE_METHOD5(int, av_crc_init, (AVCRC *p1, int p2, int p3, uint32_t p4, int p5)); +- DEFINE_METHOD4(uint32_t, av_crc, (const AVCRC *p1, uint32_t p2, const uint8_t *p3, size_t p4)); +- DEFINE_METHOD4(int, av_opt_set, (void *p1, const char *p2, const char *p3, int p4)); +- DEFINE_METHOD4(int, av_opt_set_double, (void *p1, const char *p2, double p3, int p4)) +- DEFINE_METHOD4(int, av_opt_set_int, (void *p1, const char *p2, int64_t p3, int p4)) +- DEFINE_METHOD1(AVFifoBuffer*, av_fifo_alloc, (unsigned int p1)) +- DEFINE_METHOD1(void, av_fifo_free, (AVFifoBuffer *p1)) +- DEFINE_METHOD1(void, av_fifo_reset, (AVFifoBuffer *p1)) +- DEFINE_METHOD1(int, av_fifo_size, (AVFifoBuffer *p1)) +- DEFINE_METHOD4(int, av_fifo_generic_read, (AVFifoBuffer *p1, void *p2, int p3, void (*p4)(void*, void*, int))) +- DEFINE_METHOD4(int, av_fifo_generic_write, (AVFifoBuffer *p1, void *p2, int p3, int (*p4)(void*, void*, int))) +- DEFINE_METHOD1(char*, av_strdup, (const char *p1)) +- DEFINE_METHOD1(int, av_get_bytes_per_sample, (enum AVSampleFormat p1)) +- DEFINE_METHOD4(AVDictionaryEntry *, av_dict_get, (AVDictionary *p1, const char *p2, const AVDictionaryEntry *p3, int p4)) +- DEFINE_METHOD4(int, av_dict_set, (AVDictionary **p1, const char *p2, const char *p3, int p4)); +- DEFINE_METHOD1(void, av_dict_free, (AVDictionary **p1)); +- DEFINE_METHOD5(int, av_samples_get_buffer_size, (int *p1, int p2, int p3, enum AVSampleFormat p4, int p5)) +- DEFINE_METHOD1(int64_t, av_get_default_channel_layout, (int p1)) +- DEFINE_METHOD6(int, av_samples_alloc, (uint8_t **p1, int *p2, int p3, int p4, enum AVSampleFormat p5, int p6)) +- DEFINE_METHOD1(int, av_sample_fmt_is_planar, (enum AVSampleFormat p1)) +- DEFINE_METHOD2(int, av_get_channel_layout_channel_index, (uint64_t p1, uint64_t p2)) +- DEFINE_METHOD7(int, av_samples_fill_arrays, (uint8_t **p1, int *p2, const uint8_t *p3, int p4, int p5, enum AVSampleFormat p6, int p7)) +- DEFINE_METHOD7(int, av_samples_copy, (uint8_t **p1, uint8_t *const *p2, int p3, int p4, int p5, int p6, enum AVSampleFormat p7)) +- DEFINE_METHOD2(uint64_t, av_channel_layout_extract_channel, (uint64_t p1, int p2)) +-#if defined(AVFRAME_IN_LAVU) +- DEFINE_METHOD1(void, av_frame_free, (AVFrame **p1)) +- DEFINE_METHOD0(AVFrame *, av_frame_alloc) +- DEFINE_METHOD1(void, av_frame_unref, (AVFrame *p1)) +- DEFINE_METHOD2(void, av_frame_move_ref, (AVFrame *p1, AVFrame* p2)) +-#endif +- +- public: +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD(av_log_set_callback) +- RESOLVE_METHOD(av_malloc) +- RESOLVE_METHOD(av_mallocz) +- RESOLVE_METHOD(av_realloc) +- RESOLVE_METHOD(av_free) +- RESOLVE_METHOD(av_freep) +- RESOLVE_METHOD(av_rescale_rnd) +- RESOLVE_METHOD(av_rescale_q) +- RESOLVE_METHOD(av_crc_init) +- RESOLVE_METHOD(av_crc_get_table) +- RESOLVE_METHOD(av_crc) +- RESOLVE_METHOD(av_opt_set) +- RESOLVE_METHOD(av_opt_set_double) +- RESOLVE_METHOD(av_opt_set_int) +- RESOLVE_METHOD(av_fifo_alloc) +- RESOLVE_METHOD(av_fifo_free) +- RESOLVE_METHOD(av_fifo_reset) +- RESOLVE_METHOD(av_fifo_size) +- RESOLVE_METHOD(av_fifo_generic_read) +- RESOLVE_METHOD(av_fifo_generic_write) +- RESOLVE_METHOD(av_strdup) +- RESOLVE_METHOD(av_get_bytes_per_sample) +- RESOLVE_METHOD(av_dict_get) +- RESOLVE_METHOD(av_dict_set) +- RESOLVE_METHOD(av_dict_free) +- RESOLVE_METHOD(av_samples_get_buffer_size) +- RESOLVE_METHOD(av_get_default_channel_layout) +- RESOLVE_METHOD(av_samples_alloc) +- RESOLVE_METHOD(av_sample_fmt_is_planar) +- RESOLVE_METHOD(av_get_channel_layout_channel_index) +- RESOLVE_METHOD(av_samples_fill_arrays) +- RESOLVE_METHOD(av_samples_copy) +- RESOLVE_METHOD(av_channel_layout_extract_channel) +-#if defined(AVFRAME_IN_LAVU) +- RESOLVE_METHOD(av_frame_free) +- RESOLVE_METHOD(av_frame_alloc) +- RESOLVE_METHOD(av_frame_unref) +- RESOLVE_METHOD(av_frame_move_ref) +-#endif +- END_METHOD_RESOLVE() +-}; +- +-#endif +- +-class DllAvUtil : public DllAvUtilBase +-{ +-public: +- virtual bool Load() +- { +- if( DllAvUtilBase::Load() ) +- { +- DllAvUtilBase::av_log_set_callback(ff_avutil_log); +- return true; +- } +- return false; +- } +-}; +diff --git a/lib/DllPostProc.h b/lib/DllPostProc.h +deleted file mode 100644 +index ebba5e2..0000000 +--- a/lib/DllPostProc.h ++++ /dev/null +@@ -1,129 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "utils/log.h" +- +-extern "C" { +-#define HAVE_MMX +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS +-#endif +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +- +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +- #include +-#else +- #include "libavutil/avutil.h" +- #include "libpostproc/postprocess.h" +-#endif +-} +- +-#include "utils/CPUInfo.h" +- +-inline int PPCPUFlags() +-{ +- unsigned int cpuFeatures = g_cpuInfo.GetCPUFeatures(); +- int flags = 0; +- +- if (cpuFeatures & CPU_FEATURE_MMX) +- flags |= PP_CPU_CAPS_MMX; +- if (cpuFeatures & CPU_FEATURE_MMX2) +- flags |= PP_CPU_CAPS_MMX2; +- if (cpuFeatures & CPU_FEATURE_3DNOW) +- flags |= PP_CPU_CAPS_3DNOW; +- if (cpuFeatures & CPU_FEATURE_ALTIVEC) +- flags |= PP_CPU_CAPS_ALTIVEC; +- +- return flags; +-} +- +-class DllPostProcInterface +-{ +-public: +- virtual ~DllPostProcInterface() {} +- virtual void pp_postprocess(uint8_t * src[3], int srcStride[3], uint8_t * dst[3], int dstStride[3], +- int horizontalSize, int verticalSize, QP_STORE_T *QP_store, int QP_stride, +- pp_mode *mode, pp_context *ppContext, int pict_type)=0; +- virtual pp_mode *pp_get_mode_by_name_and_quality(char *name, int quality)=0; +- virtual void pp_free_mode(pp_mode *mode)=0; +- virtual pp_context *pp_get_context(int width, int height, int flags)=0; +- virtual void pp_free_context(pp_context *ppContext)=0; +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +- +-// We call directly. +-class DllPostProc : public DllDynamic, DllPostProcInterface +-{ +-public: +- +- virtual ~DllPostProc() {} +- virtual void pp_postprocess(uint8_t * src[3], int srcStride[3], uint8_t * dst[3], int dstStride[3], +- int horizontalSize, int verticalSize, QP_STORE_T *QP_store, int QP_stride, +- pp_mode *mode, pp_context *ppContext, int pict_type) { ::pp_postprocess((const uint8_t** )src, srcStride, dst, dstStride, horizontalSize, verticalSize, QP_store, QP_stride, mode, ppContext, pict_type); } +- virtual pp_mode *pp_get_mode_by_name_and_quality(char *name, int quality) { return ::pp_get_mode_by_name_and_quality(name, quality); } +- virtual void pp_free_mode(pp_mode *mode) { ::pp_free_mode(mode); } +- virtual pp_context *pp_get_context(int width, int height, int flags) { return ::pp_get_context(width, height, flags); } +- virtual void pp_free_context(pp_context *ppContext) { ::pp_free_context(ppContext); } +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllPostProc: Using libpostproc system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +-}; +- +-#else +-class DllPostProc : public DllDynamic, DllPostProcInterface +-{ +- DECLARE_DLL_WRAPPER(DllPostProc, DLL_PATH_LIBPOSTPROC) +- DEFINE_METHOD11(void, pp_postprocess, (uint8_t* p1[3], int p2[3], uint8_t * p3[3], int p4[3], +- int p5, int p6, QP_STORE_T *p7, int p8, +- pp_mode *p9, pp_context *p10, int p11)) +- DEFINE_METHOD2(pp_mode*, pp_get_mode_by_name_and_quality, (char *p1, int p2)) +- DEFINE_METHOD1(void, pp_free_mode, (pp_mode *p1)) +- DEFINE_METHOD3(pp_context*, pp_get_context, (int p1, int p2, int p3)) +- DEFINE_METHOD1(void, pp_free_context, (pp_context *p1)) +- +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD(pp_postprocess) +- RESOLVE_METHOD(pp_get_mode_by_name_and_quality) +- RESOLVE_METHOD(pp_free_mode) +- RESOLVE_METHOD(pp_get_context) +- RESOLVE_METHOD(pp_free_context) +- END_METHOD_RESOLVE() +-}; +- +-#endif +diff --git a/lib/DllSwResample.h b/lib/DllSwResample.h +deleted file mode 100644 +index cd1452b..0000000 +--- a/lib/DllSwResample.h ++++ /dev/null +@@ -1,131 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "utils/log.h" +- +-extern "C" { +-#ifndef HAVE_MMX +-#define HAVE_MMX +-#endif +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +-#if (defined USE_EXTERNAL_FFMPEG) +- #if (defined USE_LIBAV_HACKS) +- #include "xbmc-libav-hacks/libav_hacks.h" +- #else +- #include +- #endif +-#else +- #include "libswresample/swresample.h" +-#endif +-} +- +-class DllSwResampleInterface +-{ +-public: +- virtual ~DllSwResampleInterface() {} +- virtual struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)=0; +- virtual int swr_init(struct SwrContext *s)=0; +- virtual void swr_free(struct SwrContext **s)=0; +- virtual int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in , int in_count)=0; +- virtual int64_t swr_get_delay(struct SwrContext *s, int64_t base) = 0; +- virtual int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map) = 0; +- virtual int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) = 0; +- virtual int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance) = 0; +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +- +-// Use direct mapping +-class DllSwResample : public DllDynamic, DllSwResampleInterface +-{ +-public: +- virtual ~DllSwResample() {} +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllAvFormat: Using libswresample system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +- virtual struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx) { return ::swr_alloc_set_opts(s, out_ch_layout, out_sample_fmt, out_sample_rate, in_ch_layout, in_sample_fmt, in_sample_rate, log_offset, log_ctx); } +- virtual int swr_init(struct SwrContext *s) { return ::swr_init(s); } +- virtual void swr_free(struct SwrContext **s){ return ::swr_free(s); } +- virtual int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in , int in_count){ return ::swr_convert(s, out, out_count, in, in_count); } +- virtual int64_t swr_get_delay(struct SwrContext *s, int64_t base) { return ::swr_get_delay(s, base); } +- virtual int swr_set_channel_mapping (struct SwrContext *s, const int *channel_map) { return ::swr_set_channel_mapping(s, channel_map); } +- virtual int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) { return ::swr_set_matrix(s, matrix, stride); } +- virtual int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance) { return ::swr_set_compensation(s, sample_delta, compensation_distance); } +-}; +- +-#else +- +-class DllSwResample : public DllDynamic, DllSwResampleInterface +-{ +- DECLARE_DLL_WRAPPER(DllSwResample, DLL_PATH_LIBSWRESAMPLE) +- +- LOAD_SYMBOLS() +- +- DEFINE_METHOD9(SwrContext*, swr_alloc_set_opts, (struct SwrContext *p1, int64_t p2, enum AVSampleFormat p3, int p4, int64_t p5, enum AVSampleFormat p6, int p7, int p8, void * p9)); +- DEFINE_METHOD1(int, swr_init, (struct SwrContext *p1)) +- DEFINE_METHOD1(void, swr_free, (struct SwrContext **p1)) +- DEFINE_METHOD5(int, swr_convert, (struct SwrContext *p1, uint8_t **p2, int p3, const uint8_t **p4, int p5)) +- DEFINE_METHOD2(int64_t, swr_get_delay, (struct SwrContext *p1, int64_t p2)) +- DEFINE_METHOD2(int, swr_set_channel_mapping, (struct SwrContext *p1, const int *p2)) +- DEFINE_METHOD3(int, swr_set_matrix, (struct SwrContext *p1, const double *p2, int p3)) +- DEFINE_METHOD3(int, swr_set_compensation, (struct SwrContext *p1, int p2, int p3)) +- +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD(swr_alloc_set_opts) +- RESOLVE_METHOD(swr_init) +- RESOLVE_METHOD(swr_free) +- RESOLVE_METHOD(swr_convert) +- RESOLVE_METHOD(swr_get_delay) +- RESOLVE_METHOD(swr_set_channel_mapping) +- RESOLVE_METHOD(swr_set_matrix) +- RESOLVE_METHOD(swr_set_compensation) +- END_METHOD_RESOLVE() +- +- /* dependencies of libavformat */ +- DllAvUtil m_dllAvUtil; +- +-public: +- +- virtual bool Load() +- { +- if (!m_dllAvUtil.Load()) +- return false; +- return DllDynamic::Load(); +- } +-}; +- +-#endif +diff --git a/lib/DllSwScale.h b/lib/DllSwScale.h +deleted file mode 100644 +index 97e3b40..0000000 +--- a/lib/DllSwScale.h ++++ /dev/null +@@ -1,153 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#include "DynamicDll.h" +-#include "DllAvUtil.h" +-#include "utils/log.h" +- +-extern "C" { +-#ifndef HAVE_MMX +-#define HAVE_MMX +-#endif +- +-#ifndef __STDC_CONSTANT_MACROS +-#define __STDC_CONSTANT_MACROS +-#endif +- +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS +-#endif +- +-#ifndef __GNUC__ +-#pragma warning(disable:4244) +-#endif +- +-#if (defined USE_EXTERNAL_FFMPEG) +- #include +-#else +- #include "libswscale/swscale.h" +-#endif +-} +- +-#include "../xbmc/utils/CPUInfo.h" +- +-inline int SwScaleCPUFlags() +-{ +- unsigned int cpuFeatures = g_cpuInfo.GetCPUFeatures(); +- int flags = 0; +- +- if (cpuFeatures & CPU_FEATURE_MMX) +- flags |= SWS_CPU_CAPS_MMX; +- if (cpuFeatures & CPU_FEATURE_MMX2) +- flags |= SWS_CPU_CAPS_MMX2; +- if (cpuFeatures & CPU_FEATURE_3DNOW) +- flags |= SWS_CPU_CAPS_3DNOW; +- if (cpuFeatures & CPU_FEATURE_ALTIVEC) +- flags |= SWS_CPU_CAPS_ALTIVEC; +- +- return flags; +-} +- +-class DllSwScaleInterface +-{ +-public: +- virtual ~DllSwScaleInterface() {} +- +- virtual struct SwsContext *sws_getCachedContext(struct SwsContext *context, +- int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, +- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)=0; +- +- virtual struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, +- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)=0; +- +- virtual int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, +- int srcSliceH, uint8_t* dst[], int dstStride[])=0; +- +- virtual void sws_freeContext(struct SwsContext *context)=0; +-}; +- +-#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG) +- +-// We call into this library directly. +-class DllSwScale : public DllDynamic, public DllSwScaleInterface +-{ +-public: +- virtual ~DllSwScale() {} +- virtual struct SwsContext *sws_getCachedContext(struct SwsContext *context, +- int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, +- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param) +- { return ::sws_getCachedContext(context, srcW, srcH, (enum PixelFormat)srcFormat, dstW, dstH, (enum PixelFormat)dstFormat, flags, srcFilter, dstFilter, param); } +- +- virtual struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, +- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param) +- { return ::sws_getContext(srcW, srcH, (enum PixelFormat)srcFormat, dstW, dstH, (enum PixelFormat)dstFormat, flags, srcFilter, dstFilter, param); } +- +- virtual int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, +- int srcSliceH, uint8_t* dst[], int dstStride[]) +- { return ::sws_scale(context, src, srcStride, srcSliceY, srcSliceH, dst, dstStride); } +- virtual void sws_freeContext(struct SwsContext *context) { ::sws_freeContext(context); } +- +- // DLL faking. +- virtual bool ResolveExports() { return true; } +- virtual bool Load() { +-#if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG) +- CLog::Log(LOGDEBUG, "DllSwScale: Using libswscale system library"); +-#endif +- return true; +- } +- virtual void Unload() {} +-}; +- +-#else +- +-class DllSwScale : public DllDynamic, public DllSwScaleInterface +-{ +- DECLARE_DLL_WRAPPER(DllSwScale, DLL_PATH_LIBSWSCALE) +- DEFINE_METHOD11(struct SwsContext *, sws_getCachedContext, ( struct SwsContext *p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, +- SwsFilter * p9, SwsFilter * p10, double * p11)) +- DEFINE_METHOD10(struct SwsContext *, sws_getContext, ( int p1, int p2, int p3, int p4, int p5, int p6, int p7, +- SwsFilter * p8, SwsFilter * p9, double * p10)) +- DEFINE_METHOD7(int, sws_scale, (struct SwsContext *p1, uint8_t** p2, int *p3, int p4, int p5, uint8_t **p6, int *p7)) +- DEFINE_METHOD1(void, sws_freeContext, (struct SwsContext *p1)) +- +- BEGIN_METHOD_RESOLVE() +- RESOLVE_METHOD(sws_getCachedContext) +- RESOLVE_METHOD(sws_getContext) +- RESOLVE_METHOD(sws_scale) +- RESOLVE_METHOD(sws_freeContext) +- END_METHOD_RESOLVE() +- +- /* dependency of libswscale */ +- DllAvUtil m_dllAvUtil; +- +-public: +- virtual bool Load() +- { +- if (!m_dllAvUtil.Load()) +- return false; +- return DllDynamic::Load(); +- } +-}; +- +-#endif +diff --git a/lib/Makefile.in b/lib/Makefile.in +deleted file mode 100644 +index ca18a4a..0000000 +--- a/lib/Makefile.in ++++ /dev/null +@@ -1,103 +0,0 @@ +-ARCH=@ARCH@ +- +-AR=@AR@ +-LD=@LD@ +-CC=@CC@ +-CXX=@CXX@ +-SYSDIR=@abs_top_srcdir@/system/players/dvdplayer +- +-ifeq (@USE_ANDROID@,1) +-AVPREFIX=lib +-else +-AVPREFIX= +-endif +- +-AVFORMAT_SO=$(AVPREFIX)avformat-54-$(ARCH).so +-AVCODEC_SO=$(AVPREFIX)avcodec-54-$(ARCH).so +-AVUTIL_SO=$(AVPREFIX)avutil-52-$(ARCH).so +-AVFILTER_SO=$(AVPREFIX)avfilter-3-$(ARCH).so +-SWSCALE_SO=$(AVPREFIX)swscale-2-$(ARCH).so +-POSTPROC_SO=$(AVPREFIX)postproc-52-$(ARCH).so +-SWRESAMPLE_SO=$(AVPREFIX)swresample-0-$(ARCH).so +- +-DIRS= +-ifneq (@USE_EXTERNAL_FFMPEG@,1) +- DIRS+=ffmpeg +-endif +- +-LIBS= +-ifneq (@USE_EXTERNAL_FFMPEG@,1) +-ifneq (@USE_STATIC_FFMPEG@,1) +- LIBS+=$(AVUTIL_SO) \ +- $(AVCODEC_SO) \ +- $(AVFORMAT_SO) \ +- $(POSTPROC_SO) \ +- $(AVFILTER_SO) \ +- $(SWSCALE_SO) \ +- $(SWRESAMPLE_SO) +-endif +-endif +- +-.PHONY: $(DIRS) codecs +- +-ifneq ($(findstring osx,$(ARCH)), osx) +-ifneq (@USE_STATIC_FFMPEG@,1) +- +-codecs: $(addprefix $(SYSDIR)/, $(LIBS)); +- +-$(SYSDIR)/$(AVUTIL_SO): ffmpeg/libavutil/libavutil.so +- cp ffmpeg/libavutil/libavutil.so $@ +- +-$(SYSDIR)/$(AVCODEC_SO): ffmpeg/libavcodec/libavcodec.so +- cp ffmpeg/libavcodec/libavcodec.so $@ +- +-$(SYSDIR)/$(AVFORMAT_SO): ffmpeg/libavformat/libavformat.so +- cp ffmpeg/libavformat/libavformat.so $@ +- +-$(SYSDIR)/$(AVFILTER_SO): ffmpeg/libavfilter/libavfilter.so +- cp ffmpeg/libavfilter/libavfilter.so $@ +- +-$(SYSDIR)/$(SWSCALE_SO): ffmpeg/libswscale/libswscale.so +- cp ffmpeg/libswscale/libswscale.so $@ +- +-$(SYSDIR)/$(POSTPROC_SO): ffmpeg/libpostproc/libpostproc.so +- cp ffmpeg/libpostproc/libpostproc.so $@ +- +-$(SYSDIR)/$(SWRESAMPLE_SO): ffmpeg/libswresample/libswresample.so +- cp ffmpeg/libswresample/libswresample.so $@ +- +-ffmpeg/libavutil/libavutil.so : ffmpeg; +-ffmpeg/libavcodec/libavcodec.so : ffmpeg; +-ffmpeg/libavformat/libavformat.so : ffmpeg; +-ffmpeg/libavfilter/libavfilter.so : ffmpeg; +-ffmpeg/libswscale/libswscale.so : ffmpeg; +-ffmpeg/libpostproc/libpostproc.so : ffmpeg; +-ffmpeg/libswresample/libswresample.so : ffmpeg; +-endif +-endif +- +-ifeq (@USE_STATIC_FFMPEG@,1) +-ffmpeg/libavutil/libavutil.a : ffmpeg; +-ffmpeg/libavcodec/libavcodec.a : ffmpeg; +-ffmpeg/libavformat/libavformat.a : ffmpeg; +-ffmpeg/libavfilter/libavfilter.a : ffmpeg; +-ffmpeg/libswscale/libswscale.a : ffmpeg; +-ffmpeg/libpostproc/libpostproc.a : ffmpeg; +-ffmpeg/libswresample/libswresample.a : ffmpeg; +-endif +- +-ffmpeg: +- $(MAKE) -C $@ +-ifeq ($(findstring osx,$(ARCH)), osx) +- -$(AR) d ffmpeg/libavcodec/libavcodec.a log2_tab.o +- -$(AR) d ffmpeg/libavformat/libavformat.a log2_tab.o +- -$(AR) d ffmpeg/libswresample/libswresample.a log2_tab.o +-endif +- +-clean: +- rm -f $(addprefix $(SYSDIR)/, $(LIBS)) +- for d in $(DIRS); do (if test -f "$$d/Makefile"; then ($(MAKE) -C "$$d" clean); fi ); done +- +-distclean: +- rm -f $(addprefix $(SYSDIR)/, $(LIBS)) +- for d in $(DIRS); do (if test -f "$$d/Makefile"; then ($(MAKE) -C "$$d" distclean || $(MAKE) -C "$$d" clean); fi ); done +diff --git a/lib/xbmc-dll-symbols/DllAvFormat.c b/lib/xbmc-dll-symbols/DllAvFormat.c +deleted file mode 100644 +index a592a1f..0000000 +--- a/lib/xbmc-dll-symbols/DllAvFormat.c ++++ /dev/null +@@ -1,126 +0,0 @@ +-/* +- * various utility functions used within FFmpeg +- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard +- * +- * FFmpeg is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * FFmpeg is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with FFmpeg; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-/* Functions defined here are functions that cannot be resolved through the +- * ffmpeg shared libraries, yet are used in XBMC. +- */ +- +-#if (defined HAVE_CONFIG_H) && (!defined WIN32) +- #include "config.h" +-#endif +-#if (defined USE_EXTERNAL_FFMPEG) +-#include +- +-/* Taken from libavformat/utils.c */ +-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(54,0,0) +-static void flush_packet_queue(AVFormatContext *s) +-{ +- AVPacketList *pktl; +- +- for(;;) { +- pktl = s->packet_buffer; +- if (!pktl) +- break; +- s->packet_buffer = pktl->next; +- av_free_packet(&pktl->pkt); +- av_free(pktl); +- } +- while(s->raw_packet_buffer){ +- pktl = s->raw_packet_buffer; +- s->raw_packet_buffer = pktl->next; +- av_free_packet(&pktl->pkt); +- av_free(pktl); +- } +- s->packet_buffer_end= +- s->raw_packet_buffer_end= NULL; +-#ifdef RAW_PACKET_BUFFER_SIZE +- // Added on: 2009-06-25 +- s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; +-#endif +-} +-#else +-static void free_packet_buffer(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) +-{ +- while (*pkt_buf) { +- AVPacketList *pktl = *pkt_buf; +- *pkt_buf = pktl->next; +- av_free_packet(&pktl->pkt); +- av_freep(&pktl); +- } +- *pkt_buf_end = NULL; +-} +-/* XXX: suppress the packet queue */ +-static void flush_packet_queue(AVFormatContext *s) +-{ +- free_packet_buffer(&s->parse_queue, &s->parse_queue_end); +- free_packet_buffer(&s->packet_buffer, &s->packet_buffer_end); +- free_packet_buffer(&s->raw_packet_buffer, &s->raw_packet_buffer_end); +- +- s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; +-} +-#endif +- +-/* Taken from libavformat/utils.c +- * Original name is ff_read_frame_flush +- * */ +-void xbmc_read_frame_flush(AVFormatContext *s) +-{ +- AVStream *st; +- int i, j; +- +- flush_packet_queue(s); +- +-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(54,0,0) +- s->cur_st = NULL; +-#endif +- +- /* for each stream, reset read state */ +- for(i = 0; i < s->nb_streams; i++) { +- st = s->streams[i]; +- +- if (st->parser) { +- av_parser_close(st->parser); +- st->parser = NULL; +-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(54,0,0) +- av_free_packet(&st->cur_pkt); +-#endif +- } +- st->last_IP_pts = AV_NOPTS_VALUE; +-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(54,0,0) +- st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ +- st->reference_dts = AV_NOPTS_VALUE; +- /* fail safe */ +- st->cur_ptr = NULL; +- st->cur_len = 0; +-#else +-#define RELATIVE_TS_BASE (INT64_MAX - (1LL<<48)) +- if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE; +- else st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ +-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(55,0,0) +- st->reference_dts = AV_NOPTS_VALUE; +-#endif +- +- st->probe_packets = MAX_PROBE_PACKETS; +-#endif +- +- for(j=0; jpts_buffer[j]= AV_NOPTS_VALUE; +- } +-} +-#endif /* (defined USE_EXTERNAL_FFMPEG) */ +diff --git a/lib/xbmc-dll-symbols/Makefile b/lib/xbmc-dll-symbols/Makefile +deleted file mode 100644 +index d3e5198..0000000 +--- a/lib/xbmc-dll-symbols/Makefile ++++ /dev/null +@@ -1,6 +0,0 @@ +-SRCS = DllAvFormat.c +- +-LIB = dll-symbols.a +- +-include ../../Makefile.include +--include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +diff --git a/lib/xbmc-libav-hacks/Makefile b/lib/xbmc-libav-hacks/Makefile +deleted file mode 100644 +index ca447d4..0000000 +--- a/lib/xbmc-libav-hacks/Makefile ++++ /dev/null +@@ -1,6 +0,0 @@ +-SRCS = swresample.c alloc_output_context2.c buffersink.c accessors.c graphparser.c +- +-LIB = dll-libavhacks.a +- +-include ../../Makefile.include +--include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +diff --git a/lib/xbmc-libav-hacks/accessors.c b/lib/xbmc-libav-hacks/accessors.c +deleted file mode 100644 +index 417bf32..0000000 +--- a/lib/xbmc-libav-hacks/accessors.c ++++ /dev/null +@@ -1,35 +0,0 @@ +-/* +- * Copyright (C) 2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, write to +- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +- * http://www.gnu.org/copyleft/gpl.html +- * +- */ +- +-#include "libav_hacks.h" +- +-AVDictionary *av_frame_get_metadata (const AVFrame *frame) +-{ +- return NULL; +-} +- +-AVRational av_stream_get_r_frame_rate(const AVStream *s) +-{ +- AVRational zero; +- zero.num = 0; +- zero.den = 1; +- return zero; +-} +diff --git a/lib/xbmc-libav-hacks/alloc_output_context2.c b/lib/xbmc-libav-hacks/alloc_output_context2.c +deleted file mode 100644 +index b0aa5eb..0000000 +--- a/lib/xbmc-libav-hacks/alloc_output_context2.c ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* +- * Code copied from libavformat/mux.c +- * +- * Original license is: +- * +- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard +- * +- * This file is part of FFmpeg. +- * +- * FFmpeg is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * FFmpeg is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with FFmpeg; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-#include "libav_hacks.h" +- +-#include +- +-int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, +- const char *format, const char *filename) +-{ +- AVFormatContext *s = avformat_alloc_context(); +- int ret = 0; +- +- *avctx = NULL; +- if (!s) +- goto nomem; +- +- if (!oformat) { +- if (format) { +- oformat = av_guess_format(format, NULL, NULL); +- if (!oformat) { +- av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format); +- ret = AVERROR(EINVAL); +- goto error; +- } +- } else { +- oformat = av_guess_format(NULL, filename, NULL); +- if (!oformat) { +- ret = AVERROR(EINVAL); +- av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", +- filename); +- goto error; +- } +- } +- } +- +- s->oformat = oformat; +- if (s->oformat->priv_data_size > 0) { +- s->priv_data = av_mallocz(s->oformat->priv_data_size); +- if (!s->priv_data) +- goto nomem; +- if (s->oformat->priv_class) { +- *(const AVClass**)s->priv_data= s->oformat->priv_class; +- av_opt_set_defaults(s->priv_data); +- } +- } else +- s->priv_data = NULL; +- +- if (filename) +- av_strlcpy(s->filename, filename, sizeof(s->filename)); +- *avctx = s; +- return 0; +-nomem: +- av_log(s, AV_LOG_ERROR, "Out of memory\n"); +- ret = AVERROR(ENOMEM); +-error: +- avformat_free_context(s); +- return ret; +-} +diff --git a/lib/xbmc-libav-hacks/buffersink.c b/lib/xbmc-libav-hacks/buffersink.c +deleted file mode 100644 +index e3fdd35..0000000 +--- a/lib/xbmc-libav-hacks/buffersink.c ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* +- * Code copied from libavfilter/buffersink.c +- * +- * Original license is: +- * +- * Copyright (c) 2011 Stefano Sabatini +- * +- * This file is part of FFmpeg. +- * +- * FFmpeg is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * FFmpeg is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with FFmpeg; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-#include "libav_hacks.h" +- +-AVBufferSinkParams *av_buffersink_params_alloc(void) +-{ +- static const int pixel_fmts[] = { AV_PIX_FMT_NONE }; +- AVBufferSinkParams *params = av_malloc(sizeof(AVBufferSinkParams)); +- if (!params) +- return NULL; +- +- params->pixel_fmts = pixel_fmts; +- return params; +-} +diff --git a/lib/xbmc-libav-hacks/graphparser.c b/lib/xbmc-libav-hacks/graphparser.c +deleted file mode 100644 +index ef52392..0000000 +--- a/lib/xbmc-libav-hacks/graphparser.c ++++ /dev/null +@@ -1,451 +0,0 @@ +-/* +- * Copied code from libavfilter/graphparser.c +- * +- * Original license is: +- * +- * filter graph parser +- * Copyright (c) 2008 Vitor Sessak +- * Copyright (c) 2007 Bobby Bingham +- * +- * This file is part of FFmpeg. +- * +- * FFmpeg is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * FFmpeg is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with FFmpeg; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- */ +- +-#include "libav_hacks.h" +- +-#include +-#include +- +-#define WHITESPACES " \n\t" +- +-/** +- * Link two filters together. +- * +- * @see avfilter_link() +- */ +-static int link_filter(AVFilterContext *src, int srcpad, +- AVFilterContext *dst, int dstpad, +- void *log_ctx) +-{ +- int ret; +- if ((ret = avfilter_link(src, srcpad, dst, dstpad))) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Cannot create the link %s:%d -> %s:%d\n", +- src->filter->name, srcpad, dst->filter->name, dstpad); +- return ret; +- } +- +- return 0; +-} +- +-/** +- * Parse the name of a link, which has the format "[linkname]". +- * +- * @return a pointer (that need to be freed after use) to the name +- * between parenthesis +- */ +-static char *parse_link_name(const char **buf, void *log_ctx) +-{ +- const char *start = *buf; +- char *name; +- (*buf)++; +- +- name = av_get_token(buf, "]"); +- +- if (!name[0]) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Bad (empty?) label found in the following: \"%s\".\n", start); +- goto fail; +- } +- +- if (*(*buf)++ != ']') { +- av_log(log_ctx, AV_LOG_ERROR, +- "Mismatched '[' found in the following: \"%s\".\n", start); +- fail: +- av_freep(&name); +- } +- +- return name; +-} +- +-/** +- * Create an instance of a filter, initialize and insert it in the +- * filtergraph in *ctx. +- * +- * @param filt_ctx put here a filter context in case of successful creation and configuration, NULL otherwise. +- * @param ctx the filtergraph context +- * @param index an index which is supposed to be unique for each filter instance added to the filtergraph +- * @param filt_name the name of the filter to create +- * @param args the arguments provided to the filter during its initialization +- * @param log_ctx the log context to use +- * @return 0 in case of success, a negative AVERROR code otherwise +- */ +-static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index, +- const char *filt_name, const char *args, void *log_ctx) +-{ +- AVFilter *filt; +- char inst_name[30]; +- char tmp_args[256]; +- int ret; +- +- snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index); +- +- filt = avfilter_get_by_name(filt_name); +- +- if (!filt) { +- av_log(log_ctx, AV_LOG_ERROR, +- "No such filter: '%s'\n", filt_name); +- return AVERROR(EINVAL); +- } +- +- *filt_ctx = avfilter_graph_alloc_filter(ctx, filt, inst_name); +- if (!*filt_ctx) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Error creating filter '%s'\n", filt_name); +- return AVERROR(ENOMEM); +- } +- +- if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") && +- ctx->scale_sws_opts) { +- snprintf(tmp_args, sizeof(tmp_args), "%s:%s", +- args, ctx->scale_sws_opts); +- args = tmp_args; +- } +- +- ret = avfilter_init_str(*filt_ctx, args); +- if (ret < 0) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Error initializing filter '%s'", filt_name); +- if (args) +- av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args); +- av_log(log_ctx, AV_LOG_ERROR, "\n"); +- return ret; +- } +- +- return 0; +-} +- +-/** +- * Parse a string of the form FILTER_NAME[=PARAMS], and create a +- * corresponding filter instance which is added to graph with +- * create_filter(). +- * +- * @param filt_ctx Pointer that is set to the created and configured filter +- * context on success, set to NULL on failure. +- * @param filt_ctx put here a pointer to the created filter context on +- * success, NULL otherwise +- * @param buf pointer to the buffer to parse, *buf will be updated to +- * point to the char next after the parsed string +- * @param index an index which is assigned to the created filter +- * instance, and which is supposed to be unique for each filter +- * instance added to the filtergraph +- * @return 0 in case of success, a negative AVERROR code otherwise +- */ +-static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph, +- int index, void *log_ctx) +-{ +- char *opts = NULL; +- char *name = av_get_token(buf, "=,;[\n"); +- int ret; +- +- if (**buf == '=') { +- (*buf)++; +- opts = av_get_token(buf, "[],;\n"); +- } +- +- ret = create_filter(filt_ctx, graph, index, name, opts, log_ctx); +- av_free(name); +- av_free(opts); +- return ret; +-} +- +-static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links) +-{ +- AVFilterInOut *ret; +- +- while (*links && (!(*links)->name || strcmp((*links)->name, label))) +- links = &((*links)->next); +- +- ret = *links; +- +- if (ret) { +- *links = ret->next; +- ret->next = NULL; +- } +- +- return ret; +-} +- +-static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element) +-{ +- element->next = *inouts; +- *inouts = element; +-} +- +-static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element) +-{ +- while (*inouts && (*inouts)->next) +- inouts = &((*inouts)->next); +- +- if (!*inouts) +- *inouts = *element; +- else +- (*inouts)->next = *element; +- *element = NULL; +-} +- +-static int link_filter_inouts(AVFilterContext *filt_ctx, +- AVFilterInOut **curr_inputs, +- AVFilterInOut **open_inputs, void *log_ctx) +-{ +- int pad, ret; +- +- for (pad = 0; pad < filt_ctx->nb_inputs; pad++) { +- AVFilterInOut *p = *curr_inputs; +- +- if (p) { +- *curr_inputs = (*curr_inputs)->next; +- p->next = NULL; +- } else if (!(p = av_mallocz(sizeof(*p)))) +- return AVERROR(ENOMEM); +- +- if (p->filter_ctx) { +- ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx); +- av_free(p->name); +- av_free(p); +- if (ret < 0) +- return ret; +- } else { +- p->filter_ctx = filt_ctx; +- p->pad_idx = pad; +- append_inout(open_inputs, &p); +- } +- } +- +- if (*curr_inputs) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Too many inputs specified for the \"%s\" filter.\n", +- filt_ctx->filter->name); +- return AVERROR(EINVAL); +- } +- +- pad = filt_ctx->nb_outputs; +- while (pad--) { +- AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut)); +- if (!currlinkn) +- return AVERROR(ENOMEM); +- currlinkn->filter_ctx = filt_ctx; +- currlinkn->pad_idx = pad; +- insert_inout(curr_inputs, currlinkn); +- } +- +- return 0; +-} +- +-static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, +- AVFilterInOut **open_outputs, void *log_ctx) +-{ +- AVFilterInOut *parsed_inputs = NULL; +- int pad = 0; +- +- while (**buf == '[') { +- char *name = parse_link_name(buf, log_ctx); +- AVFilterInOut *match; +- +- if (!name) +- return AVERROR(EINVAL); +- +- /* First check if the label is not in the open_outputs list */ +- match = extract_inout(name, open_outputs); +- +- if (match) { +- av_free(name); +- } else { +- /* Not in the list, so add it as an input */ +- if (!(match = av_mallocz(sizeof(AVFilterInOut)))) { +- av_free(name); +- return AVERROR(ENOMEM); +- } +- match->name = name; +- match->pad_idx = pad; +- } +- +- append_inout(&parsed_inputs, &match); +- +- *buf += strspn(*buf, WHITESPACES); +- pad++; +- } +- +- append_inout(&parsed_inputs, curr_inputs); +- *curr_inputs = parsed_inputs; +- +- return pad; +-} +- +-static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, +- AVFilterInOut **open_inputs, +- AVFilterInOut **open_outputs, void *log_ctx) +-{ +- int ret, pad = 0; +- +- while (**buf == '[') { +- char *name = parse_link_name(buf, log_ctx); +- AVFilterInOut *match; +- +- AVFilterInOut *input = *curr_inputs; +- +- if (!name) +- return AVERROR(EINVAL); +- +- if (!input) { +- av_log(log_ctx, AV_LOG_ERROR, +- "No output pad can be associated to link label '%s'.\n", name); +- av_free(name); +- return AVERROR(EINVAL); +- } +- *curr_inputs = (*curr_inputs)->next; +- +- /* First check if the label is not in the open_inputs list */ +- match = extract_inout(name, open_inputs); +- +- if (match) { +- if ((ret = link_filter(input->filter_ctx, input->pad_idx, +- match->filter_ctx, match->pad_idx, log_ctx)) < 0) { +- av_free(name); +- return ret; +- } +- av_free(match->name); +- av_free(name); +- av_free(match); +- av_free(input); +- } else { +- /* Not in the list, so add the first input as a open_output */ +- input->name = name; +- insert_inout(open_outputs, input); +- } +- *buf += strspn(*buf, WHITESPACES); +- pad++; +- } +- +- return pad; +-} +- +-static int parse_sws_flags(const char **buf, AVFilterGraph *graph) +-{ +- char *p = strchr(*buf, ';'); +- +- if (strncmp(*buf, "sws_flags=", 10)) +- return 0; +- +- if (!p) { +- av_log(graph, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n"); +- return AVERROR(EINVAL); +- } +- +- *buf += 4; // keep the 'flags=' part +- +- av_freep(&graph->scale_sws_opts); +- if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1))) +- return AVERROR(ENOMEM); +- av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1); +- +- *buf = p + 1; +- return 0; +-} +- +-int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, +- AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr, +- void *log_ctx) +-{ +- int index = 0, ret = 0; +- char chr = 0; +- +- AVFilterInOut *curr_inputs = NULL; +- AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL; +- AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL; +- +- if ((ret = parse_sws_flags(&filters, graph)) < 0) +- goto end; +- +- do { +- AVFilterContext *filter; +- const char *filterchain = filters; +- filters += strspn(filters, WHITESPACES); +- +- if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0) +- goto end; +- +- if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0) +- goto end; +- +- if (filter->input_count == 1 && !curr_inputs && !index) { +- /* First input pad, assume it is "[in]" if not specified */ +- const char *tmp = "[in]"; +- if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0) +- goto end; +- } +- +- if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0) +- goto end; +- +- if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, +- log_ctx)) < 0) +- goto end; +- +- filters += strspn(filters, WHITESPACES); +- chr = *filters++; +- +- if (chr == ';' && curr_inputs) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Invalid filterchain containing an unlabelled output pad: \"%s\"\n", +- filterchain); +- ret = AVERROR(EINVAL); +- goto end; +- } +- index++; +- } while (chr == ',' || chr == ';'); +- +- if (chr) { +- av_log(log_ctx, AV_LOG_ERROR, +- "Unable to parse graph description substring: \"%s\"\n", +- filters - 1); +- ret = AVERROR(EINVAL); +- goto end; +- } +- +- if (curr_inputs) { +- /* Last output pad, assume it is "[out]" if not specified */ +- const char *tmp = "[out]"; +- if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs, +- log_ctx)) < 0) +- goto end; +- } +- +-end: +- /* clear open_in/outputs only if not passed as parameters */ +- if (open_inputs_ptr) *open_inputs_ptr = open_inputs; +- else avfilter_inout_free(&open_inputs); +- if (open_outputs_ptr) *open_outputs_ptr = open_outputs; +- else avfilter_inout_free(&open_outputs); +- avfilter_inout_free(&curr_inputs); +- +- if (ret < 0) { +- while (graph->nb_filters) +- avfilter_free(graph->filters[0]); +- av_freep(&graph->filters); +- } +- return ret; +-} +diff --git a/lib/xbmc-libav-hacks/libav_hacks.h b/lib/xbmc-libav-hacks/libav_hacks.h +deleted file mode 100644 +index f81e29e..0000000 +--- a/lib/xbmc-libav-hacks/libav_hacks.h ++++ /dev/null +@@ -1,96 +0,0 @@ +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#ifndef __LIBAV_HACKS_H +-#define __LIBAV_HACKS_H +- +-#include +-#include +-#include +-#include +-#include +- +-#if LIBAVUTIL_VERSION_MICRO >= 100 +-#error "You should not enable libav hacks when building against FFmpeg." +-#endif +- +-#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,8,0) +-#error "Your libav version is too old. Please update to libav-10 or git master." +-#endif +- +-// libavutil +- +-#define AVFRAME_IN_LAVU +- +-#define AV_CODEC_ID_OTF AV_CODEC_ID_TTF +-#define AV_CODEC_ID_SUBRIP AV_CODEC_ID_FIRST_SUBTITLE +- +-AVDictionary *av_frame_get_metadata (const AVFrame *frame); +- +-// libavformat +- +-int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, +- const char *format_name, const char *filename); +- +-#define AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE +- +-AVRational av_stream_get_r_frame_rate(const AVStream *s); +- +-// libavresample +- +-#define SwrContext AVAudioResampleContext +- +-struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, +- int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, +- int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, +- int log_offset, void *log_ctx); +- +-int swr_init(struct SwrContext *s); +- +-void swr_free(struct SwrContext **s); +- +-int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, +- const uint8_t **in , int in_count); +- +-int64_t swr_get_delay(struct SwrContext *s, int64_t base); +- +-int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); +- +-int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride); +- +-int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance); +- +-// libavfilter +- +-#define LIBAVFILTER_AVFRAME_BASED +- +-typedef struct { +- const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE +-} AVBufferSinkParams; +- +-AVBufferSinkParams *av_buffersink_params_alloc(void); +- +-#define HAVE_AVFILTER_GRAPH_PARSE_PTR +- +-int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, +- AVFilterInOut **inputs, AVFilterInOut **outputs, +- void *log_ctx); +- +-#endif +diff --git a/lib/xbmc-libav-hacks/pkgconfig/libswresample.pc b/lib/xbmc-libav-hacks/pkgconfig/libswresample.pc +deleted file mode 100644 +index 1319d85..0000000 +--- a/lib/xbmc-libav-hacks/pkgconfig/libswresample.pc ++++ /dev/null +@@ -1,4 +0,0 @@ +-Name: libswresample to libavresample +-Version: 0 +-Description: Hack to provide libswresample through libavresample +-Requires: libavresample +diff --git a/lib/xbmc-libav-hacks/swresample.c b/lib/xbmc-libav-hacks/swresample.c +deleted file mode 100644 +index f674ef7..0000000 +--- a/lib/xbmc-libav-hacks/swresample.c ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* +- * Copyright (C) 2005-2013 Team XBMC +- * http://xbmc.org +- * +- * This Program 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, or (at your option) +- * any later version. +- * +- * This Program 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 XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#include "libav_hacks.h" +- +-#include +-#include +- +-struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, +- int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, +- int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, +- int log_offset, void *log_ctx) +-{ +- AVAudioResampleContext *ret = avresample_alloc_context(); +- av_opt_set_int(ret, "out_channel_layout", out_ch_layout , 0); +- av_opt_set_int(ret, "out_sample_fmt" , out_sample_fmt , 0); +- av_opt_set_int(ret, "out_sample_rate" , out_sample_rate, 0); +- av_opt_set_int(ret, "in_channel_layout" , in_ch_layout , 0); +- av_opt_set_int(ret, "in_sample_fmt" , in_sample_fmt , 0); +- av_opt_set_int(ret, "in_sample_rate" , in_sample_rate , 0); +- return ret; +-} +- +- +-int swr_init(struct SwrContext *s) +-{ +- return avresample_open(s); +-} +- +-void swr_free(struct SwrContext **s) +-{ +- avresample_close(*s); +- *s = NULL; +-} +- +-int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, +- const uint8_t **in , int in_count) +-{ +- return avresample_convert(s, out, 0, out_count, (uint8_t**)in, 0,in_count); +-} +- +-int64_t swr_get_delay(struct SwrContext *s, int64_t base) +-{ +- int64_t in_sr, out_sr; +- av_opt_get_int(s, "in_sample_rate", 0, &in_sr); +- av_opt_get_int(s, "out_sample_rate", 0, &out_sr); +- return av_rescale_rnd(avresample_available(s), base, out_sr, AV_ROUND_UP) + av_rescale_rnd(avresample_get_delay(s), base, in_sr, AV_ROUND_UP); +-} +- +-int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map) +-{ +- return avresample_set_channel_mapping(s, channel_map); +-} +- +-int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) +-{ +- return avresample_set_matrix(s, matrix, stride); +-} +- +-int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance) +-{ +- return avresample_set_compensation(s, sample_delta, compensation_distance); +-} +diff --git a/xbmc/addons/AddonCallbacksCodec.cpp b/xbmc/addons/AddonCallbacksCodec.cpp +index 711cc5c..8ae1e4e 100644 +--- a/xbmc/addons/AddonCallbacksCodec.cpp ++++ b/xbmc/addons/AddonCallbacksCodec.cpp +@@ -21,10 +21,13 @@ + #include "Application.h" + #include "Addon.h" + #include "AddonCallbacksCodec.h" +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" + #include "utils/StringUtils.h" + ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++} ++ + namespace ADDON + { + class CCodecIds +@@ -57,23 +60,12 @@ class CCodecIds + private: + CCodecIds(void) + { +- DllAvCodec dllAvCodec; +- DllAvFormat dllAvFormat; +- +- // load ffmpeg and register formats +- if (!dllAvCodec.Load() || !dllAvFormat.Load()) +- { +- CLog::Log(LOGWARNING, "failed to load ffmpeg"); +- return; +- } +- dllAvFormat.av_register_all(); +- + // get ids and names + AVCodec* codec = NULL; + xbmc_codec_t tmp; +- while ((codec = dllAvCodec.av_codec_next(codec))) ++ while ((codec = av_codec_next(codec))) + { +- if (dllAvCodec.av_codec_is_decoder(codec)) ++ if (av_codec_is_decoder(codec)) + { + tmp.codec_type = (xbmc_codec_type_t)codec->type; + tmp.codec_id = codec->id; +diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp +index 0f20c5f..c6756e7 100644 +--- a/xbmc/cdrip/EncoderFFmpeg.cpp ++++ b/xbmc/cdrip/EncoderFFmpeg.cpp +@@ -58,19 +58,15 @@ CEncoderFFmpeg::CEncoderFFmpeg(): + + bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int iInBits) + { +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load() || !m_dllSwResample.Load()) return false; +- m_dllAvFormat.av_register_all(); +- m_dllAvCodec.avcodec_register_all(); +- + CStdString filename = URIUtils::GetFileName(strFile); +- if(m_dllAvFormat.avformat_alloc_output_context2(&m_Format,NULL,NULL,filename.c_str())) ++ if(avformat_alloc_output_context2(&m_Format,NULL,NULL,filename.c_str())) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Unable to guess the output format for the file %s", filename.c_str()); + return false; + } + + AVCodec *codec; +- codec = m_dllAvCodec.avcodec_find_encoder(m_Format->oformat->audio_codec); ++ codec = avcodec_find_encoder(m_Format->oformat->audio_codec); + + if (!codec) + { +@@ -78,10 +74,10 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + return false; + } + +- m_Format->pb = m_dllAvFormat.avio_alloc_context(m_BCBuffer, sizeof(m_BCBuffer), AVIO_FLAG_WRITE, this, NULL, avio_write_callback, avio_seek_callback); ++ m_Format->pb = avio_alloc_context(m_BCBuffer, sizeof(m_BCBuffer), AVIO_FLAG_WRITE, this, NULL, avio_write_callback, avio_seek_callback); + if (!m_Format->pb) + { +- m_dllAvUtil.av_freep(&m_Format); ++ av_freep(&m_Format); + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate ByteIOContext"); + return false; + } +@@ -89,11 +85,11 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + m_Format->bit_rate = CSettings::Get().GetInt("audiocds.bitrate") * 1000; + + /* add a stream to it */ +- m_Stream = m_dllAvFormat.avformat_new_stream(m_Format, codec); ++ m_Stream = avformat_new_stream(m_Format, codec); + if (!m_Stream) + { +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate AVStream context"); + return false; + } +@@ -105,7 +101,7 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + m_CodecCtx->bit_rate = m_Format->bit_rate; + m_CodecCtx->sample_rate = iInRate; + m_CodecCtx->channels = iInChannels; +- m_CodecCtx->channel_layout = m_dllAvUtil.av_get_default_channel_layout(iInChannels); ++ m_CodecCtx->channel_layout = av_get_default_channel_layout(iInChannels); + m_CodecCtx->time_base.num = 1; + m_CodecCtx->time_base.den = iInRate; + /* Allow experimental encoders (like FFmpeg builtin AAC encoder) */ +@@ -123,9 +119,9 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + case 16: m_InFormat = AV_SAMPLE_FMT_S16; break; + case 32: m_InFormat = AV_SAMPLE_FMT_S32; break; + default: +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + +@@ -134,30 +130,30 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + + m_NeedConversion = (m_OutFormat != m_InFormat); + +- if (m_OutFormat <= AV_SAMPLE_FMT_NONE || m_dllAvCodec.avcodec_open2(m_CodecCtx, codec, NULL)) ++ if (m_OutFormat <= AV_SAMPLE_FMT_NONE || avcodec_open2(m_CodecCtx, codec, NULL)) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to open the codec %s", codec->long_name ? codec->long_name : codec->name); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + + /* calculate how many bytes we need per frame */ + m_NeededFrames = m_CodecCtx->frame_size; +- m_NeededBytes = m_dllAvUtil.av_samples_get_buffer_size(NULL, iInChannels, m_NeededFrames, m_InFormat, 0); +- m_Buffer = (uint8_t*)m_dllAvUtil.av_malloc(m_NeededBytes); ++ m_NeededBytes = av_samples_get_buffer_size(NULL, iInChannels, m_NeededFrames, m_InFormat, 0); ++ m_Buffer = (uint8_t*)av_malloc(m_NeededBytes); + m_BufferSize = 0; + +- m_BufferFrame = m_dllAvCodec.avcodec_alloc_frame(); ++ m_BufferFrame = avcodec_alloc_frame(); + if(!m_BufferFrame || !m_Buffer) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate necessary buffers"); +- if(m_BufferFrame) m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); +- if(m_Buffer) m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ if(m_BufferFrame) avcodec_free_frame(&m_BufferFrame); ++ if(m_Buffer) av_freep(&m_Buffer); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + +@@ -165,59 +161,59 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + m_BufferFrame->format = m_InFormat; + m_BufferFrame->channel_layout = m_CodecCtx->channel_layout; + +- m_dllAvCodec.avcodec_fill_audio_frame(m_BufferFrame, iInChannels, m_InFormat, m_Buffer, m_NeededBytes, 0); ++ avcodec_fill_audio_frame(m_BufferFrame, iInChannels, m_InFormat, m_Buffer, m_NeededBytes, 0); + + if(m_NeedConversion) + { +- m_SwrCtx = m_dllSwResample.swr_alloc_set_opts(NULL, ++ m_SwrCtx = swr_alloc_set_opts(NULL, + m_CodecCtx->channel_layout, m_OutFormat, m_CodecCtx->sample_rate, + m_CodecCtx->channel_layout, m_InFormat, m_CodecCtx->sample_rate, + 0, NULL); +- if(!m_SwrCtx || m_dllSwResample.swr_init(m_SwrCtx) < 0) ++ if(!m_SwrCtx || swr_init(m_SwrCtx) < 0) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to initialize the resampler"); +- m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); +- m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ avcodec_free_frame(&m_BufferFrame); ++ av_freep(&m_Buffer); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + +- m_ResampledBufferSize = m_dllAvUtil.av_samples_get_buffer_size(NULL, iInChannels, m_NeededFrames, m_OutFormat, 0); +- m_ResampledBuffer = (uint8_t*)m_dllAvUtil.av_malloc(m_ResampledBufferSize); +- m_ResampledFrame = m_dllAvCodec.avcodec_alloc_frame(); ++ m_ResampledBufferSize = av_samples_get_buffer_size(NULL, iInChannels, m_NeededFrames, m_OutFormat, 0); ++ m_ResampledBuffer = (uint8_t*)av_malloc(m_ResampledBufferSize); ++ m_ResampledFrame = avcodec_alloc_frame(); + if(!m_ResampledBuffer || !m_ResampledFrame) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate a frame for resampling"); +- if (m_ResampledFrame) m_dllAvCodec.avcodec_free_frame(&m_ResampledFrame); +- if (m_ResampledBuffer) m_dllAvUtil.av_freep(&m_ResampledBuffer); +- if (m_SwrCtx) m_dllSwResample.swr_free(&m_SwrCtx); +- m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); +- m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ if (m_ResampledFrame) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); ++ if (m_SwrCtx) swr_free(&m_SwrCtx); ++ avcodec_free_frame(&m_BufferFrame); ++ av_freep(&m_Buffer); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + m_ResampledFrame->nb_samples = m_NeededFrames; + m_ResampledFrame->format = m_OutFormat; + m_ResampledFrame->channel_layout = m_CodecCtx->channel_layout; +- m_dllAvCodec.avcodec_fill_audio_frame(m_ResampledFrame, iInChannels, m_OutFormat, m_ResampledBuffer, m_ResampledBufferSize, 0); ++ avcodec_fill_audio_frame(m_ResampledFrame, iInChannels, m_OutFormat, m_ResampledBuffer, m_ResampledBufferSize, 0); + } + + /* set input stream information and open the file */ + if (!CEncoder::Init(strFile, iInChannels, iInRate, iInBits)) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to call CEncoder::Init"); +- if (m_ResampledFrame ) m_dllAvCodec.avcodec_free_frame(&m_ResampledFrame); +- if (m_ResampledBuffer) m_dllAvUtil.av_freep(&m_ResampledBuffer); +- if (m_SwrCtx) m_dllSwResample.swr_free(&m_SwrCtx); +- m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); +- m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); ++ if (m_SwrCtx) swr_free(&m_SwrCtx); ++ avcodec_free_frame(&m_BufferFrame); ++ av_freep(&m_Buffer); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + +@@ -230,17 +226,17 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + SetTag("encoder" , "XBMC FFmpeg Encoder"); + + /* write the header */ +- if (m_dllAvFormat.avformat_write_header(m_Format, NULL) != 0) ++ if (avformat_write_header(m_Format, NULL) != 0) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to write the header"); +- if (m_ResampledFrame ) m_dllAvCodec.avcodec_free_frame(&m_ResampledFrame); +- if (m_ResampledBuffer) m_dllAvUtil.av_freep(&m_ResampledBuffer); +- if (m_SwrCtx) m_dllSwResample.swr_free(&m_SwrCtx); +- m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); +- m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvUtil.av_freep(&m_Stream); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format); ++ if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); ++ if (m_SwrCtx) swr_free(&m_SwrCtx); ++ avcodec_free_frame(&m_BufferFrame); ++ av_freep(&m_Buffer); ++ av_freep(&m_Stream); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format); + return false; + } + +@@ -251,7 +247,7 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + + void CEncoderFFmpeg::SetTag(const CStdString tag, const CStdString value) + { +- m_dllAvUtil.av_dict_set(&m_Format->metadata, tag.c_str(), value.c_str(), 0); ++ av_dict_set(&m_Format->metadata, tag.c_str(), value.c_str(), 0); + } + + int CEncoderFFmpeg::avio_write_callback(void *opaque, uint8_t *buf, int buf_size) +@@ -296,13 +292,13 @@ bool CEncoderFFmpeg::WriteFrame() + int encoded, got_output; + AVFrame* frame; + +- m_dllAvCodec.av_init_packet(&m_Pkt); ++ av_init_packet(&m_Pkt); + m_Pkt.data = NULL; + m_Pkt.size = 0; + + if(m_NeedConversion) + { +- if (m_dllSwResample.swr_convert(m_SwrCtx, m_ResampledFrame->extended_data, m_NeededFrames, (const uint8_t**)m_BufferFrame->extended_data, m_NeededFrames) < 0) ++ if (swr_convert(m_SwrCtx, m_ResampledFrame->extended_data, m_NeededFrames, (const uint8_t**)m_BufferFrame->extended_data, m_NeededFrames) < 0) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::WriteFrame - Error resampling audio"); + return false; +@@ -311,7 +307,7 @@ bool CEncoderFFmpeg::WriteFrame() + } + else frame = m_BufferFrame; + +- encoded = m_dllAvCodec.avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); ++ encoded = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); + + m_BufferSize = 0; + +@@ -323,15 +319,15 @@ bool CEncoderFFmpeg::WriteFrame() + if (got_output) + { + if (m_CodecCtx->coded_frame && m_CodecCtx->coded_frame->pts != AV_NOPTS_VALUE) +- m_Pkt.pts = m_dllAvUtil.av_rescale_q(m_CodecCtx->coded_frame->pts, m_Stream->time_base, m_CodecCtx->time_base); ++ m_Pkt.pts = av_rescale_q(m_CodecCtx->coded_frame->pts, m_Stream->time_base, m_CodecCtx->time_base); + +- if (m_dllAvFormat.av_write_frame(m_Format, &m_Pkt) < 0) { ++ if (av_write_frame(m_Format, &m_Pkt) < 0) { + CLog::Log(LOGERROR, "CEncoderFFMmpeg::WriteFrame - Failed to write the frame data"); + return false; + } + } + +- m_dllAvCodec.av_free_packet(&m_Pkt); ++ av_free_packet(&m_Pkt); + + return true; + } +@@ -348,34 +344,30 @@ bool CEncoderFFmpeg::Close() + } + + /* Flush if needed */ +- m_dllAvUtil.av_freep(&m_Buffer); +- m_dllAvCodec.avcodec_free_frame(&m_BufferFrame); ++ av_freep(&m_Buffer); ++ avcodec_free_frame(&m_BufferFrame); + +- if (m_SwrCtx) m_dllSwResample.swr_free(&m_SwrCtx); +- if (m_ResampledFrame ) m_dllAvCodec.avcodec_free_frame(&m_ResampledFrame); +- if (m_ResampledBuffer) m_dllAvUtil.av_freep(&m_ResampledBuffer); ++ if (m_SwrCtx) swr_free(&m_SwrCtx); ++ if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); + m_NeedConversion = false; + + WriteFrame(); + + /* write the trailer */ +- m_dllAvFormat.av_write_trailer(m_Format); ++ av_write_trailer(m_Format); + FlushStream(); + FileClose(); + + /* cleanup */ +- m_dllAvCodec.avcodec_close(m_CodecCtx); +- m_dllAvUtil.av_freep(&m_Stream ); +- m_dllAvUtil.av_freep(&m_Format->pb); +- m_dllAvUtil.av_freep(&m_Format ); ++ avcodec_close(m_CodecCtx); ++ av_freep(&m_Stream ); ++ av_freep(&m_Format->pb); ++ av_freep(&m_Format ); + } + + m_BufferSize = 0; + +- m_dllAvFormat.Unload(); +- m_dllAvUtil .Unload(); +- m_dllAvCodec .Unload(); +- m_dllSwResample.Unload(); + return true; + } + +diff --git a/xbmc/cdrip/EncoderFFmpeg.h b/xbmc/cdrip/EncoderFFmpeg.h +index a16c7e9..7155796 100644 +--- a/xbmc/cdrip/EncoderFFmpeg.h ++++ b/xbmc/cdrip/EncoderFFmpeg.h +@@ -22,10 +22,13 @@ + */ + + #include "Encoder.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" +-#include "DllSwResample.h" ++ ++extern "C" { ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++#include "libswresample/swresample.h" ++} + + class CEncoderFFmpeg : public CEncoder + { +@@ -38,10 +41,6 @@ class CEncoderFFmpeg : public CEncoder + void AddTag(int key, const char* value); + + private: +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- DllAvFormat m_dllAvFormat; +- DllSwResample m_dllSwResample; + + AVFormatContext *m_Format; + AVCodecContext *m_CodecCtx; +diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +index b91ed43..5d9e2fb 100644 +--- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp ++++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +@@ -46,10 +46,10 @@ CAEEncoderFFmpeg::CAEEncoderFFmpeg(): + CAEEncoderFFmpeg::~CAEEncoderFFmpeg() + { + Reset(); +- m_dllAvUtil.av_freep(&m_CodecCtx); +- m_dllAvUtil.av_freep(&m_ResampBuffer); ++ av_freep(&m_CodecCtx); ++ av_freep(&m_ResampBuffer); + if (m_SwrCtx) +- m_dllSwResample.swr_free(&m_SwrCtx); ++ swr_free(&m_SwrCtx); + } + + bool CAEEncoderFFmpeg::IsCompatible(AEAudioFormat format) +@@ -102,11 +102,6 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input + { + Reset(); + +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwResample.Load()) +- return false; +- +- m_dllAvCodec.avcodec_register_all(); +- + bool ac3 = CSettings::Get().GetBool("audiooutput.ac3passthrough"); + + AVCodec *codec = NULL; +@@ -119,7 +114,7 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input + m_CodecID = AV_CODEC_ID_DTS; + m_PackFunc = &CAEPackIEC61937::PackDTS_1024; + m_BitRate = DTS_ENCODE_BITRATE; +- codec = m_dllAvCodec.avcodec_find_encoder(m_CodecID); ++ codec = avcodec_find_encoder(m_CodecID); + } + #endif + +@@ -130,14 +125,14 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input + m_CodecID = AV_CODEC_ID_AC3; + m_PackFunc = &CAEPackIEC61937::PackAC3; + m_BitRate = AC3_ENCODE_BITRATE; +- codec = m_dllAvCodec.avcodec_find_encoder(m_CodecID); ++ codec = avcodec_find_encoder(m_CodecID); + } + + /* check we got the codec */ + if (!codec) + return false; + +- m_CodecCtx = m_dllAvCodec.avcodec_alloc_context3(codec); ++ m_CodecCtx = avcodec_alloc_context3(codec); + m_CodecCtx->bit_rate = m_BitRate; + m_CodecCtx->sample_rate = format.m_sampleRate; + m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; +@@ -220,9 +215,9 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input + m_CodecCtx->channels = BuildChannelLayout(m_CodecCtx->channel_layout, m_Layout); + + /* open the codec */ +- if (m_dllAvCodec.avcodec_open2(m_CodecCtx, codec, NULL)) ++ if (avcodec_open2(m_CodecCtx, codec, NULL)) + { +- m_dllAvUtil.av_freep(&m_CodecCtx); ++ av_freep(&m_CodecCtx); + return false; + } + +@@ -239,11 +234,11 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input + + if (m_NeedConversion) + { +- m_SwrCtx = m_dllSwResample.swr_alloc_set_opts(NULL, ++ m_SwrCtx = swr_alloc_set_opts(NULL, + m_CodecCtx->channel_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, + m_CodecCtx->channel_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, + 0, NULL); +- if (!m_SwrCtx || m_dllSwResample.swr_init(m_SwrCtx) < 0) ++ if (!m_SwrCtx || swr_init(m_SwrCtx) < 0) + { + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Initialize - Failed to initialise resampler."); + return false; +@@ -284,14 +279,14 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + + /* size of the buffer sent to the encoder: either from the input data or after + * conversion, in all cases it is in the m_CodecCtx->sample_fmt format */ +- int buf_size = m_dllAvUtil.av_samples_get_buffer_size(NULL, m_CodecCtx->channels, frames, m_CodecCtx->sample_fmt, 0); ++ int buf_size = av_samples_get_buffer_size(NULL, m_CodecCtx->channels, frames, m_CodecCtx->sample_fmt, 0); + assert(buf_size>0); + + /* allocate the input frame + * sadly, we have to alloc/dealloc it everytime since we have no guarantee the + * data argument will be constant over iterated calls and the frame needs to + * setup pointers inside data */ +- frame = m_dllAvCodec.avcodec_alloc_frame(); ++ frame = avcodec_alloc_frame(); + if (!frame) + return 0; + +@@ -303,43 +298,43 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + { + if (!m_ResampBuffer || buf_size > m_ResampBufferSize) + { +- m_ResampBuffer = (uint8_t*)m_dllAvUtil.av_realloc(m_ResampBuffer, buf_size); ++ m_ResampBuffer = (uint8_t*)av_realloc(m_ResampBuffer, buf_size); + if (!m_ResampBuffer) + { + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Failed to allocate %i bytes buffer for resampling", buf_size); +- m_dllAvCodec.avcodec_free_frame(&frame); ++ avcodec_free_frame(&frame); + return 0; + } + m_ResampBufferSize = buf_size; + } + +- m_dllAvCodec.avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, m_ResampBuffer, buf_size, 0); ++ avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, m_ResampBuffer, buf_size, 0); + + /* important note: the '&input' here works because we convert from a packed + * format (ie, interleaved). If it were to be used to convert from planar + * formats (ie, non-interleaved, which is not currently supported by AE), + * we would need to adapt it or it would segfault. */ +- if (m_dllSwResample.swr_convert(m_SwrCtx, frame->extended_data, frames, &input, frames) < 0) ++ if (swr_convert(m_SwrCtx, frame->extended_data, frames, &input, frames) < 0) + { + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Resampling failed"); +- m_dllAvCodec.avcodec_free_frame(&frame); ++ avcodec_free_frame(&frame); + return 0; + } + } + else +- m_dllAvCodec.avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, ++ avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, + input, buf_size, 0); + + /* initialize the output packet */ +- m_dllAvCodec.av_init_packet(&m_Pkt); ++ av_init_packet(&m_Pkt); + m_Pkt.size = sizeof(m_Buffer) - IEC61937_DATA_OFFSET; + m_Pkt.data = m_Buffer + IEC61937_DATA_OFFSET; + + /* encode it */ +- int ret = m_dllAvCodec.avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); ++ int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); + + /* free temporary data */ +- m_dllAvCodec.avcodec_free_frame(&frame); ++ avcodec_free_frame(&frame); + + if (ret < 0 || !got_output) + { +@@ -356,7 +351,7 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + } + + /* free the packet */ +- m_dllAvCodec.av_free_packet(&m_Pkt); ++ av_free_packet(&m_Pkt); + + /* return the number of frames used */ + return m_NeededFrames; +@@ -374,7 +369,7 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz + * sadly, we have to alloc/dealloc it everytime since we have no guarantee the + * data argument will be constant over iterated calls and the frame needs to + * setup pointers inside data */ +- frame = m_dllAvCodec.avcodec_alloc_frame(); ++ frame = avcodec_alloc_frame(); + if (!frame) + return 0; + +@@ -382,19 +377,19 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz + frame->format = m_CodecCtx->sample_fmt; + frame->channel_layout = m_CodecCtx->channel_layout; + +- m_dllAvCodec.avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, ++ avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, + in, in_size, 0); + + /* initialize the output packet */ +- m_dllAvCodec.av_init_packet(&m_Pkt); ++ av_init_packet(&m_Pkt); + m_Pkt.size = out_size - IEC61937_DATA_OFFSET; + m_Pkt.data = out + IEC61937_DATA_OFFSET; + + /* encode it */ +- int ret = m_dllAvCodec.avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); ++ int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); + + /* free temporary data */ +- m_dllAvCodec.avcodec_free_frame(&frame); ++ avcodec_free_frame(&frame); + + if (ret < 0 || !got_output) + { +@@ -406,7 +401,7 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz + m_PackFunc(NULL, m_Pkt.size, out); + + /* free the packet */ +- m_dllAvCodec.av_free_packet(&m_Pkt); ++ av_free_packet(&m_Pkt); + + /* return the number of frames used */ + return m_NeededFrames; +diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h +index 4fb67c4..dad3708 100644 +--- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h ++++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h +@@ -23,11 +23,12 @@ + #include "cores/AudioEngine/Utils/AERemap.h" + #include "cores/AudioEngine/Utils/AEPackIEC61937.h" + ++extern "C" { ++#include "libswresample/swresample.h" ++} ++ + /* ffmpeg re-defines this, so undef it to squash the warning */ + #undef restrict +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +-#include "DllSwResample.h" + + class CAEEncoderFFmpeg: public IAEEncoder + { +@@ -48,11 +49,6 @@ class CAEEncoderFFmpeg: public IAEEncoder + virtual int GetData(uint8_t **data); + virtual double GetDelay(unsigned int bufferSize); + private: +- DllAvCodec m_dllAvCodec; +- DllAvFormat m_dllAvFormat; +- DllAvUtil m_dllAvUtil; +- DllSwResample m_dllSwResample; +- + std::string m_CodecName; + AVCodecID m_CodecID; + unsigned int m_BitRate; +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +index 8013d71..b23a501 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -178,10 +178,6 @@ void CActiveAE::Dispose() + m_controlPort.Purge(); + m_dataPort.Purge(); + m_sink.Dispose(); +- +- m_dllAvFormat.Unload(); +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); + } + + //----------------------------------------------------------------------------- +@@ -2041,7 +2037,7 @@ void CActiveAE::MixSounds(CSoundPacket &dstSample) + int available_samples = it->sound->GetSound(false)->nb_samples - it->samples_played; + int mix_samples = std::min(max_samples, available_samples); + int start = it->samples_played * +- m_dllAvUtil.av_get_bytes_per_sample(it->sound->GetSound(false)->config.fmt) * ++ av_get_bytes_per_sample(it->sound->GetSound(false)->config.fmt) * + it->sound->GetSound(false)->config.channels / + it->sound->GetSound(false)->planes; + +@@ -2125,13 +2121,6 @@ void CActiveAE::LoadSettings() + + bool CActiveAE::Initialize() + { +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load()) +- { +- CLog::Log(LOGERROR,"CActiveAE::Initialize - failed to load ffmpeg libraries"); +- return false; +- } +- m_dllAvFormat.av_register_all(); +- + Create(); + Message *reply; + if (m_controlPort.SendOutMessageSync(CActiveAEControlProtocol::INIT, +@@ -2387,19 +2376,19 @@ void CActiveAE::OnAppFocusChange(bool focus) + uint8_t **CActiveAE::AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize) + { + uint8_t **buffer; +- planes = m_dllAvUtil.av_sample_fmt_is_planar(config.fmt) ? config.channels : 1; ++ planes = av_sample_fmt_is_planar(config.fmt) ? config.channels : 1; + buffer = new uint8_t*[planes]; + + // align buffer to 16 in order to be compatible with sse in CAEConvert +- m_dllAvUtil.av_samples_alloc(buffer, &linesize, config.channels, ++ av_samples_alloc(buffer, &linesize, config.channels, + samples, config.fmt, 16); +- bytes_per_sample = m_dllAvUtil.av_get_bytes_per_sample(config.fmt); ++ bytes_per_sample = av_get_bytes_per_sample(config.fmt); + return buffer; + } + + void CActiveAE::FreeSoundSample(uint8_t **data) + { +- m_dllAvUtil.av_freep(data); ++ av_freep(data); + delete [] data; + } + +@@ -2443,9 +2432,9 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + } + int fileSize = sound->GetFileSize(); + +- fmt_ctx = m_dllAvFormat.avformat_alloc_context(); +- unsigned char* buffer = (unsigned char*)m_dllAvUtil.av_malloc(SOUNDBUFFER_SIZE+FF_INPUT_BUFFER_PADDING_SIZE); +- io_ctx = m_dllAvFormat.avio_alloc_context(buffer, SOUNDBUFFER_SIZE, 0, ++ fmt_ctx = avformat_alloc_context(); ++ unsigned char* buffer = (unsigned char*)av_malloc(SOUNDBUFFER_SIZE+FF_INPUT_BUFFER_PADDING_SIZE); ++ io_ctx = avio_alloc_context(buffer, SOUNDBUFFER_SIZE, 0, + sound, CActiveAESound::Read, NULL, CActiveAESound::Seek); + io_ctx->max_packet_size = sound->GetChunkSize(); + if(io_ctx->max_packet_size) +@@ -2456,22 +2445,22 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + + fmt_ctx->pb = io_ctx; + +- m_dllAvFormat.av_probe_input_buffer(io_ctx, &io_fmt, file.c_str(), NULL, 0, 0); ++ av_probe_input_buffer(io_ctx, &io_fmt, file.c_str(), NULL, 0, 0); + if (!io_fmt) + { +- m_dllAvFormat.avformat_close_input(&fmt_ctx); ++ avformat_close_input(&fmt_ctx); + delete sound; + return NULL; + } + + // find decoder +- if (m_dllAvFormat.avformat_open_input(&fmt_ctx, file.c_str(), NULL, NULL) == 0) ++ if (avformat_open_input(&fmt_ctx, file.c_str(), NULL, NULL) == 0) + { + fmt_ctx->flags |= AVFMT_FLAG_NOPARSE; +- if (m_dllAvFormat.avformat_find_stream_info(fmt_ctx, NULL) >= 0) ++ if (avformat_find_stream_info(fmt_ctx, NULL) >= 0) + { + dec_ctx = fmt_ctx->streams[0]->codec; +- dec = m_dllAvCodec.avcodec_find_decoder(dec_ctx->codec_id); ++ dec = avcodec_find_decoder(dec_ctx->codec_id); + config.sample_rate = dec_ctx->sample_rate; + config.channels = dec_ctx->channels; + config.channel_layout = dec_ctx->channel_layout; +@@ -2479,39 +2468,39 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + } + if (dec == NULL) + { +- m_dllAvFormat.avformat_close_input(&fmt_ctx); ++ avformat_close_input(&fmt_ctx); + delete sound; + return NULL; + } + +- dec_ctx = m_dllAvCodec.avcodec_alloc_context3(dec); ++ dec_ctx = avcodec_alloc_context3(dec); + dec_ctx->sample_rate = config.sample_rate; + dec_ctx->channels = config.channels; + if (!config.channel_layout) +- config.channel_layout = m_dllAvUtil.av_get_default_channel_layout(config.channels); ++ config.channel_layout = av_get_default_channel_layout(config.channels); + dec_ctx->channel_layout = config.channel_layout; + + AVPacket avpkt; + AVFrame *decoded_frame = NULL; +- decoded_frame = m_dllAvCodec.avcodec_alloc_frame(); ++ decoded_frame = avcodec_alloc_frame(); + +- if (m_dllAvCodec.avcodec_open2(dec_ctx, dec, NULL) >= 0) ++ if (avcodec_open2(dec_ctx, dec, NULL) >= 0) + { + bool init = false; + + // decode until eof +- m_dllAvCodec.av_init_packet(&avpkt); ++ av_init_packet(&avpkt); + int len; +- while (m_dllAvFormat.av_read_frame(fmt_ctx, &avpkt) >= 0) ++ while (av_read_frame(fmt_ctx, &avpkt) >= 0) + { + int got_frame = 0; +- len = m_dllAvCodec.avcodec_decode_audio4(dec_ctx, decoded_frame, &got_frame, &avpkt); ++ len = avcodec_decode_audio4(dec_ctx, decoded_frame, &got_frame, &avpkt); + if (len < 0) + { +- m_dllAvCodec.avcodec_close(dec_ctx); +- m_dllAvUtil.av_free(dec_ctx); +- m_dllAvUtil.av_free(&decoded_frame); +- m_dllAvFormat.avformat_close_input(&fmt_ctx); ++ avcodec_close(dec_ctx); ++ av_free(dec_ctx); ++ av_free(&decoded_frame); ++ avformat_close_input(&fmt_ctx); + delete sound; + return NULL; + } +@@ -2519,7 +2508,7 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + { + if (!init) + { +- int samples = fileSize / m_dllAvUtil.av_get_bytes_per_sample(dec_ctx->sample_fmt) / config.channels; ++ int samples = fileSize / av_get_bytes_per_sample(dec_ctx->sample_fmt) / config.channels; + config.fmt = dec_ctx->sample_fmt; + config.bits_per_sample = dec_ctx->bits_per_coded_sample; + sound->InitSound(true, config, samples); +@@ -2529,12 +2518,12 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + decoded_frame->nb_samples, decoded_frame->linesize[0]); + } + } +- m_dllAvCodec.avcodec_close(dec_ctx); ++ avcodec_close(dec_ctx); + } + +- m_dllAvUtil.av_free(dec_ctx); +- m_dllAvUtil.av_free(decoded_frame); +- m_dllAvFormat.avformat_close_input(&fmt_ctx); ++ av_free(dec_ctx); ++ av_free(decoded_frame); ++ avformat_close_input(&fmt_ctx); + + sound->Finish(); + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +index 8596617..700098b 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +@@ -31,9 +31,11 @@ + #include + + // ffmpeg +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" ++extern "C" { ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++} + + class IAESink; + class IAEEncoder; +@@ -347,11 +349,6 @@ class CActiveAE : public IAE, private CThread + bool m_vizInitialized; + CCriticalSection m_vizLock; + +- // ffmpeg +- DllAvFormat m_dllAvFormat; +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- + // polled via the interface + float m_aeVolume; + bool m_aeMuted; +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h +index 58205a4..f8d0ba0 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h +@@ -19,12 +19,15 @@ + * + */ + +-#include "DllAvUtil.h" +-#include "DllSwResample.h" + #include "cores/AudioEngine/Utils/AEAudioFormat.h" + #include "cores/AudioEngine/Interfaces/AE.h" + #include + ++extern "C" { ++#include "libavutil/avutil.h" ++#include "libswresample/swresample.h" ++} ++ + namespace ActiveAE + { + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +index e131f16..6478f3a 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +@@ -19,24 +19,26 @@ + */ + + #include "ActiveAEResample.h" ++#include "utils/log.h" ++ ++extern "C" { ++#include "libavutil/channel_layout.h" ++#include "libavutil/opt.h" ++#include "libswresample/swresample.h" ++} + + using namespace ActiveAE; + + CActiveAEResample::CActiveAEResample() + { + m_pContext = NULL; +- m_loaded = false; +- if (m_dllAvUtil.Load() && m_dllSwResample.Load()) +- m_loaded = true; ++ m_loaded = true; + } + + CActiveAEResample::~CActiveAEResample() + { + if (m_pContext) +- m_dllSwResample.swr_free(&m_pContext); +- +- m_dllAvUtil.Unload(); +- m_dllSwResample.Unload(); ++ swr_free(&m_pContext); + } + + bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) +@@ -56,11 +58,11 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + m_src_bits = src_bits; + + if (m_dst_chan_layout == 0) +- m_dst_chan_layout = m_dllAvUtil.av_get_default_channel_layout(m_dst_channels); ++ m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); + if (m_src_chan_layout == 0) +- m_src_chan_layout = m_dllAvUtil.av_get_default_channel_layout(m_src_channels); ++ m_src_chan_layout = av_get_default_channel_layout(m_src_channels); + +- m_pContext = m_dllSwResample.swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate, ++ m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate, + m_src_chan_layout, m_src_fmt, m_src_rate, + 0, NULL); + +@@ -72,24 +74,24 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + + if(quality == AE_QUALITY_HIGH) + { +- m_dllAvUtil.av_opt_set_double(m_pContext, "cutoff", 1.0, 0); +- m_dllAvUtil.av_opt_set_int(m_pContext,"filter_size", 256, 0); ++ av_opt_set_double(m_pContext, "cutoff", 1.0, 0); ++ av_opt_set_int(m_pContext,"filter_size", 256, 0); + } + else if(quality == AE_QUALITY_MID) + { + // 0.97 is default cutoff so use (1.0 - 0.97) / 2.0 + 0.97 +- m_dllAvUtil.av_opt_set_double(m_pContext, "cutoff", 0.985, 0); +- m_dllAvUtil.av_opt_set_int(m_pContext,"filter_size", 64, 0); ++ av_opt_set_double(m_pContext, "cutoff", 0.985, 0); ++ av_opt_set_int(m_pContext,"filter_size", 64, 0); + } + else if(quality == AE_QUALITY_LOW) + { +- m_dllAvUtil.av_opt_set_double(m_pContext, "cutoff", 0.97, 0); +- m_dllAvUtil.av_opt_set_int(m_pContext,"filter_size", 32, 0); ++ av_opt_set_double(m_pContext, "cutoff", 0.97, 0); ++ av_opt_set_int(m_pContext,"filter_size", 32, 0); + } + + if (m_dst_fmt == AV_SAMPLE_FMT_S32 || m_dst_fmt == AV_SAMPLE_FMT_S32P) + { +- m_dllAvUtil.av_opt_set_int(m_pContext, "output_sample_bits", m_dst_bits, 0); ++ av_opt_set_int(m_pContext, "output_sample_bits", m_dst_bits, 0); + } + + // tell resampler to clamp float values +@@ -98,7 +100,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) && + !remapLayout && normalize) + { +- m_dllAvUtil.av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); ++ av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); + } + + if (remapLayout) +@@ -118,10 +120,10 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + } + } + +- m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); +- m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); ++ av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); ++ av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); + +- if (m_dllSwResample.swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) ++ if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) + { + CLog::Log(LOGERROR, "CActiveAEResample::Init - setting channel matrix failed"); + return false; +@@ -133,7 +135,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + memset(m_rematrix, 0, sizeof(m_rematrix)); + for (int out=0; outRead(buf, size); + } + +-offset_t CActiveAESound::Seek(void *h, offset_t pos, int whence) ++int64_t CActiveAESound::Seek(void *h, int64_t pos, int whence) + { + CFile* pFile = static_cast(h)->m_pFile; + if(whence == AVSEEK_SIZE) +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h +index 75227ab..9324e1e 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESound.h +@@ -56,7 +56,7 @@ class CActiveAESound : public IAESound + bool IsSeekPosible() { return m_isSeekPosible; } + + static int Read(void *h, uint8_t* buf, int size); +- static offset_t Seek(void *h, offset_t pos, int whence); ++ static int64_t Seek(void *h, int64_t pos, int whence); + + protected: + std::string m_filename; +diff --git a/xbmc/cores/AudioEngine/Interfaces/AEEncoder.h b/xbmc/cores/AudioEngine/Interfaces/AEEncoder.h +index 7a9cf99..d070d36 100644 +--- a/xbmc/cores/AudioEngine/Interfaces/AEEncoder.h ++++ b/xbmc/cores/AudioEngine/Interfaces/AEEncoder.h +@@ -19,9 +19,12 @@ + * + */ + +-#include "DllAvCodec.h" + #include "cores/AudioEngine/Utils/AEAudioFormat.h" + ++extern "C" { ++#include "libavcodec/avcodec.h" ++} ++ + /** + * IAEEncoder interface for on the fly audio compression + */ +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +index f0babde..08e375b 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +@@ -19,6 +19,7 @@ + */ + + #include "AEStreamInfo.h" ++#include "utils/log.h" + + #define IEC61937_PREAMBLE1 0xF872 + #define IEC61937_PREAMBLE2 0x4E1F +@@ -85,13 +86,11 @@ CAEStreamInfo::CAEStreamInfo() : + m_dataIsLE (false), + m_packFunc (NULL) + { +- m_dllAvUtil.Load(); +- m_dllAvUtil.av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD)); ++ av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD)); + } + + CAEStreamInfo::~CAEStreamInfo() + { +- m_dllAvUtil.Unload(); + } + + int CAEStreamInfo::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/* = NULL */, unsigned int *bufferSize/* = 0 */) +@@ -360,7 +359,7 @@ unsigned int CAEStreamInfo::SyncAC3(uint8_t *data, unsigned int size) + crc_size = (framesize >> 1) + (framesize >> 3) - 1; + + if (crc_size <= size - skip) +- if (m_dllAvUtil.av_crc(m_dllAvUtil.av_crc_get_table(AV_CRC_16_ANSI), 0, &data[2], crc_size * 2)) ++ if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &data[2], crc_size * 2)) + continue; + + /* if we get here, we can sync */ +@@ -668,7 +667,7 @@ unsigned int CAEStreamInfo::SyncTrueHD(uint8_t *data, unsigned int size) + continue; + + /* verify the crc of the audio unit */ +- uint16_t crc = m_dllAvUtil.av_crc(m_crcTrueHD, 0, data + 4, 24); ++ uint16_t crc = av_crc(m_crcTrueHD, 0, data + 4, 24); + crc ^= (data[29] << 8) | data[28]; + if (((data[31] << 8) | data[30]) != crc) + continue; +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h +index 4d7bcdd..8fadab0 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h +@@ -26,8 +26,12 @@ + + /* ffmpeg re-defines this, so undef it to squash the warning */ + #undef restrict +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++#include "libavutil/crc.h" ++} + + class CAEStreamInfo + { +@@ -67,8 +71,6 @@ class CAEStreamInfo + CAEPackIEC61937::PackFunc GetPackFunc () { return m_packFunc ; } + unsigned int GetBufferSize () { return m_bufferSize ; } + private: +- DllAvUtil m_dllAvUtil; +- + uint8_t m_buffer[MAX_IEC61937_PACKET]; + unsigned int m_bufferSize; + unsigned int m_skipBytes; +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +index 3b9851d..73eb193 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +@@ -40,7 +40,6 @@ + #include "guilib/Texture.h" + #include "guilib/LocalizeStrings.h" + #include "threads/SingleLock.h" +-#include "DllSwScale.h" + #include "utils/log.h" + #include "utils/GLUtils.h" + #include "utils/StringUtils.h" +@@ -48,6 +47,11 @@ + #include "RenderFormats.h" + #include "cores/IPlayer.h" + #include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h" ++#include "cores/FFmpeg.h" ++ ++extern "C" { ++#include "libswscale/swscale.h" ++} + + #ifdef HAVE_LIBVDPAU + #include "cores/dvdplayer/DVDCodecs/Video/VDPAU.h" +@@ -191,8 +195,6 @@ CLinuxRendererGL::CLinuxRendererGL() + m_nonLinStretch = false; + m_nonLinStretchGui = false; + m_pixelRatio = 0.0f; +- +- m_dllSwScale = new DllSwScale; + } + + CLinuxRendererGL::~CLinuxRendererGL() +@@ -213,7 +215,7 @@ CLinuxRendererGL::~CLinuxRendererGL() + + if (m_context) + { +- m_dllSwScale->sws_freeContext(m_context); ++ sws_freeContext(m_context); + m_context = NULL; + } + +@@ -223,8 +225,6 @@ CLinuxRendererGL::~CLinuxRendererGL() + delete m_pYUVShader; + m_pYUVShader = NULL; + } +- +- delete m_dllSwScale; + } + + bool CLinuxRendererGL::ValidateRenderer() +@@ -779,9 +779,6 @@ unsigned int CLinuxRendererGL::PreInit() + // setup the background colour + m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff; + +- if (!m_dllSwScale->Load()) +- CLog::Log(LOGERROR,"CLinuxRendererGL::PreInit - failed to load rescale libraries!"); +- + return true; + } + +@@ -1131,7 +1128,7 @@ void CLinuxRendererGL::UnInit() + + if (m_context) + { +- m_dllSwScale->sws_freeContext(m_context); ++ sws_freeContext(m_context); + m_context = NULL; + } + +@@ -3159,14 +3156,14 @@ void CLinuxRendererGL::ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsign + m_rgbBuffer = (BYTE*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB) + PBO_OFFSET; + } + +- m_context = m_dllSwScale->sws_getCachedContext(m_context, +- im->width, im->height, srcFormat, +- im->width, im->height, PIX_FMT_BGRA, ++ m_context = sws_getCachedContext(m_context, ++ im->width, im->height, (AVPixelFormat)srcFormat, ++ im->width, im->height, (AVPixelFormat)PIX_FMT_BGRA, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); + + uint8_t *dst[] = { m_rgbBuffer, 0, 0, 0 }; + int dstStride[] = { (int)m_sourceWidth * 4, 0, 0, 0 }; +- m_dllSwScale->sws_scale(m_context, src, srcStride, 0, im->height, dst, dstStride); ++ sws_scale(m_context, src, srcStride, 0, im->height, dst, dstStride); + + if (m_rgbPbo) + { +@@ -3239,9 +3236,9 @@ void CLinuxRendererGL::ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, un + m_rgbBuffer = (BYTE*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB) + PBO_OFFSET; + } + +- m_context = m_dllSwScale->sws_getCachedContext(m_context, +- im->width, im->height >> 1, srcFormat, +- im->width, im->height >> 1, PIX_FMT_BGRA, ++ m_context = sws_getCachedContext(m_context, ++ im->width, im->height >> 1, (AVPixelFormat)srcFormat, ++ im->width, im->height >> 1, (AVPixelFormat)PIX_FMT_BGRA, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); + uint8_t *dstTop[] = { m_rgbBuffer, 0, 0, 0 }; + uint8_t *dstBot[] = { m_rgbBuffer + m_sourceWidth * m_sourceHeight * 2, 0, 0, 0 }; +@@ -3249,8 +3246,8 @@ void CLinuxRendererGL::ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, un + + //convert each YUV field to an RGB field, the top field is placed at the top of the rgb buffer + //the bottom field is placed at the bottom of the rgb buffer +- m_dllSwScale->sws_scale(m_context, srcTop, srcStrideTop, 0, im->height >> 1, dstTop, dstStride); +- m_dllSwScale->sws_scale(m_context, srcBot, srcStrideBot, 0, im->height >> 1, dstBot, dstStride); ++ sws_scale(m_context, srcTop, srcStrideTop, 0, im->height >> 1, dstTop, dstStride); ++ sws_scale(m_context, srcBot, srcStrideBot, 0, im->height >> 1, dstBot, dstStride); + + if (m_rgbPbo) + { +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h +index 63ea287..304017f 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h +@@ -112,8 +112,6 @@ extern YUVCOEF yuv_coef_bt709; + extern YUVCOEF yuv_coef_ebu; + extern YUVCOEF yuv_coef_smtp240m; + +-class DllSwScale; +- + class CLinuxRendererGL : public CBaseRenderer + { + public: +@@ -312,7 +310,6 @@ class CLinuxRendererGL : public CBaseRenderer + float m_clearColour; + + // software scale library (fallback if required gl version is not available) +- DllSwScale *m_dllSwScale; + BYTE *m_rgbBuffer; // if software scale is used, this will hold the result image + unsigned int m_rgbBufferSize; + GLuint m_rgbPbo; +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +index 30c0601..72eb725 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +@@ -34,6 +34,7 @@ + #include "utils/fastmemcpy.h" + #include "utils/MathUtils.h" + #include "utils/GLUtils.h" ++#include "utils/log.h" + #include "settings/AdvancedSettings.h" + #include "settings/DisplaySettings.h" + #include "settings/MediaSettings.h" +@@ -43,7 +44,6 @@ + #include "VideoShaders/VideoFilterShader.h" + #include "windowing/WindowingFactory.h" + #include "guilib/Texture.h" +-#include "lib/DllSwScale.h" + #include "../dvdplayer/DVDCodecs/Video/OpenMaxVideo.h" + #include "threads/SingleLock.h" + #include "RenderCapture.h" +@@ -51,6 +51,10 @@ + #include "xbmc/Application.h" + #include "cores/IPlayer.h" + ++extern "C" { ++#include "libswscale/swscale.h" ++} ++ + #if defined(__ARM_NEON__) + #include "yuv2rgb.neon.h" + #include "utils/CPUInfo.h" +@@ -132,7 +136,6 @@ CLinuxRendererGLES::CLinuxRendererGLES() + m_rgbBuffer = NULL; + m_rgbBufferSize = 0; + +- m_dllSwScale = new DllSwScale; + m_sw_context = NULL; + m_NumYV12Buffers = 0; + m_iLastRenderBuffer = 0; +@@ -167,8 +170,6 @@ CLinuxRendererGLES::~CLinuxRendererGLES() + delete m_pYUVShader; + m_pYUVShader = NULL; + } +- +- delete m_dllSwScale; + } + + bool CLinuxRendererGLES::ValidateRenderTarget() +@@ -607,9 +608,6 @@ unsigned int CLinuxRendererGLES::PreInit() + // setup the background colour + m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff; + +- if (!m_dllSwScale->Load()) +- CLog::Log(LOGERROR,"CLinuxRendererGL::PreInit - failed to load rescale libraries!"); +- + return true; + } + +@@ -837,9 +835,9 @@ void CLinuxRendererGLES::UnInit() + for (int i = 0; i < NUM_BUFFERS; ++i) + (this->*m_textureDelete)(i); + +- if (m_dllSwScale && m_sw_context) ++ if (m_sw_context) + { +- m_dllSwScale->sws_freeContext(m_sw_context); ++ sws_freeContext(m_sw_context); + m_sw_context = NULL; + } + +@@ -1684,7 +1682,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source) + else + #endif + { +- m_sw_context = m_dllSwScale->sws_getCachedContext(m_sw_context, ++ m_sw_context = sws_getCachedContext(m_sw_context, + im->width, im->height, PIX_FMT_YUV420P, + im->width, im->height, PIX_FMT_RGBA, + SWS_FAST_BILINEAR, NULL, NULL, NULL); +@@ -1693,7 +1691,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source) + int srcStride[] = { im->stride[0], im->stride[1], im->stride[2], 0 }; + uint8_t *dst[] = { m_rgbBuffer, 0, 0, 0 }; + int dstStride[] = { m_sourceWidth*4, 0, 0, 0 }; +- m_dllSwScale->sws_scale(m_sw_context, src, srcStride, 0, im->height, dst, dstStride); ++ sws_scale(m_sw_context, src, srcStride, 0, im->height, dst, dstStride); + } + } + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +index 45e9c20..642cded 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +@@ -115,9 +115,6 @@ extern YUVCOEF yuv_coef_bt709; + extern YUVCOEF yuv_coef_ebu; + extern YUVCOEF yuv_coef_smtp240m; + +-class DllSwScale; +-struct SwsContext; +- + class CEvent; + + class CLinuxRendererGLES : public CBaseRenderer +@@ -314,7 +311,6 @@ class CLinuxRendererGLES : public CBaseRenderer + float m_clearColour; + + // software scale libraries (fallback if required gl version is not available) +- DllSwScale *m_dllSwScale; + struct SwsContext *m_sw_context; + BYTE *m_rgbBuffer; // if software scale is used, this will hold the result image + unsigned int m_rgbBufferSize; +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp +index 48794a7..7e82dd4 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp +@@ -20,7 +20,7 @@ + + #ifdef HAS_DX + +-#include "DllSwScale.h" ++#include "libswscale/swscale.h" + #include "Util.h" + #include "WinRenderer.h" + #include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h" +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h +index 7486464..63eb3cd 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.h ++++ b/xbmc/cores/VideoRenderers/WinRenderer.h +@@ -208,9 +208,6 @@ class CWinRenderer : public CBaseRenderer + std::vector m_formats; + + // software scale libraries (fallback if required pixel shaders version is not available) +- DllAvUtil *m_dllAvUtil; +- DllAvCodec *m_dllAvCodec; +- DllSwScale *m_dllSwScale; + struct SwsContext *m_sw_scale_ctx; + + // Software rendering +diff --git a/xbmc/cores/dvdplayer/DVDAudio.h b/xbmc/cores/dvdplayer/DVDAudio.h +index 4328fc3..4e22383 100644 +--- a/xbmc/cores/dvdplayer/DVDAudio.h ++++ b/xbmc/cores/dvdplayer/DVDAudio.h +@@ -30,7 +30,9 @@ + #include "cores/AudioEngine/Utils/AEChannelInfo.h" + class IAEStream; + +-#include "DllAvCodec.h" ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + + typedef struct stDVDAudioFrame DVDAudioFrame; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodec.h +index 08839ee..baadb79 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodec.h +@@ -30,7 +30,10 @@ + #include "config.h" + #endif + #include +-#include "DllAvCodec.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + + struct AVStream; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +index af897fe..aeb3995 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +@@ -59,19 +59,14 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + AVCodec* pCodec; + m_bOpenedCodec = false; + +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwResample.Load()) +- return false; +- +- m_dllAvCodec.avcodec_register_all(); +- +- pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); ++ pCodec = avcodec_find_decoder(hints.codec); + if (!pCodec) + { + CLog::Log(LOGDEBUG,"CDVDAudioCodecFFmpeg::Open() Unable to find codec %d", hints.codec); + return false; + } + +- m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec); ++ m_pCodecContext = avcodec_alloc_context3(pCodec); + m_pCodecContext->debug_mv = 0; + m_pCodecContext->debug = 0; + m_pCodecContext->workaround_bugs = 1; +@@ -91,7 +86,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + + if( hints.extradata && hints.extrasize > 0 ) + { +- m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); ++ m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); + if(m_pCodecContext->extradata) + { + m_pCodecContext->extradata_size = hints.extrasize; +@@ -99,14 +94,14 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + } + } + +- if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) ++ if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) + { + CLog::Log(LOGDEBUG,"CDVDAudioCodecFFmpeg::Open() Unable to open codec"); + Dispose(); + return false; + } + +- m_pFrame1 = m_dllAvCodec.avcodec_alloc_frame(); ++ m_pFrame1 = avcodec_alloc_frame(); + m_bOpenedCodec = true; + m_iSampleFormat = AV_SAMPLE_FMT_NONE; + +@@ -115,27 +110,23 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + + void CDVDAudioCodecFFmpeg::Dispose() + { +- if (m_pFrame1) m_dllAvUtil.av_free(m_pFrame1); ++ if (m_pFrame1) av_free(m_pFrame1); + m_pFrame1 = NULL; + + if (m_pConvert) +- m_dllSwResample.swr_free(&m_pConvert); ++ swr_free(&m_pConvert); + + if (m_pBuffer2) +- m_dllAvUtil.av_freep(&m_pBuffer2); ++ av_freep(&m_pBuffer2); + + if (m_pCodecContext) + { +- if (m_bOpenedCodec) m_dllAvCodec.avcodec_close(m_pCodecContext); ++ if (m_bOpenedCodec) avcodec_close(m_pCodecContext); + m_bOpenedCodec = false; +- m_dllAvUtil.av_free(m_pCodecContext); ++ av_free(m_pCodecContext); + m_pCodecContext = NULL; + } + +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); +- m_dllSwResample.Unload(); +- + m_iBufferSize1 = 0; + m_iBufferSize2 = 0; + m_iBufferTotalSize2 = 0; +@@ -150,10 +141,10 @@ int CDVDAudioCodecFFmpeg::Decode(uint8_t* pData, int iSize) + m_iBufferSize2 = 0; + + AVPacket avpkt; +- m_dllAvCodec.av_init_packet(&avpkt); ++ av_init_packet(&avpkt); + avpkt.data = pData; + avpkt.size = iSize; +- iBytesUsed = m_dllAvCodec.avcodec_decode_audio4( m_pCodecContext ++ iBytesUsed = avcodec_decode_audio4( m_pCodecContext + , m_pFrame1 + , &got_frame + , &avpkt); +@@ -162,7 +153,7 @@ int CDVDAudioCodecFFmpeg::Decode(uint8_t* pData, int iSize) + m_iBufferSize1 = 0; + return iBytesUsed; + } +- m_iBufferSize1 = m_pFrame1->nb_samples * m_pCodecContext->channels * m_dllAvUtil.av_get_bytes_per_sample(m_pCodecContext->sample_fmt); ++ m_iBufferSize1 = m_pFrame1->nb_samples * m_pCodecContext->channels * av_get_bytes_per_sample(m_pCodecContext->sample_fmt); + + /* some codecs will attempt to consume more data than what we gave */ + if (iBytesUsed > iSize) +@@ -202,17 +193,17 @@ void CDVDAudioCodecFFmpeg::ConvertToFloat() + if(m_pCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT && m_iBufferSize1 > 0) + { + if(m_pConvert && (m_pCodecContext->sample_fmt != m_iSampleFormat || m_channels != m_pCodecContext->channels)) +- m_dllSwResample.swr_free(&m_pConvert); ++ swr_free(&m_pConvert); + + if(!m_pConvert) + { + m_iSampleFormat = m_pCodecContext->sample_fmt; +- m_pConvert = m_dllSwResample.swr_alloc_set_opts(NULL, +- m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels), AV_SAMPLE_FMT_FLT, m_pCodecContext->sample_rate, +- m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels), m_pCodecContext->sample_fmt, m_pCodecContext->sample_rate, ++ m_pConvert = swr_alloc_set_opts(NULL, ++ av_get_default_channel_layout(m_pCodecContext->channels), AV_SAMPLE_FMT_FLT, m_pCodecContext->sample_rate, ++ av_get_default_channel_layout(m_pCodecContext->channels), m_pCodecContext->sample_fmt, m_pCodecContext->sample_rate, + 0, NULL); + +- if(!m_pConvert || m_dllSwResample.swr_init(m_pConvert) < 0) ++ if(!m_pConvert || swr_init(m_pConvert) < 0) + { + CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Decode - Unable to convert %d to AV_SAMPLE_FMT_FLT", m_pCodecContext->sample_fmt); + m_iBufferSize1 = 0; +@@ -221,10 +212,10 @@ void CDVDAudioCodecFFmpeg::ConvertToFloat() + } + } + +- int needed_buf_size = m_dllAvUtil.av_samples_get_buffer_size(NULL, m_pCodecContext->channels, m_pFrame1->nb_samples, AV_SAMPLE_FMT_FLT, 0); ++ int needed_buf_size = av_samples_get_buffer_size(NULL, m_pCodecContext->channels, m_pFrame1->nb_samples, AV_SAMPLE_FMT_FLT, 0); + if(m_iBufferTotalSize2 < needed_buf_size) + { +- m_pBuffer2 = (uint8_t*)m_dllAvUtil.av_realloc(m_pBuffer2, needed_buf_size); ++ m_pBuffer2 = (uint8_t*)av_realloc(m_pBuffer2, needed_buf_size); + if(!m_pBuffer2) + { + CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Decode - Unable to allocate a %i bytes buffer for resampling", needed_buf_size); +@@ -237,7 +228,7 @@ void CDVDAudioCodecFFmpeg::ConvertToFloat() + } + + int outsamples; +- outsamples = m_dllSwResample.swr_convert(m_pConvert, &m_pBuffer2, m_iBufferTotalSize2, (const uint8_t**)m_pFrame1->extended_data, m_pFrame1->nb_samples); ++ outsamples = swr_convert(m_pConvert, &m_pBuffer2, m_iBufferTotalSize2, (const uint8_t**)m_pFrame1->extended_data, m_pFrame1->nb_samples); + + if(outsamples < 0) + { +@@ -253,7 +244,7 @@ void CDVDAudioCodecFFmpeg::ConvertToFloat() + } + + m_iBufferSize1 = 0; +- m_iBufferSize2 = m_pFrame1->nb_samples * m_pCodecContext->channels * m_dllAvUtil.av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT); ++ m_iBufferSize2 = m_pFrame1->nb_samples * m_pCodecContext->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT); + } + } + +@@ -276,7 +267,7 @@ int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst) + + void CDVDAudioCodecFFmpeg::Reset() + { +- if (m_pCodecContext) m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); ++ if (m_pCodecContext) avcodec_flush_buffers(m_pCodecContext); + m_iBufferSize1 = 0; + m_iBufferSize2 = 0; + m_iBuffered = 0; +@@ -348,7 +339,7 @@ void CDVDAudioCodecFFmpeg::BuildChannelMap() + else + { + CLog::Log(LOGINFO, "CDVDAudioCodecFFmpeg::GetChannelMap - FFmpeg reported %d channels, but the layout contains %d ignoring", m_pCodecContext->channels, bits); +- layout = m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels); ++ layout = av_get_default_channel_layout(m_pCodecContext->channels); + } + + m_channelLayout.Reset(); +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h +index 1646e00..7d78516 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h +@@ -21,10 +21,13 @@ + */ + + #include "DVDAudioCodec.h" +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +-#include "DllAvUtil.h" +-#include "DllSwResample.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++#include "libavutil/avutil.h" ++#include "libswresample/swresample.h" ++} + + class CDVDAudioCodecFFmpeg : public CDVDAudioCodec + { +@@ -63,10 +66,6 @@ class CDVDAudioCodecFFmpeg : public CDVDAudioCodec + int m_channels; + uint64_t m_layout; + +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- DllSwResample m_dllSwResample; +- + void BuildChannelMap(); + void ConvertToFloat(); + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +index 5443cb3..46841a1 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +@@ -23,7 +23,11 @@ + #include "cores/VideoRenderers/RenderManager.h" + #include "utils/log.h" + #include "utils/fastmemcpy.h" +-#include "DllSwScale.h" ++#include "cores/FFmpeg.h" ++ ++extern "C" { ++#include "libswscale/swscale.h" ++} + + // allocate a new picture (PIX_FMT_YUV420P) + DVDVideoPicture* CDVDCodecUtils::AllocatePicture(int iWidth, int iHeight) +@@ -241,12 +245,6 @@ DVDVideoPicture* CDVDCodecUtils::ConvertToYUV422PackedPicture(DVDVideoPicture *p + + //if this is going to be used for anything else than testing the renderer + //the library should not be loaded on every function call +- DllSwScale dllSwScale; +- if (!dllSwScale.Load()) +- { +- CLog::Log(LOGERROR,"CDVDCodecUtils::ConvertToYUY2Picture - failed to load rescale libraries!"); +- } +- else + { + // Perform the scaling. + uint8_t* src[] = { pSrc->data[0], pSrc->data[1], pSrc->data[2], NULL }; +@@ -260,11 +258,11 @@ DVDVideoPicture* CDVDCodecUtils::ConvertToYUV422PackedPicture(DVDVideoPicture *p + else + dstformat = PIX_FMT_YUYV422; + +- struct SwsContext *ctx = dllSwScale.sws_getContext(pSrc->iWidth, pSrc->iHeight, PIX_FMT_YUV420P, +- pPicture->iWidth, pPicture->iHeight, dstformat, ++ struct SwsContext *ctx = sws_getContext(pSrc->iWidth, pSrc->iHeight, PIX_FMT_YUV420P, ++ pPicture->iWidth, pPicture->iHeight, (AVPixelFormat)dstformat, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); +- dllSwScale.sws_scale(ctx, src, srcStride, 0, pSrc->iHeight, dst, dstStride); +- dllSwScale.sws_freeContext(ctx); ++ sws_scale(ctx, src, srcStride, 0, pSrc->iHeight, dst, dstStride); ++ sws_freeContext(ctx); + } + } + else +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +index 805ee22..72b9bca 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +@@ -45,18 +45,14 @@ CDVDOverlayCodecFFmpeg::~CDVDOverlayCodecFFmpeg() + + bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) + { +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load()) return false; +- +- m_dllAvCodec.avcodec_register_all(); +- +- AVCodec* pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); ++ AVCodec* pCodec = avcodec_find_decoder(hints.codec); + if (!pCodec) + { + CLog::Log(LOGDEBUG,"%s - Unable to find codec %d", __FUNCTION__, hints.codec); + return false; + } + +- m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec); ++ m_pCodecContext = avcodec_alloc_context3(pCodec); + m_pCodecContext->debug_mv = 0; + m_pCodecContext->debug = 0; + m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT; +@@ -69,7 +65,7 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio + if( hints.extradata && hints.extrasize > 0 ) + { + m_pCodecContext->extradata_size = hints.extrasize; +- m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); ++ m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); + + // start parsing of extra data - create a copy to be safe and make it zero-terminating to avoid access violations! +@@ -110,7 +106,7 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio + delete[] parse_extra; + } + +- if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) ++ if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) + { + CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec"); + return false; +@@ -123,14 +119,11 @@ void CDVDOverlayCodecFFmpeg::Dispose() + { + if (m_pCodecContext) + { +- if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext); +- m_dllAvUtil.av_free(m_pCodecContext); ++ if (m_pCodecContext->codec) avcodec_close(m_pCodecContext); ++ av_free(m_pCodecContext); + m_pCodecContext = NULL; + } + FreeSubtitle(m_Subtitle); +- +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); + } + + void CDVDOverlayCodecFFmpeg::FreeSubtitle(AVSubtitle& sub) +@@ -139,13 +132,13 @@ void CDVDOverlayCodecFFmpeg::FreeSubtitle(AVSubtitle& sub) + { + if(sub.rects[i]) + { +- m_dllAvUtil.av_free(sub.rects[i]->pict.data[0]); +- m_dllAvUtil.av_free(sub.rects[i]->pict.data[1]); +- m_dllAvUtil.av_freep(&sub.rects[i]); ++ av_free(sub.rects[i]->pict.data[0]); ++ av_free(sub.rects[i]->pict.data[1]); ++ av_freep(&sub.rects[i]); + } + } + if(sub.rects) +- m_dllAvUtil.av_freep(&sub.rects); ++ av_freep(&sub.rects); + sub.num_rects = 0; + sub.start_display_time = 0; + sub.end_display_time = 0; +@@ -161,13 +154,13 @@ int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket) + FreeSubtitle(m_Subtitle); + + AVPacket avpkt; +- m_dllAvCodec.av_init_packet(&avpkt); ++ av_init_packet(&avpkt); + avpkt.data = pPacket->pData; + avpkt.size = pPacket->iSize; + avpkt.pts = pPacket->pts == DVD_NOPTS_VALUE ? AV_NOPTS_VALUE : (int64_t)pPacket->pts; + avpkt.dts = pPacket->dts == DVD_NOPTS_VALUE ? AV_NOPTS_VALUE : (int64_t)pPacket->dts; + +- len = m_dllAvCodec.avcodec_decode_subtitle2(m_pCodecContext, &m_Subtitle, &gotsub, &avpkt); ++ len = avcodec_decode_subtitle2(m_pCodecContext, &m_Subtitle, &gotsub, &avpkt); + + if (len < 0) + { +@@ -216,7 +209,7 @@ void CDVDOverlayCodecFFmpeg::Flush() + FreeSubtitle(m_Subtitle); + m_SubtitleIndex = -1; + +- m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); ++ avcodec_flush_buffers(m_pCodecContext); + } + + CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() +@@ -309,9 +302,9 @@ CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() + for(int i=0;ipalette[i] = Endian_SwapLE32(((uint32_t *)rect.pict.data[1])[i]); + +- m_dllAvUtil.av_free(rect.pict.data[0]); +- m_dllAvUtil.av_free(rect.pict.data[1]); +- m_dllAvUtil.av_freep(&m_Subtitle.rects[m_SubtitleIndex]); ++ av_free(rect.pict.data[0]); ++ av_free(rect.pict.data[1]); ++ av_freep(&m_Subtitle.rects[m_SubtitleIndex]); + m_SubtitleIndex++; + + return overlay; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h +index 3306d94..f84e9a4 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h +@@ -21,8 +21,11 @@ + */ + + #include "DVDOverlayCodec.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++} + + class CDVDOverlaySpu; + class CDVDOverlayText; +@@ -50,8 +53,4 @@ class CDVDOverlayCodecFFmpeg : public CDVDOverlayCodec + + int m_width; + int m_height; +- +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h +index e4ee3fa..4e3b223 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h +@@ -21,7 +21,7 @@ + */ + + #include "DVDOverlayCodec.h" +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + + class CDVDOverlayText; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp +index 7585636..b6e1ed3 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp +@@ -36,9 +36,12 @@ + #include "threads/Thread.h" + #include "utils/log.h" + #include "utils/fastmemcpy.h" +-#include "DllSwScale.h" ++extern "C" { ++#include "libswscale/swscale.h" ++} + #include "utils/TimeUtils.h" + #include "windowing/WindowingFactory.h" ++#include "cores/FFmpeg.h" + + namespace BCM + { +@@ -248,7 +251,6 @@ class CMPCOutputThread : public CThread + int m_aspectratio_x; + int m_aspectratio_y; + CEvent m_ready_event; +- DllSwScale *m_dllSwScale; + struct SwsContext *m_sw_scale_ctx; + }; + +@@ -348,9 +350,6 @@ CMPCOutputThread::CMPCOutputThread(void *device, DllLibCrystalHD *dll, bool has_ + m_aspectratio_y(1) + { + m_sw_scale_ctx = NULL; +- m_dllSwScale = new DllSwScale; +- m_dllSwScale->Load(); +- + + if (g_Windowing.GetRenderQuirks() & RENDER_QUIRKS_YV12_PREFERED) + m_output_YV12 = true; +@@ -366,8 +365,7 @@ CMPCOutputThread::~CMPCOutputThread() + delete m_FreeList.Pop(); + + if (m_sw_scale_ctx) +- m_dllSwScale->sws_freeContext(m_sw_scale_ctx); +- delete m_dllSwScale; ++ sws_freeContext(m_sw_scale_ctx); + } + + unsigned int CMPCOutputThread::GetReadyCount(void) +@@ -949,11 +947,11 @@ bool CMPCOutputThread::GetDecoderOutput(void) + uint8_t* dst[] = { pBuffer->m_y_buffer_ptr, pBuffer->m_u_buffer_ptr, pBuffer->m_v_buffer_ptr, NULL }; + int dstStride[] = { pBuffer->m_width, pBuffer->m_width/2, pBuffer->m_width/2, 0 }; + +- m_sw_scale_ctx = m_dllSwScale->sws_getCachedContext(m_sw_scale_ctx, ++ m_sw_scale_ctx = sws_getCachedContext(m_sw_scale_ctx, + pBuffer->m_width, pBuffer->m_height, PIX_FMT_YUYV422, + pBuffer->m_width, pBuffer->m_height, PIX_FMT_YUV420P, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); +- m_dllSwScale->sws_scale(m_sw_scale_ctx, src, srcStride, 0, pBuffer->m_height, dst, dstStride); ++ sws_scale(m_sw_scale_ctx, src, srcStride, 0, pBuffer->m_height, dst, dstStride); + } + break; + default: +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +index f6751f4..d82e4bb 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -21,13 +21,15 @@ + */ + + #include "system.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" + + #include + #include + #include "cores/VideoRenderers/RenderFormats.h" + ++extern "C" { ++#include "libavcodec/avcodec.h" ++} ++ + struct DVDCodecAvailableType + { + AVCodecID codec; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCrystalHD.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCrystalHD.cpp +index 7f6e1ca..373ae2c 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCrystalHD.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCrystalHD.cpp +@@ -22,7 +22,9 @@ + #include "config.h" + #elif defined(TARGET_WINDOWS) + #include "system.h" +-#include "DllAvCodec.h" ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + #endif + + #if defined(HAVE_LIBCRYSTALHD) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 9b6a34d..7348d5f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -63,6 +63,13 @@ + #endif + #include "utils/StringUtils.h" + ++extern "C" { ++#include "libavutil/opt.h" ++#include "libavfilter/avfilter.h" ++#include "libavfilter/buffersink.h" ++#include "libavfilter/buffersrc.h" ++} ++ + using namespace boost; + + enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx +@@ -72,7 +79,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + + // if frame threading is enabled hw accel is not allowed + if((EDECODEMETHOD) CSettings::Get().GetInt("videoplayer.decodingmethod") != VS_DECODEMETHOD_HARDWARE || !ctx->IsHardwareAllowed()) +- return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt); ++ return avcodec_default_get_format(avctx, fmt); + + const PixelFormat * cur = fmt; + while(*cur != PIX_FMT_NONE) +@@ -134,7 +141,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + #endif + cur++; + } +- return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt); ++ return avcodec_default_get_format(avctx, fmt); + } + + CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() +@@ -144,11 +151,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() + m_pFilterGraph = NULL; + m_pFilterIn = NULL; + m_pFilterOut = NULL; +-#if defined(LIBAVFILTER_AVFRAME_BASED) + m_pFilterFrame = NULL; +-#else +- m_pBufferRef = NULL; +-#endif + + m_iPictureWidth = 0; + m_iPictureHeight = 0; +@@ -175,16 +178,6 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + { + AVCodec* pCodec; + +- if(!m_dllAvUtil.Load() +- || !m_dllAvCodec.Load() +- || !m_dllSwScale.Load() +- || !m_dllPostProc.Load() +- || !m_dllAvFilter.Load() +- ) return false; +- +- m_dllAvCodec.avcodec_register_all(); +- m_dllAvFilter.avfilter_register_all(); +- + m_bSoftware = hints.software; + m_iOrientation = hints.orientation; + +@@ -219,7 +212,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + } + + if(pCodec == NULL) +- pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); ++ pCodec = avcodec_find_decoder(hints.codec); + + if(pCodec == NULL) + { +@@ -230,7 +223,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Using codec: %s",pCodec->long_name ? pCodec->long_name : pCodec->name); + + if(m_pCodecContext == NULL) +- m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec); ++ m_pCodecContext = avcodec_alloc_context3(pCodec); + + m_pCodecContext->opaque = (void*)this; + m_pCodecContext->debug_mv = 0; +@@ -276,7 +269,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + if( hints.extradata && hints.extrasize > 0 ) + { + m_pCodecContext->extradata_size = hints.extrasize; +- m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); ++ m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); + } + +@@ -293,7 +286,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + if (it->m_name == "surfaces") + m_uSurfacesCount = std::atoi(it->m_value.c_str()); + else +- m_dllAvUtil.av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0); ++ av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0); + } + + int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount()); +@@ -302,19 +295,17 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + || pCodec->id == AV_CODEC_ID_MPEG4 )) + m_pCodecContext->thread_count = num_threads; + +- if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) ++ if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) + { + CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec"); + return false; + } + +- m_pFrame = m_dllAvCodec.avcodec_alloc_frame(); ++ m_pFrame = avcodec_alloc_frame(); + if (!m_pFrame) return false; + +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- m_pFilterFrame = m_dllAvUtil.av_frame_alloc(); ++ m_pFilterFrame = av_frame_alloc(); + if (!m_pFilterFrame) return false; +-#endif + + UpdateName(); + return true; +@@ -322,33 +313,26 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + + void CDVDVideoCodecFFmpeg::Dispose() + { +- if (m_pFrame) m_dllAvUtil.av_free(m_pFrame); ++ if (m_pFrame) av_free(m_pFrame); + m_pFrame = NULL; + +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- m_dllAvUtil.av_frame_free(&m_pFilterFrame); +-#endif ++ av_frame_free(&m_pFilterFrame); + + if (m_pCodecContext) + { +- if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext); ++ if (m_pCodecContext->codec) avcodec_close(m_pCodecContext); + if (m_pCodecContext->extradata) + { +- m_dllAvUtil.av_free(m_pCodecContext->extradata); ++ av_free(m_pCodecContext->extradata); + m_pCodecContext->extradata = NULL; + m_pCodecContext->extradata_size = 0; + } +- m_dllAvUtil.av_free(m_pCodecContext); ++ av_free(m_pCodecContext); + m_pCodecContext = NULL; + } + SAFE_RELEASE(m_pHardware); + + FilterClose(); +- +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); +- m_dllAvFilter.Unload(); +- m_dllPostProc.Unload(); + } + + void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop) +@@ -476,13 +460,13 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + m_pCodecContext->reordered_opaque = pts_dtoi(pts); + + AVPacket avpkt; +- m_dllAvCodec.av_init_packet(&avpkt); ++ av_init_packet(&avpkt); + avpkt.data = pData; + avpkt.size = iSize; + /* We lie, but this flag is only used by pngdec.c. + * Setting it correctly would allow CorePNG decoding. */ + avpkt.flags = AV_PKT_FLAG_KEY; +- len = m_dllAvCodec.avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt); ++ len = avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt); + + if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2) + m_iLastKeyframe = m_pCodecContext->has_b_frames + 2; +@@ -557,7 +541,7 @@ void CDVDVideoCodecFFmpeg::Reset() + { + m_started = false; + m_iLastKeyframe = m_pCodecContext->has_b_frames; +- m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); ++ avcodec_flush_buffers(m_pCodecContext); + + if (m_pHardware) + m_pHardware->Reset(); +@@ -571,14 +555,6 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + pDvdVideoPicture->iWidth = m_pFrame->width; + pDvdVideoPicture->iHeight = m_pFrame->height; + +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- if(m_pBufferRef) +- { +- pDvdVideoPicture->iWidth = m_pBufferRef->video->w; +- pDvdVideoPicture->iHeight = m_pBufferRef->video->h; +- } +-#endif +- + /* crop of 10 pixels if demuxer asked it */ + if(m_pCodecContext->coded_width && m_pCodecContext->coded_width < (int)pDvdVideoPicture->iWidth + && m_pCodecContext->coded_width > (int)pDvdVideoPicture->iWidth - 10) +@@ -592,10 +568,6 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + + /* use variable in the frame */ + AVRational pixel_aspect = m_pFrame->sample_aspect_ratio; +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- if (m_pBufferRef) +- pixel_aspect = m_pBufferRef->video->sample_aspect_ratio; +-#endif + + if (pixel_aspect.num == 0) + aspect_ratio = 0; +@@ -620,7 +592,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + if (!m_pFrame) + return false; + +- AVDictionaryEntry * entry = m_dllAvUtil.av_dict_get(m_dllAvCodec.av_frame_get_metadata(m_pFrame), "stereo_mode", NULL, 0); ++ AVDictionaryEntry * entry = av_dict_get(av_frame_get_metadata(m_pFrame), "stereo_mode", NULL, 0); + if(entry && entry->value) + { + strncpy(pDvdVideoPicture->stereo_mode, (const char*)entry->value, sizeof(pDvdVideoPicture->stereo_mode)); +@@ -690,12 +662,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) + pDvdVideoPicture->extended_format = 0; + + PixelFormat pix_fmt; +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- if(m_pBufferRef) +- pix_fmt = (PixelFormat)m_pBufferRef->format; +- else +-#endif +- pix_fmt = (PixelFormat)m_pFrame->format; ++ pix_fmt = (PixelFormat)m_pFrame->format; + + pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt); + return true; +@@ -718,14 +685,14 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + return 0; + } + +- if (!(m_pFilterGraph = m_dllAvFilter.avfilter_graph_alloc())) ++ if (!(m_pFilterGraph = avfilter_graph_alloc())) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph"); + return -1; + } + +- AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer"); +- AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now ++ AVFilter* srcFilter = avfilter_get_by_name("buffer"); ++ AVFilter* outFilter = avfilter_get_by_name("buffersink"); // should be last filter in the graph for now + + CStdString args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d", + m_pCodecContext->width, +@@ -736,64 +703,57 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + m_pCodecContext->sample_aspect_ratio.num, + m_pCodecContext->sample_aspect_ratio.den); + +- if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args, NULL, m_pFilterGraph)) < 0) ++ if ((result = avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args, NULL, m_pFilterGraph)) < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: src"); + return result; + } + +- buffersink_params = m_dllAvFilter.av_buffersink_params_alloc(); +- buffersink_params->pixel_fmts = &m_formats[0]; +-#ifdef FF_API_OLD_VSINK_API +- if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, (void*)buffersink_params->pixel_fmts, m_pFilterGraph)) < 0) +-#else +- if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, buffersink_params, m_pFilterGraph)) < 0) +-#endif ++ if ((result = avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, NULL, m_pFilterGraph)) < 0) + { +- m_dllAvUtil.av_freep(&buffersink_params); + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out"); + return result; + } +- m_dllAvUtil.av_freep(&buffersink_params); ++ if ((result = av_opt_set_int_list(m_pFilterOut, "pix_fmts", &m_formats[0], AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0) ++ { ++ CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - failed settings pix formats"); ++ return result; ++ } + + if (!filters.empty()) + { +- AVFilterInOut* outputs = m_dllAvFilter.avfilter_inout_alloc(); +- AVFilterInOut* inputs = m_dllAvFilter.avfilter_inout_alloc(); ++ AVFilterInOut* outputs = avfilter_inout_alloc(); ++ AVFilterInOut* inputs = avfilter_inout_alloc(); + +- outputs->name = m_dllAvUtil.av_strdup("in"); ++ outputs->name = av_strdup("in"); + outputs->filter_ctx = m_pFilterIn; + outputs->pad_idx = 0; + outputs->next = NULL; + +- inputs->name = m_dllAvUtil.av_strdup("out"); ++ inputs->name = av_strdup("out"); + inputs->filter_ctx = m_pFilterOut; + inputs->pad_idx = 0; + inputs->next = NULL; + +-#if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR) +- if ((result = m_dllAvFilter.avfilter_graph_parse_ptr(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0) +-#else +- if ((result = m_dllAvFilter.avfilter_graph_parse(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0) +-#endif ++ if ((result = avfilter_graph_parse_ptr(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_parse"); + return result; + } + +- m_dllAvFilter.avfilter_inout_free(&outputs); +- m_dllAvFilter.avfilter_inout_free(&inputs); ++ avfilter_inout_free(&outputs); ++ avfilter_inout_free(&inputs); + } + else + { +- if ((result = m_dllAvFilter.avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0) ++ if ((result = avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_link"); + return result; + } + } + +- if ((result = m_dllAvFilter.avfilter_graph_config(m_pFilterGraph, NULL)) < 0) ++ if ((result = avfilter_graph_config(m_pFilterGraph, NULL)) < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_config"); + return result; +@@ -804,17 +764,9 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + + void CDVDVideoCodecFFmpeg::FilterClose() + { +-#if !defined(LIBAVFILTER_AVFRAME_BASED) +- if(m_pBufferRef) +- { +- m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef); +- m_pBufferRef = NULL; +- } +-#endif +- + if (m_pFilterGraph) + { +- m_dllAvFilter.avfilter_graph_free(&m_pFilterGraph); ++ avfilter_graph_free(&m_pFilterGraph); + + // Disposed by above code + m_pFilterIn = NULL; +@@ -828,19 +780,7 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) + + if (frame) + { +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- // API changed in: +- // ffmpeg: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012) +- // not released (post 1.2) +- // libav: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012) +- // release v9 (5 January 2013) +- result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame); +-#else +- // API changed in: +- // ffmpeg: commit 7bac2a78c2241df4bcc1665703bb71afd9a3e692 (28 Apr 2012) +- // release 0.11 (25 May 2012) +- result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame, 0); +-#endif ++ result = av_buffersrc_add_frame(m_pFilterIn, frame); + if (result < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersrc_add_frame"); +@@ -848,8 +788,7 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) + } + } + +-#if defined(LIBAVFILTER_AVFRAME_BASED) +- result = m_dllAvFilter.av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame); ++ result = av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame); + + if(result == AVERROR(EAGAIN) || result == AVERROR_EOF) + return VC_BUFFER; +@@ -859,54 +798,10 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) + return VC_ERROR; + } + +- m_dllAvUtil.av_frame_unref(m_pFrame); +- m_dllAvUtil.av_frame_move_ref(m_pFrame, m_pFilterFrame); ++ av_frame_unref(m_pFrame); ++ av_frame_move_ref(m_pFrame, m_pFilterFrame); + + return VC_PICTURE; +-#else +- int frames; +- +- if(m_pBufferRef) +- { +- m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef); +- m_pBufferRef = NULL; +- } +- +- if ((frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut)) < 0) +- { +- CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_poll_frame"); +- return VC_ERROR; +- } +- +- if (frames > 0) +- { +- +- result = m_dllAvFilter.av_buffersink_get_buffer_ref(m_pFilterOut, &m_pBufferRef, 0); +- if(!m_pBufferRef || result < 0) +- { +- CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - cur_buf"); +- return VC_ERROR; +- } +- +- if(frame == NULL) +- m_pFrame->reordered_opaque = 0; +- else +- m_pFrame->repeat_pict = -(frames - 1); +- +- m_pFrame->interlaced_frame = m_pBufferRef->video->interlaced; +- m_pFrame->top_field_first = m_pBufferRef->video->top_field_first; +- +- memcpy(m_pFrame->linesize, m_pBufferRef->linesize, 4*sizeof(int)); +- memcpy(m_pFrame->data , m_pBufferRef->data , 4*sizeof(uint8_t*)); +- +- if(frames > 1) +- return VC_PICTURE; +- else +- return VC_PICTURE | VC_BUFFER; +- } +- +- return VC_BUFFER; +-#endif + } + + unsigned CDVDVideoCodecFFmpeg::GetConvergeCount() +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index 2287031..ab5e565 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -22,12 +22,17 @@ + + #include "DVDVideoCodec.h" + #include "DVDResource.h" +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +-#include "DllAvUtil.h" +-#include "DllSwScale.h" +-#include "DllAvFilter.h" +-#include "DllPostProc.h" ++#include ++#include "utils/StdString.h" ++ ++extern "C" { ++#include "libavfilter/avfilter.h" ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++#include "libavutil/avutil.h" ++#include "libswscale/swscale.h" ++#include "libpostproc/postprocess.h" ++} + + class CCriticalSection; + +@@ -98,11 +103,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + AVFilterGraph* m_pFilterGraph; + AVFilterContext* m_pFilterIn; + AVFilterContext* m_pFilterOut; +-#if defined(LIBAVFILTER_AVFRAME_BASED) + AVFrame* m_pFilterFrame; +-#else +- AVFilterBufferRef* m_pBufferRef; +-#endif + + int m_iPictureWidth; + int m_iPictureHeight; +@@ -113,12 +114,6 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + + unsigned int m_uSurfacesCount; + +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- DllSwScale m_dllSwScale; +- DllAvFilter m_dllAvFilter; +- DllPostProc m_dllPostProc; +- + std::string m_name; + bool m_bSoftware; + bool m_isHi10p; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp +index 134f29b..31a118d 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp +@@ -24,7 +24,7 @@ + #include "system_gl.h" + #include "DVDVideoCodecVDA.h" + +-#include "DllSwScale.h" ++#include "libswscale/swscale.h" + #include "DVDClock.h" + #include "DVDStreamInfo.h" + #include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h" +@@ -137,7 +137,6 @@ CDVDVideoCodecVDA::CDVDVideoCodecVDA() : CDVDVideoCodec() + pthread_mutex_init(&m_queue_mutex, NULL); + + m_bitstream = NULL; +- m_dllSwScale = NULL; + memset(&m_videobuffer, 0, sizeof(DVDVideoPicture)); + m_DropPictures = false; + m_decode_async = false; +@@ -267,13 +266,6 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) + + if (!m_use_cvBufferRef) + { +- m_dllSwScale = new DllSwScale; +- if (!m_dllSwScale->Load()) +- { +- CFRelease(avcCData); +- return false; +- } +- + // allocate a YV12 DVDVideoPicture buffer. + // first make sure all properties are reset. + memset(&m_videobuffer, 0, sizeof(DVDVideoPicture)); +@@ -394,9 +386,6 @@ void CDVDVideoCodecVDA::Dispose() + + if (m_bitstream) + delete m_bitstream, m_bitstream = NULL; +- +- if (m_dllSwScale) +- delete m_dllSwScale, m_dllSwScale = NULL; + } + + void CDVDVideoCodecVDA::SetDropState(bool bDrop) +@@ -553,7 +542,7 @@ void CDVDVideoCodecVDA::DisplayQueuePop(void) + void CDVDVideoCodecVDA::UYVY422_to_YUV420P(uint8_t *yuv422_ptr, int yuv422_stride, DVDVideoPicture *picture) + { + // convert PIX_FMT_UYVY422 to PIX_FMT_YUV420P. +- struct SwsContext *swcontext = m_dllSwScale->sws_getContext( ++ struct SwsContext *swcontext = sws_getContext( + m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_UYVY422, + m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_YUV420P, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); +@@ -565,15 +554,15 @@ void CDVDVideoCodecVDA::UYVY422_to_YUV420P(uint8_t *yuv422_ptr, int yuv422_strid + uint8_t *dst[] = { picture->data[0], picture->data[1], picture->data[2], 0 }; + int dstStride[] = { picture->iLineSize[0], picture->iLineSize[1], picture->iLineSize[2], 0 }; + +- m_dllSwScale->sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride); +- m_dllSwScale->sws_freeContext(swcontext); ++ sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride); ++ sws_freeContext(swcontext); + } + } + + void CDVDVideoCodecVDA::BGRA_to_YUV420P(uint8_t *bgra_ptr, int bgra_stride, DVDVideoPicture *picture) + { + // convert PIX_FMT_BGRA to PIX_FMT_YUV420P. +- struct SwsContext *swcontext = m_dllSwScale->sws_getContext( ++ struct SwsContext *swcontext = sws_getContext( + m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_BGRA, + m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_YUV420P, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); +@@ -585,8 +574,8 @@ void CDVDVideoCodecVDA::BGRA_to_YUV420P(uint8_t *bgra_ptr, int bgra_stride, DVDV + uint8_t *dst[] = { picture->data[0], picture->data[1], picture->data[2], 0 }; + int dstStride[] = { picture->iLineSize[0], picture->iLineSize[1], picture->iLineSize[2], 0 }; + +- m_dllSwScale->sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride); +- m_dllSwScale->sws_freeContext(swcontext); ++ sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride); ++ sws_freeContext(swcontext); + } + } + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h +index b095778..eb9975e 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h +@@ -22,7 +22,6 @@ + #include "DVDVideoCodec.h" + #include + +-class DllSwScale; + class CBitstreamConverter; + struct frame_queue; + +@@ -66,6 +65,5 @@ class CDVDVideoCodecVDA : public CDVDVideoCodec + + CBitstreamConverter *m_bitstream; + +- DllSwScale *m_dllSwScale; + DVDVideoPicture m_videobuffer; + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp +index c7651c4..d55853a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp +@@ -27,13 +27,16 @@ + #include "DVDStreamInfo.h" + #include "DVDCodecUtils.h" + #include "DVDVideoCodecVideoToolBox.h" +-#include "lib/DllSwScale.h" +-#include "lib/DllAvFormat.h" + #include "settings/Settings.h" + #include "utils/log.h" + #include "utils/TimeUtils.h" + #include "osx/DarwinUtils.h" + ++extern "C" { ++#include "lib/libswscale/swscale.h" ++#include "lib/libavformat/avformat.h" ++} ++ + #if defined(__cplusplus) + extern "C" + { +@@ -436,7 +439,7 @@ typedef struct { + uint8_t* decoderConfig; + } quicktime_esds_t; + +-int quicktime_write_mp4_descr_length(DllAvFormat *av_format_ctx, AVIOContext *pb, int length, int compact) ++int quicktime_write_mp4_descr_length(AVIOContext *pb, int length, int compact) + { + int i; + uint8_t b; +@@ -473,45 +476,45 @@ int quicktime_write_mp4_descr_length(DllAvFormat *av_format_ctx, AVIOContext *pb + { + b |= 0x80; + } +- av_format_ctx->avio_w8(pb, b); ++ avio_w8(pb, b); + } + + return numBytes; + } + +-void quicktime_write_esds(DllAvFormat *av_format_ctx, AVIOContext *pb, quicktime_esds_t *esds) ++void quicktime_write_esds(AVIOContext *pb, quicktime_esds_t *esds) + { +- av_format_ctx->avio_w8(pb, 0); // Version +- av_format_ctx->avio_wb24(pb, 0); // Flags ++ avio_w8(pb, 0); // Version ++ avio_wb24(pb, 0); // Flags + + // elementary stream descriptor tag +- av_format_ctx->avio_w8(pb, 0x03); +- quicktime_write_mp4_descr_length(av_format_ctx, pb, ++ avio_w8(pb, 0x03); ++ quicktime_write_mp4_descr_length(pb, + 3 + 5 + (13 + 5 + esds->decoderConfigLen) + 3, false); + // 3 bytes + 5 bytes for tag +- av_format_ctx->avio_wb16(pb, esds->esid); +- av_format_ctx->avio_w8(pb, esds->stream_priority); ++ avio_wb16(pb, esds->esid); ++ avio_w8(pb, esds->stream_priority); + + // decoder configuration description tag +- av_format_ctx->avio_w8(pb, 0x04); +- quicktime_write_mp4_descr_length(av_format_ctx, pb, ++ avio_w8(pb, 0x04); ++ quicktime_write_mp4_descr_length(pb, + 13 + 5 + esds->decoderConfigLen, false); + // 13 bytes + 5 bytes for tag +- av_format_ctx->avio_w8(pb, esds->objectTypeId); // objectTypeIndication +- av_format_ctx->avio_w8(pb, esds->streamType); // streamType +- av_format_ctx->avio_wb24(pb, esds->bufferSizeDB); // buffer size +- av_format_ctx->avio_wb32(pb, esds->maxBitrate); // max bitrate +- av_format_ctx->avio_wb32(pb, esds->avgBitrate); // average bitrate ++ avio_w8(pb, esds->objectTypeId); // objectTypeIndication ++ avio_w8(pb, esds->streamType); // streamType ++ avio_wb24(pb, esds->bufferSizeDB); // buffer size ++ avio_wb32(pb, esds->maxBitrate); // max bitrate ++ avio_wb32(pb, esds->avgBitrate); // average bitrate + + // decoder specific description tag +- av_format_ctx->avio_w8(pb, 0x05); +- quicktime_write_mp4_descr_length(av_format_ctx, pb, esds->decoderConfigLen, false); +- av_format_ctx->avio_write(pb, esds->decoderConfig, esds->decoderConfigLen); ++ avio_w8(pb, 0x05); ++ quicktime_write_mp4_descr_length(pb, esds->decoderConfigLen, false); ++ avio_write(pb, esds->decoderConfig, esds->decoderConfigLen); + + // sync layer configuration descriptor tag +- av_format_ctx->avio_w8(pb, 0x06); // tag +- av_format_ctx->avio_w8(pb, 0x01); // length +- av_format_ctx->avio_w8(pb, 0x7F); // no SL ++ avio_w8(pb, 0x06); // tag ++ avio_w8(pb, 0x01); // length ++ avio_w8(pb, 0x7F); // no SL + + /* no IPI_DescrPointer */ + /* no IP_IdentificationDataSet */ +@@ -523,7 +526,7 @@ void quicktime_write_esds(DllAvFormat *av_format_ctx, AVIOContext *pb, quicktime + + } + +-quicktime_esds_t* quicktime_set_esds(DllAvFormat *av_format_ctx, const uint8_t * decoderConfig, int decoderConfigLen) ++quicktime_esds_t* quicktime_set_esds(const uint8_t * decoderConfig, int decoderConfigLen) + { + // ffmpeg's codec->avctx->extradata, codec->avctx->extradata_size + // are decoderConfig/decoderConfigLen +@@ -652,8 +655,7 @@ const uint8_t *avc_find_startcode(const uint8_t *p, const uint8_t *end) + return out; + } + +-const int avc_parse_nal_units(DllAvFormat *av_format_ctx, +- AVIOContext *pb, const uint8_t *buf_in, int size) ++const int avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size) + { + const uint8_t *p = buf_in; + const uint8_t *end = p + size; +@@ -665,26 +667,25 @@ const int avc_parse_nal_units(DllAvFormat *av_format_ctx, + { + while (!*(nal_start++)); + nal_end = avc_find_startcode(nal_start, end); +- av_format_ctx->avio_wb32(pb, nal_end - nal_start); +- av_format_ctx->avio_write(pb, nal_start, nal_end - nal_start); ++ avio_wb32(pb, nal_end - nal_start); ++ avio_write(pb, nal_start, nal_end - nal_start); + size += 4 + nal_end - nal_start; + nal_start = nal_end; + } + return size; + } + +-const int avc_parse_nal_units_buf(DllAvUtil *av_util_ctx, DllAvFormat *av_format_ctx, +- const uint8_t *buf_in, uint8_t **buf, int *size) ++const int avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size) + { + AVIOContext *pb; +- int ret = av_format_ctx->avio_open_dyn_buf(&pb); ++ int ret = avio_open_dyn_buf(&pb); + if (ret < 0) + return ret; + +- avc_parse_nal_units(av_format_ctx, pb, buf_in, *size); ++ avc_parse_nal_units(pb, buf_in, *size); + +- av_util_ctx->av_freep(buf); +- *size = av_format_ctx->avio_close_dyn_buf(pb, buf); ++ av_freep(buf); ++ *size = avio_close_dyn_buf(pb, buf); + return 0; + } + +@@ -729,8 +730,7 @@ const int avc_parse_nal_units_buf(DllAvUtil *av_util_ctx, DllAvFormat *av_format + field_pic_flag: 0 on the frames, + (field_pic_flag: 1 would indicate a normal interlaced frame). + */ +-const int isom_write_avcc(DllAvUtil *av_util_ctx, DllAvFormat *av_format_ctx, +- AVIOContext *pb, const uint8_t *data, int len) ++const int isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) + { + // extradata from bytestream h264, convert to avcC atom data for bitstream + if (len > 6) +@@ -742,7 +742,7 @@ const int isom_write_avcc(DllAvUtil *av_util_ctx, DllAvFormat *av_format_ctx, + uint32_t sps_size=0, pps_size=0; + uint8_t *sps=0, *pps=0; + +- int ret = avc_parse_nal_units_buf(av_util_ctx, av_format_ctx, data, &buf, &len); ++ int ret = avc_parse_nal_units_buf(data, &buf, &len); + if (ret < 0) + return ret; + start = buf; +@@ -769,26 +769,26 @@ const int isom_write_avcc(DllAvUtil *av_util_ctx, DllAvFormat *av_format_ctx, + } + assert(sps); + +- av_format_ctx->avio_w8(pb, 1); /* version */ +- av_format_ctx->avio_w8(pb, sps[1]); /* profile */ +- av_format_ctx->avio_w8(pb, sps[2]); /* profile compat */ +- av_format_ctx->avio_w8(pb, sps[3]); /* level */ +- av_format_ctx->avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ +- av_format_ctx->avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ ++ avio_w8(pb, 1); /* version */ ++ avio_w8(pb, sps[1]); /* profile */ ++ avio_w8(pb, sps[2]); /* profile compat */ ++ avio_w8(pb, sps[3]); /* level */ ++ avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ ++ avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ + +- av_format_ctx->avio_wb16(pb, sps_size); +- av_format_ctx->avio_write(pb, sps, sps_size); ++ avio_wb16(pb, sps_size); ++ avio_write(pb, sps, sps_size); + if (pps) + { +- av_format_ctx->avio_w8(pb, 1); /* number of pps */ +- av_format_ctx->avio_wb16(pb, pps_size); +- av_format_ctx->avio_write(pb, pps, pps_size); ++ avio_w8(pb, 1); /* number of pps */ ++ avio_wb16(pb, pps_size); ++ avio_write(pb, pps, pps_size); + } +- av_util_ctx->av_free(start); ++ av_free(start); + } + else + { +- av_format_ctx->avio_write(pb, data, len); ++ avio_write(pb, data, len); + } + } + return 0; +@@ -1043,8 +1043,6 @@ CDVDVideoCodecVideoToolBox::CDVDVideoCodecVideoToolBox() : CDVDVideoCodec() + + m_convert_bytestream = false; + m_convert_3byteTo4byteNALSize = false; +- m_dllAvUtil = NULL; +- m_dllAvFormat = NULL; + memset(&m_videobuffer, 0, sizeof(DVDVideoPicture)); + m_DropPictures = false; + m_sort_time_offset = 0.0; +@@ -1060,11 +1058,6 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + { + if (CSettings::Get().GetBool("videoplayer.usevideotoolbox") && !hints.software) + { +- m_dllAvUtil = new DllAvUtil; +- m_dllAvFormat = new DllAvFormat; +- if (!m_dllAvUtil->Load() || !m_dllAvFormat->Load()) +- return false; +- + int width = hints.width; + int height = hints.height; + int level = hints.level; +@@ -1103,16 +1096,16 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + AVIOContext *pb; + quicktime_esds_t *esds; + +- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if (avio_open_dyn_buf(&pb) < 0) + return false; + +- esds = quicktime_set_esds(m_dllAvFormat, extradata, extrasize); +- quicktime_write_esds(m_dllAvFormat, pb, esds); ++ esds = quicktime_set_esds(extradata, extrasize); ++ quicktime_write_esds(pb, esds); + + // unhook from ffmpeg's extradata + extradata = NULL; + // extract the esds atom decoderConfig from extradata +- extrasize = m_dllAvFormat->avio_close_dyn_buf(pb, &extradata); ++ extrasize = avio_close_dyn_buf(pb, &extradata); + free(esds->decoderConfig); + free(esds); + +@@ -1120,7 +1113,7 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + kVTFormatMPEG4Video, width, height, extradata, extrasize, 'esds'); + + // done with the converted extradata, we MUST free using av_free +- m_dllAvUtil->av_free(extradata); ++ av_free(extradata); + } + else + { +@@ -1188,21 +1181,21 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + // NAL reformating to bitstream format required + + AVIOContext *pb; +- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if (avio_open_dyn_buf(&pb) < 0) + return false; + + m_convert_bytestream = true; + // create a valid avcC atom data from ffmpeg's extradata +- isom_write_avcc(m_dllAvUtil, m_dllAvFormat, pb, extradata, extrasize); ++ isom_write_avcc(pb, extradata, extrasize); + // unhook from ffmpeg's extradata + extradata = NULL; + // extract the avcC atom data into extradata getting size into extrasize +- extrasize = m_dllAvFormat->avio_close_dyn_buf(pb, &extradata); ++ extrasize = avio_close_dyn_buf(pb, &extradata); + + // check for interlaced and get number of ref frames + if (!validate_avcC_spc(extradata, extrasize, &m_max_ref_frames, &spsLevel, &spsProfile)) + { +- m_dllAvUtil->av_free(extradata); ++ av_free(extradata); + return false; + } + +@@ -1221,7 +1214,7 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + // Main@L3.2, VTB cannot handle greater than 4 ref frames (ie. flash video) + CLog::Log(LOGNOTICE, "%s - Main@L3.2 detected, VTB cannot decode with %d ref frames", + __FUNCTION__, m_max_ref_frames); +- m_dllAvUtil->av_free(extradata); ++ av_free(extradata); + return false; + } + +@@ -1230,7 +1223,7 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o + kVTFormatH264, width, height, extradata, extrasize, 'avcC'); + + // done with the new converted extradata, we MUST free using av_free +- m_dllAvUtil->av_free(extradata); ++ av_free(extradata); + CLog::Log(LOGNOTICE, "%s - created avcC atom of size(%d)", __FUNCTION__, extrasize); + } + else +@@ -1314,17 +1307,6 @@ void CDVDVideoCodecVideoToolBox::Dispose() + + while (m_queue_depth) + DisplayQueuePop(); +- +- if (m_dllAvUtil) +- { +- delete m_dllAvUtil; +- m_dllAvUtil = NULL; +- } +- if (m_dllAvFormat) +- { +- delete m_dllAvFormat; +- m_dllAvFormat = NULL; +- } + } + + void CDVDVideoCodecVideoToolBox::SetDropState(bool bDrop) +@@ -1348,17 +1330,17 @@ int CDVDVideoCodecVideoToolBox::Decode(uint8_t* pData, int iSize, double dts, do + if (m_convert_bytestream) + { + // convert demuxer packet from bytestream (AnnexB) to bitstream +- if(m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if(avio_open_dyn_buf(&pb) < 0) + return VC_ERROR; + +- avc_parse_nal_units(m_dllAvFormat, pb, pData, iSize); +- demux_size = m_dllAvFormat->avio_close_dyn_buf(pb, &demux_buff); ++ avc_parse_nal_units(pb, pData, iSize); ++ demux_size = avio_close_dyn_buf(pb, &demux_buff); + sampleBuff = CreateSampleBufferFrom(m_fmt_desc, demux_buff, demux_size); + } + else if (m_convert_3byteTo4byteNALSize) + { + // convert demuxer packet from 3 byte NAL sizes to 4 byte +- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if (avio_open_dyn_buf(&pb) < 0) + return VC_ERROR; + + uint32_t nal_size; +@@ -1367,13 +1349,13 @@ int CDVDVideoCodecVideoToolBox::Decode(uint8_t* pData, int iSize, double dts, do + while (nal_start < end) + { + nal_size = VDA_RB24(nal_start); +- m_dllAvFormat->avio_wb32(pb, nal_size); ++ avio_wb32(pb, nal_size); + nal_start += 3; +- m_dllAvFormat->avio_write(pb, nal_start, nal_size); ++ avio_write(pb, nal_start, nal_size); + nal_start += nal_size; + } + +- demux_size = m_dllAvFormat->avio_close_dyn_buf(pb, &demux_buff); ++ demux_size = avio_close_dyn_buf(pb, &demux_buff); + sampleBuff = CreateSampleBufferFrom(m_fmt_desc, demux_buff, demux_size); + } + else +@@ -1384,7 +1366,7 @@ int CDVDVideoCodecVideoToolBox::Decode(uint8_t* pData, int iSize, double dts, do + if (!sampleBuff) + { + if (demux_size) +- m_dllAvUtil->av_free(demux_buff); ++ av_free(demux_buff); + CLog::Log(LOGNOTICE, "%s - CreateSampleBufferFrom failed", __FUNCTION__); + return VC_ERROR; + } +@@ -1404,7 +1386,7 @@ int CDVDVideoCodecVideoToolBox::Decode(uint8_t* pData, int iSize, double dts, do + CFRelease(frameInfo); + CFRelease(sampleBuff); + if (demux_size) +- m_dllAvUtil->av_free(demux_buff); ++ av_free(demux_buff); + return VC_ERROR; + // VTDecompressionSessionDecodeFrame returned 8969 (codecBadDataErr) + // VTDecompressionSessionDecodeFrame returned -12350 +@@ -1421,14 +1403,14 @@ int CDVDVideoCodecVideoToolBox::Decode(uint8_t* pData, int iSize, double dts, do + CFRelease(frameInfo); + CFRelease(sampleBuff); + if (demux_size) +- m_dllAvUtil->av_free(demux_buff); ++ av_free(demux_buff); + return VC_ERROR; + } + + CFRelease(frameInfo); + CFRelease(sampleBuff); + if (demux_size) +- m_dllAvUtil->av_free(demux_buff); ++ av_free(demux_buff); + } + + // TODO: queue depth is related to the number of reference frames in encoded h.264. +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.h +index bfc083b..d320886 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.h +@@ -39,8 +39,6 @@ typedef struct frame_queue { + struct frame_queue *nextframe; + } frame_queue; + +-class DllAvUtil; +-class DllAvFormat; + class CDVDVideoCodecVideoToolBox : public CDVDVideoCodec + { + public: +@@ -80,9 +78,6 @@ class CDVDVideoCodecVideoToolBox : public CDVDVideoCodec + + bool m_convert_bytestream; + bool m_convert_3byteTo4byteNALSize; +- +- DllAvUtil *m_dllAvUtil; +- DllAvFormat *m_dllAvFormat; + }; + + #endif +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +index f993efb..a83b7d7 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +@@ -20,6 +20,7 @@ + + #include "DVDVideoPPFFmpeg.h" + #include "utils/log.h" ++#include "cores/FFmpeg.h" + + CDVDVideoPPFFmpeg::CDVDVideoPPFFmpeg(const CStdString& mType) + { +@@ -38,12 +39,12 @@ void CDVDVideoPPFFmpeg::Dispose() + { + if (m_pMode) + { +- m_dll.pp_free_mode(m_pMode); ++ pp_free_mode(m_pMode); + m_pMode = NULL; + } + if(m_pContext) + { +- m_dll.pp_free_context(m_pContext); ++ pp_free_context(m_pContext); + m_pContext = NULL; + } + +@@ -63,14 +64,10 @@ void CDVDVideoPPFFmpeg::Dispose() + + m_iInitWidth = 0; + m_iInitHeight = 0; +- +- m_dll.Unload(); + } + + bool CDVDVideoPPFFmpeg::CheckInit(int iWidth, int iHeight) + { +- if (!m_dll.IsLoaded() && !m_dll.Load()) return false; +- + if(m_iInitWidth != iWidth || m_iInitHeight != iHeight) + { + if(m_pContext || m_pMode) +@@ -78,12 +75,12 @@ bool CDVDVideoPPFFmpeg::CheckInit(int iWidth, int iHeight) + Dispose(); + } + +- m_pContext = m_dll.pp_get_context(m_pSource->iWidth, m_pSource->iHeight, PPCPUFlags() | PP_FORMAT_420); ++ m_pContext = pp_get_context(m_pSource->iWidth, m_pSource->iHeight, PPCPUFlags() | PP_FORMAT_420); + + m_iInitWidth = m_pSource->iWidth; + m_iInitHeight = m_pSource->iHeight; + +- m_pMode = m_dll.pp_get_mode_by_name_and_quality((char *)m_sType.c_str(), PP_QUALITY_MAX); ++ m_pMode = pp_get_mode_by_name_and_quality((char *)m_sType.c_str(), PP_QUALITY_MAX); + } + + +@@ -134,7 +131,7 @@ bool CDVDVideoPPFFmpeg::Process(DVDVideoPicture* pPicture) + int pict_type = (m_pSource->qscale_type != DVP_QSCALE_MPEG1) ? + PP_PICT_TYPE_QP2 : 0; + +- m_dll.pp_postprocess(m_pSource->data, m_pSource->iLineSize, ++ pp_postprocess((const uint8_t**)m_pSource->data, m_pSource->iLineSize, + m_pTarget->data, m_pTarget->iLineSize, + m_pSource->iWidth, m_pSource->iHeight, + m_pSource->qscale_table, m_pSource->qscale_stride, +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.h +index 08bc6c2..5febe0b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.h +@@ -21,7 +21,7 @@ + */ + + #include "DVDVideoCodec.h" +-#include "DllPostProc.h" ++#include "utils/StdString.h" + + class CDVDVideoPPFFmpeg + { +@@ -52,8 +52,6 @@ class CDVDVideoPPFFmpeg + int m_iInitWidth, m_iInitHeight; + bool CheckInit(int iWidth, int iHeight); + bool CheckFrameBuffer(const DVDVideoPicture* pSource); +- +- DllPostProc m_dll; + }; + + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +index 3bafe92..b0025ed 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +@@ -19,7 +19,7 @@ + */ + #pragma once + +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + #include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h" + #include "guilib/D3DResource.h" + #include "threads/Event.h" +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h +index 22a9d39..811841f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h +@@ -19,7 +19,7 @@ + */ + #pragma once + +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + #include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h" + #include "guilib/D3DResource.h" + #include "threads/Event.h" +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index bfefc9d..47c84e6 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -24,6 +24,8 @@ + #include "DVDVideoCodec.h" + #include + #include ++#include "utils/log.h" ++#include "threads/SingleLock.h" + + #define CHECK(a) \ + do { \ +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +index a520e42..9744c80 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +@@ -21,7 +21,7 @@ + + #include "system_gl.h" + +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + #include "DVDVideoCodecFFmpeg.h" + #include + #include +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +index c5e4714..a7cd60a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +@@ -21,7 +21,7 @@ + + #include "system_gl.h" + +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + #include "DVDVideoCodecFFmpeg.h" + + struct vda_context; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 4bc5180..5993767 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -530,9 +530,6 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned + m_DisplayState = VDPAU_OPEN; + m_vdpauConfigured = false; + +- if (!m_dllAvUtil.Load()) +- return false; +- + m_presentPicture = 0; + + { +@@ -616,11 +613,9 @@ void CDecoder::Close() + + if (m_hwContext.bitstream_buffers_allocated) + { +- m_dllAvUtil.av_freep(&m_hwContext.bitstream_buffers); ++ av_freep(&m_hwContext.bitstream_buffers); + } + +- m_dllAvUtil.Unload(); +- + if (m_vdpauConfig.context) + m_vdpauConfig.context->Release(); + m_vdpauConfig.context = 0; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index ccad9a6..86a1714 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -40,19 +40,15 @@ + + #include "system_gl.h" + +-#include "DllAvUtil.h" + #include "DVDVideoCodec.h" + #include "DVDVideoCodecFFmpeg.h" +-#include "libavcodec/vdpau.h" + #include + #include + #define GLX_GLXEXT_PROTOTYPES + #include + +-#include "DllAvUtil.h" + #include "DVDVideoCodec.h" + #include "DVDVideoCodecFFmpeg.h" +-#include "libavcodec/vdpau.h" + #include "threads/CriticalSection.h" + #include "threads/SharedSection.h" + #include "settings/VideoSettings.h" +@@ -61,6 +57,12 @@ + #include "threads/Thread.h" + #include "utils/ActorProtocol.h" + #include ++#include ++ ++extern "C" { ++#include "libavutil/avutil.h" ++#include "libavcodec/vdpau.h" ++} + + using namespace Actor; + +@@ -614,7 +616,6 @@ class CDecoder + int m_ErrorCount; + bool m_DecoderError; + +- DllAvUtil m_dllAvUtil; + ThreadIdentifier m_decoderThread; + bool m_vdpauConfigured; + CVdpauConfig m_vdpauConfig; +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +index 6b3e901..07b24ca 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +@@ -34,7 +34,10 @@ class CDVDInputStream; + #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) + #include "config.h" + #endif +-#include "DllAvCodec.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + + #ifndef __GNUC__ + #pragma warning(pop) +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index fcc186d..03fe65c 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -55,7 +55,7 @@ void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) + { + if(!m_stream) return; + char temp[128]; +- m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0); ++ avcodec_string(temp, 128, m_stream->codec, 0); + strInfo = temp; + } + +@@ -81,7 +81,7 @@ void CDemuxStreamVideoFFmpeg::GetStreamInfo(std::string& strInfo) + { + if(!m_stream) return; + char temp[128]; +- m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0); ++ avcodec_string(temp, 128, m_stream->codec, 0); + strInfo = temp; + } + +@@ -89,14 +89,12 @@ void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo) + { + if(!m_stream) return; + char temp[128]; +- m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0); ++ avcodec_string(temp, 128, m_stream->codec, 0); + strInfo = temp; + } + + // these need to be put somewhere that are compiled, we should have some better place for it + +-int DllAvFormat::m_avformat_refcnt = 0; +-CCriticalSection DllAvCodec::m_critSection; + static CCriticalSection m_logSection; + std::map g_logbuffer; + +@@ -190,7 +188,7 @@ static int dvd_file_write(URLContext *h, uint8_t* buf, int size) + return -1; + } + */ +-static offset_t dvd_file_seek(void *h, offset_t pos, int whence) ++static int64_t dvd_file_seek(void *h, int64_t pos, int whence) + { + if(interrupt_cb(h)) + return AVERROR_EXIT; +@@ -248,14 +246,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + if (!pInput) return false; + +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load()) { +- CLog::Log(LOGERROR,"CDVDDemuxFFmpeg::Open - failed to load ffmpeg libraries"); +- return false; +- } +- +- // register codecs +- m_dllAvFormat.av_register_all(); +- + m_pInput = pInput; + strFile = m_pInput->GetFileName(); + +@@ -267,19 +257,17 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + /* check if we can get a hint from content */ + if ( content.compare("video/x-vobsub") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("mpeg"); ++ iformat = av_find_input_format("mpeg"); + else if( content.compare("video/x-dvd-mpeg") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("mpeg"); ++ iformat = av_find_input_format("mpeg"); + else if( content.compare("video/x-mpegts") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("mpegts"); ++ iformat = av_find_input_format("mpegts"); + else if( content.compare("multipart/x-mixed-replace") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("mjpeg"); +- else if( content.compare("audio/flac") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("flac"); ++ iformat = av_find_input_format("mjpeg"); + } + + // open the demuxer +- m_pFormatContext = m_dllAvFormat.avformat_alloc_context(); ++ m_pFormatContext = avformat_alloc_context(); + m_pFormatContext->interrupt_callback = int_cb; + + // try to abort after 30 seconds +@@ -300,26 +288,26 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + // try mmsh, then mmst + url.SetProtocol("mmsh"); + url.SetProtocolOptions(""); +- result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options); ++ result = avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options); + if (result < 0) + { + url.SetProtocol("mmst"); + strFile = url.Get(); + } + } +- if (result < 0 && m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 ) ++ if (result < 0 && avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 ) + { + CLog::Log(LOGDEBUG, "Error, could not open file %s", CURL::GetRedacted(strFile).c_str()); + Dispose(); +- m_dllAvUtil.av_dict_free(&options); ++ av_dict_free(&options); + return false; + } +- m_dllAvUtil.av_dict_free(&options); ++ av_dict_free(&options); + } + else + { +- unsigned char* buffer = (unsigned char*)m_dllAvUtil.av_malloc(FFMPEG_FILE_BUFFER_SIZE); +- m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek); ++ unsigned char* buffer = (unsigned char*)av_malloc(FFMPEG_FILE_BUFFER_SIZE); ++ m_ioContext = avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek); + m_ioContext->max_packet_size = m_pInput->GetBlockSize(); + if(m_ioContext->max_packet_size) + m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size; +@@ -334,7 +322,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed"); + + if (!trySPDIFonly) +- m_dllAvFormat.av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); ++ av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); + + // Use the more low-level code in case we have been built against an old + // FFmpeg without the above av_probe_input_buffer(), or in case we only +@@ -351,7 +339,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + pd.filename = strFile.c_str(); + + // read data using avformat's buffers +- pd.buf_size = m_dllAvFormat.avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : m_ioContext->buffer_size); ++ pd.buf_size = avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : m_ioContext->buffer_size); + if (pd.buf_size <= 0) + { + CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); +@@ -360,7 +348,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE); + + // restore position again +- m_dllAvFormat.avio_seek(m_ioContext , 0, SEEK_SET); ++ avio_seek(m_ioContext , 0, SEEK_SET); + + // the advancedsetting is for allowing the user to force outputting the + // 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode +@@ -374,7 +362,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS + // may be just padded. + AVInputFormat *iformat2; +- iformat2 = m_dllAvFormat.av_find_input_format("spdif"); ++ iformat2 = av_find_input_format("spdif"); + + if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) + { +@@ -383,7 +371,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + else + { + // not spdif or no spdif demuxer, try dts +- iformat2 = m_dllAvFormat.av_find_input_format("dts"); ++ iformat2 = av_find_input_format("dts"); + + if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) + { +@@ -406,13 +394,13 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + /* check if we can get a hint from content */ + if( content.compare("audio/aacp") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("aac"); ++ iformat = av_find_input_format("aac"); + else if( content.compare("audio/aac") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("aac"); ++ iformat = av_find_input_format("aac"); + else if( content.compare("video/flv") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("flv"); ++ iformat = av_find_input_format("flv"); + else if( content.compare("video/x-flv") == 0 ) +- iformat = m_dllAvFormat.av_find_input_format("flv"); ++ iformat = av_find_input_format("flv"); + } + + if (!iformat) +@@ -432,7 +420,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + m_pFormatContext->pb = m_ioContext; + +- if (m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0) ++ if (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0) + { + CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); + Dispose(); +@@ -460,7 +448,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + + CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__); +- int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL); ++ int iErr = avformat_find_stream_info(m_pFormatContext, NULL); + if (iErr < 0) + { + CLog::Log(LOGWARNING,"could not find codec parameters for %s", CURL::GetRedacted(strFile).c_str()); +@@ -485,7 +473,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; + + // print some extra information +- m_dllAvFormat.av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0); ++ av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0); + + UpdateCurrentPTS(); + +@@ -497,7 +485,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + void CDVDDemuxFFmpeg::Dispose() + { + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + + if (m_pFormatContext) + { +@@ -506,13 +494,13 @@ void CDVDDemuxFFmpeg::Dispose() + CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak"); + m_ioContext = m_pFormatContext->pb; + } +- m_dllAvFormat.avformat_close_input(&m_pFormatContext); ++ avformat_close_input(&m_pFormatContext); + } + + if(m_ioContext) + { +- m_dllAvUtil.av_free(m_ioContext->buffer); +- m_dllAvUtil.av_free(m_ioContext); ++ av_free(m_ioContext->buffer); ++ av_free(m_ioContext); + } + + m_ioContext = NULL; +@@ -522,10 +510,6 @@ void CDVDDemuxFFmpeg::Dispose() + DisposeStreams(); + + m_pInput = NULL; +- +- m_dllAvFormat.Unload(); +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); + } + + void CDVDDemuxFFmpeg::Reset() +@@ -539,12 +523,12 @@ void CDVDDemuxFFmpeg::Flush() + { + // naughty usage of an internal ffmpeg function + if (m_pFormatContext) +- m_dllAvFormat.av_read_frame_flush(m_pFormatContext); ++ av_read_frame_flush(m_pFormatContext); + + m_iCurrentPts = DVD_NOPTS_VALUE; + + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + } + + void CDVDDemuxFFmpeg::Abort() +@@ -560,12 +544,12 @@ void CDVDDemuxFFmpeg::SetSpeed(int iSpeed) + if(m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE) + { + m_pInput->Pause((double)m_iCurrentPts); +- m_dllAvFormat.av_read_pause(m_pFormatContext); ++ av_read_pause(m_pFormatContext); + } + else if(m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE) + { + m_pInput->Pause((double)m_iCurrentPts); +- m_dllAvFormat.av_read_play(m_pFormatContext); ++ av_read_play(m_pFormatContext); + } + m_speed = iSpeed; + +@@ -606,10 +590,10 @@ AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url) + const CStdString &value = it->second; + + if (name.Equals("seekable")) +- m_dllAvUtil.av_dict_set(&options, "seekable", value.c_str(), 0); ++ av_dict_set(&options, "seekable", value.c_str(), 0); + else if (name.Equals("User-Agent")) + { +- m_dllAvUtil.av_dict_set(&options, "user-agent", value.c_str(), 0); ++ av_dict_set(&options, "user-agent", value.c_str(), 0); + hasUserAgent = true; + } + else if (!name.Equals("auth") && !name.Equals("Encoding")) +@@ -618,14 +602,14 @@ AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url) + } + if (!hasUserAgent) + // set default xbmc user-agent. +- m_dllAvUtil.av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0); ++ av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0); + + if (!headers.empty()) +- m_dllAvUtil.av_dict_set(&options, "headers", headers.c_str(), 0); ++ av_dict_set(&options, "headers", headers.c_str(), 0); + + std::string cookies; + if (XFILE::CCurlFile::GetCookies(url, cookies)) +- m_dllAvUtil.av_dict_set(&options, "cookies", cookies.c_str(), 0); ++ av_dict_set(&options, "cookies", cookies.c_str(), 0); + + } + return options; +@@ -678,7 +662,7 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + + // timeout reads after 100ms + m_timeout.Set(20000); +- m_pkt.result = m_dllAvFormat.av_read_frame(m_pFormatContext, &m_pkt.pkt); ++ m_pkt.result = av_read_frame(m_pFormatContext, &m_pkt.pkt); + m_timeout.SetInfinite(); + } + +@@ -717,7 +701,7 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached"); + + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + } + else + { +@@ -803,7 +787,7 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + if(duration > stream->duration) + { + stream->duration = duration; +- duration = m_dllAvUtil.av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF); ++ duration = av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF); + if ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE) + || (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration)) + m_pFormatContext->duration = duration; +@@ -815,7 +799,7 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + pPacket->iStreamId = m_pkt.pkt.stream_index; + } + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + } + } + } // end of lock scope +@@ -872,7 +856,7 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) + time = 0; + + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + + CDVDInputStream::ISeekTime* ist = dynamic_cast(m_pInput); + if (ist) +@@ -905,7 +889,7 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) + int ret; + { + CSingleLock lock(m_critSection); +- ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); ++ ret = av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); + + if(ret >= 0) + UpdateCurrentPTS(); +@@ -930,13 +914,13 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) + bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) + { + CSingleLock lock(m_critSection); +- int ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE); ++ int ret = av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE); + + if(ret >= 0) + UpdateCurrentPTS(); + + m_pkt.result = -1; +- m_dllAvCodec.av_free_packet(&m_pkt.pkt); ++ av_free_packet(&m_pkt.pkt); + + return (ret >= 0); + } +@@ -1083,8 +1067,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + st->iBitRate = pStream->codec->bit_rate; + st->iBitsPerSample = pStream->codec->bits_per_raw_sample; + +- if(m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)) +- st->m_description = m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)->value; ++ if(av_dict_get(pStream->metadata, "title", NULL, 0)) ++ st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; + + break; + } +@@ -1102,7 +1086,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + st->bPTSInvalid = true; + + #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- AVRational r_frame_rate = m_dllAvFormat.av_stream_get_r_frame_rate(pStream); ++ AVRational r_frame_rate = av_stream_get_r_frame_rate(pStream); + #else + AVRational r_frame_rate = pStream->r_frame_rate; + #endif +@@ -1151,11 +1135,11 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + st->iOrientation = 0; + st->iBitsPerPixel = pStream->codec->bits_per_coded_sample; + +- AVDictionaryEntry *rtag = m_dllAvUtil.av_dict_get(pStream->metadata, "rotate", NULL, 0); ++ AVDictionaryEntry *rtag = av_dict_get(pStream->metadata, "rotate", NULL, 0); + if (rtag) + st->iOrientation = atoi(rtag->value); + +- rtag = m_dllAvUtil.av_dict_get(pStream->metadata, "stereo_mode", NULL, 0); ++ rtag = av_dict_get(pStream->metadata, "stereo_mode", NULL, 0); + if (rtag && rtag->value) + st->stereo_mode = rtag->value; + +@@ -1196,8 +1180,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + CDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream); + stream = st; + +- if(m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)) +- st->m_description = m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)->value; ++ if(av_dict_get(pStream->metadata, "title", NULL, 0)) ++ st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; + + break; + } +@@ -1210,7 +1194,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + { + std::string fileName = "special://temp/fonts/"; + XFILE::CDirectory::Create(fileName); +- AVDictionaryEntry *nameTag = m_dllAvUtil.av_dict_get(pStream->metadata, "filename", NULL, 0); ++ AVDictionaryEntry *nameTag = av_dict_get(pStream->metadata, "filename", NULL, 0); + if (!nameTag) { + CLog::Log(LOGERROR, "%s: TTF attachment has no name", __FUNCTION__); + break; +@@ -1251,7 +1235,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + stream->pPrivate = pStream; + stream->flags = (CDemuxStream::EFlags)pStream->disposition; + +- AVDictionaryEntry *langTag = m_dllAvUtil.av_dict_get(pStream->metadata, "language", NULL, 0); ++ AVDictionaryEntry *langTag = av_dict_get(pStream->metadata, "language", NULL, 0); + if (langTag) + strncpy(stream->language, langTag->value, 3); + +@@ -1382,7 +1366,7 @@ void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName) + if(chapterIdx <= 0) + return; + +- AVDictionaryEntry *titleTag = m_dllAvUtil.av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata, ++ AVDictionaryEntry *titleTag = av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata, + "title", NULL, 0); + if (titleTag) + strChapterName = titleTag->value; +@@ -1463,7 +1447,7 @@ void CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId, CStdString &strName) + } + #endif + +- AVCodec *codec = m_dllAvCodec.avcodec_find_decoder(stream->codec); ++ AVCodec *codec = avcodec_find_decoder(stream->codec); + if (codec) + strName = codec->name; + } +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index aef5ab1..34ddd57 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -21,15 +21,16 @@ + */ + + #include "DVDDemux.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" +- + #include "threads/CriticalSection.h" + #include "threads/SystemClock.h" +- + #include + ++extern "C" { ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++} ++ + class CDVDDemuxFFmpeg; + class CURL; + +@@ -139,10 +140,6 @@ class CDVDDemuxFFmpeg : public CDVDDemux + + AVIOContext* m_ioContext; + +- DllAvFormat m_dllAvFormat; +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- + double m_iCurrentPts; // used for stream length estimation + bool m_bMatroska; + bool m_bAVI; +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +index 7d0a732..6c8e6db 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +@@ -47,12 +47,12 @@ void CDemuxStreamPVRInternal::DisposeParser() + { + if (m_parser) + { +- m_parent->m_dllAvCodec.av_parser_close(m_parser); ++ av_parser_close(m_parser); + m_parser = NULL; + } + if (m_context) + { +- m_parent->m_dllAvCodec.avcodec_close(m_context); ++ avcodec_close(m_context); + m_context = NULL; + } + } +@@ -113,17 +113,8 @@ CDVDDemuxPVRClient::~CDVDDemuxPVRClient() + + bool CDVDDemuxPVRClient::Open(CDVDInputStream* pInput) + { +- if (!m_dllAvCodec.Load()) +- { +- CLog::Log(LOGWARNING, "%s could not load ffmpeg", __FUNCTION__); +- return false; +- } +- + Abort(); + +- // register codecs +- m_dllAvCodec.avcodec_register_all(); +- + m_pInput = pInput; + if (!g_PVRClients->GetPlayingClient(m_pvrClient)) + return false; +@@ -141,8 +132,6 @@ void CDVDDemuxPVRClient::Dispose() + } + + m_pInput = NULL; +- +- m_dllAvCodec.Unload(); + } + + void CDVDDemuxPVRClient::DisposeStream(int iStreamId) +@@ -192,7 +181,7 @@ void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt) + + if(pvr->m_context == NULL) + { +- AVCodec *codec = m_dllAvCodec.avcodec_find_decoder(st->codec); ++ AVCodec *codec = avcodec_find_decoder(st->codec); + if (codec == NULL) + { + CLog::Log(LOGERROR, "%s - can't find decoder", __FUNCTION__); +@@ -200,7 +189,7 @@ void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt) + return; + } + +- pvr->m_context = m_dllAvCodec.avcodec_alloc_context3(codec); ++ pvr->m_context = avcodec_alloc_context3(codec); + if(pvr->m_context == NULL) + { + CLog::Log(LOGERROR, "%s - can't allocate context", __FUNCTION__); +@@ -231,7 +220,7 @@ void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt) + + uint8_t *outbuf = NULL; + int outbuf_size = 0; +- int len = m_dllAvCodec.av_parser_parse2(pvr->m_parser ++ int len = av_parser_parse2(pvr->m_parser + , pvr->m_context, &outbuf, &outbuf_size + , pkt->pData, pkt->iSize + , (int64_t)(pkt->pts * DVD_TIME_BASE) +@@ -347,7 +336,7 @@ void CDVDDemuxPVRClient::RequestStreams() + if (!m_streams[i]) + { + st = new CDemuxStreamAudioPVRClient(this); +- st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId); ++ st->m_parser = av_parser_init(props.stream[i].iCodecId); + if(st->m_parser) + st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; + } +@@ -374,7 +363,7 @@ void CDVDDemuxPVRClient::RequestStreams() + if (!m_streams[i]) + { + st = new CDemuxStreamVideoPVRClient(this); +- st->m_parser = m_dllAvCodec.av_parser_init(props.stream[i].iCodecId); ++ st->m_parser = av_parser_init(props.stream[i].iCodecId); + if(st->m_parser) + st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; + } +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h +index 6ebf41e..e5f603c 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h +@@ -21,11 +21,13 @@ + + #include "DVDDemux.h" + #include +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +- + #include "pvr/addons/PVRClient.h" + ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++} ++ + class CDVDDemuxPVRClient; + struct PVR_STREAM_PROPERTIES; + +@@ -108,8 +110,6 @@ class CDVDDemuxPVRClient : public CDVDDemux + CDemuxStream* m_streams[MAX_STREAMS]; // maximum number of streams that ffmpeg can handle + boost::shared_ptr m_pvrClient; + +- DllAvCodec m_dllAvCodec; +- + private: + void RequestStreams(); + void ParsePacket(DemuxPacket* pPacket); +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp +index 811de23..ab298b2 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp +@@ -24,7 +24,10 @@ + #include "DVDDemuxUtils.h" + #include "DVDClock.h" + #include "utils/log.h" +-#include "DllAvCodec.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + + void CDVDDemuxUtils::FreeDemuxPacket(DemuxPacket* pPacket) + { +diff --git a/xbmc/cores/dvdplayer/DVDFileInfo.cpp b/xbmc/cores/dvdplayer/DVDFileInfo.cpp +index fd104d9..4670fe5 100644 +--- a/xbmc/cores/dvdplayer/DVDFileInfo.cpp ++++ b/xbmc/cores/dvdplayer/DVDFileInfo.cpp +@@ -46,9 +46,10 @@ + #include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h" + #include "DVDDemuxers/DVDDemuxVobsub.h" + +-#include "DllAvCodec.h" +-#include "DllSwScale.h" ++#include "libavcodec/avcodec.h" ++#include "libswscale/swscale.h" + #include "filesystem/File.h" ++#include "cores/FFmpeg.h" + #include "TextureCache.h" + #include "Util.h" + #include "utils/LangCodeExpander.h" +@@ -262,11 +263,8 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta + aspect = hint.aspect; + unsigned int nHeight = (unsigned int)((double)g_advancedSettings.GetThumbSize() / aspect); + +- DllSwScale dllSwScale; +- dllSwScale.Load(); +- + uint8_t *pOutBuf = new uint8_t[nWidth * nHeight * 4]; +- struct SwsContext *context = dllSwScale.sws_getContext(picture.iWidth, picture.iHeight, ++ struct SwsContext *context = sws_getContext(picture.iWidth, picture.iHeight, + PIX_FMT_YUV420P, nWidth, nHeight, PIX_FMT_BGRA, SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); + + if (context) +@@ -276,8 +274,8 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta + uint8_t *dst[] = { pOutBuf, 0, 0, 0 }; + int dstStride[] = { (int)nWidth*4, 0, 0, 0 }; + int orientation = DegreeToOrientation(hint.orientation); +- dllSwScale.sws_scale(context, src, srcStride, 0, picture.iHeight, dst, dstStride); +- dllSwScale.sws_freeContext(context); ++ sws_scale(context, src, srcStride, 0, picture.iHeight, dst, dstStride); ++ sws_freeContext(context); + + details.width = nWidth; + details.height = nHeight; +@@ -285,7 +283,6 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta + bOk = true; + } + +- dllSwScale.Unload(); + delete [] pOutBuf; + } + } +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index 3a37dee..3f2e0df 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -51,7 +51,7 @@ + #include "ApplicationMessenger.h" + #include "filesystem/File.h" + #include "pictures/Picture.h" +-#include "DllSwScale.h" ++#include "libswscale/swscale.h" + #ifdef HAS_VIDEO_PLAYBACK + #include "cores/VideoRenderers/RenderManager.h" + #endif +diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.h b/xbmc/cores/dvdplayer/DVDStreamInfo.h +index 8aa9b95..5b3ee04 100644 +--- a/xbmc/cores/dvdplayer/DVDStreamInfo.h ++++ b/xbmc/cores/dvdplayer/DVDStreamInfo.h +@@ -25,7 +25,10 @@ + #endif + + #include "DVDDemuxers/DVDDemux.h" +-#include "DllAvCodec.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++} + + class CDemuxStream; + +diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp +index dd80412..17c7d46 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.cpp ++++ b/xbmc/cores/omxplayer/OMXAudio.cpp +@@ -41,6 +41,10 @@ + #include "cores/AudioEngine/Utils/AEConvert.h" + #include "cores/AudioEngine/AEFactory.h" + ++extern "C" { ++#include "libavutil/crc.h" ++} ++ + using namespace std; + + static const uint16_t AC3Bitrates[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640}; +@@ -414,9 +418,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo + + Deinitialize(); + +- if(!m_dllAvUtil.Load()) +- return false; +- + m_HWDecode = bUseHWDecode; + m_Passthrough = bUsePassthrough; + +@@ -746,8 +747,6 @@ bool COMXAudio::Deinitialize() + m_extradata = NULL; + m_extrasize = 0; + +- m_dllAvUtil.Unload(); +- + while(!m_ampqueue.empty()) + m_ampqueue.pop_front(); + +@@ -1543,7 +1542,7 @@ unsigned int COMXAudio::SyncAC3(BYTE* pData, unsigned int iSize) + else crc_size = (framesize >> 1) + (framesize >> 3) - 1; + + if (crc_size <= iSize - skip) +- if(m_dllAvUtil.av_crc(m_dllAvUtil.av_crc_get_table(AV_CRC_16_ANSI), 0, &pData[2], crc_size * 2)) ++ if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &pData[2], crc_size * 2)) + continue; + + /* if we get here, we can sync */ +diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h +index 804bd2a..1c53ac5 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.h ++++ b/xbmc/cores/omxplayer/OMXAudio.h +@@ -36,12 +36,15 @@ + + #include "OMXClock.h" + #include "OMXCore.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" + #include "PCMRemap.h" + + #include "threads/CriticalSection.h" + ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++} ++ + #define AUDIO_BUFFER_SECONDS 3 + #define VIS_PACKET_SIZE 512 + +@@ -164,7 +167,6 @@ class COMXAudio + COMXCoreTunel m_omx_tunnel_decoder; + COMXCoreTunel m_omx_tunnel_splitter_analog; + COMXCoreTunel m_omx_tunnel_splitter_hdmi; +- DllAvUtil m_dllAvUtil; + + static void CheckOutputBufferSize(void **buffer, int *oldSize, int newSize); + CCriticalSection m_critSection; +diff --git a/xbmc/cores/omxplayer/OMXAudioCodec.h b/xbmc/cores/omxplayer/OMXAudioCodec.h +index 04a4574..59727e6 100644 +--- a/xbmc/cores/omxplayer/OMXAudioCodec.h ++++ b/xbmc/cores/omxplayer/OMXAudioCodec.h +@@ -26,7 +26,7 @@ + #include "config.h" + #endif + #include +-#include "DllAvCodec.h" ++#include "libavcodec/avcodec.h" + + struct AVStream; + +diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp +index 5503a0e..dd4c11f 100644 +--- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp ++++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp +@@ -44,7 +44,7 @@ COMXAudioCodecOMX::COMXAudioCodecOMX() + + COMXAudioCodecOMX::~COMXAudioCodecOMX() + { +- m_dllAvUtil.av_free(m_pBufferOutput); ++ av_free(m_pBufferOutput); + m_pBufferOutput = NULL; + m_iBufferOutputAlloced = 0; + Dispose(); +@@ -55,12 +55,7 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) + AVCodec* pCodec; + m_bOpenedCodec = false; + +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwResample.Load()) +- return false; +- +- m_dllAvCodec.avcodec_register_all(); +- +- pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); ++ pCodec = avcodec_find_decoder(hints.codec); + if (!pCodec) + { + CLog::Log(LOGDEBUG,"COMXAudioCodecOMX::Open() Unable to find codec %d", hints.codec); +@@ -68,7 +63,7 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) + } + + m_bFirstFrame = true; +- m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec); ++ m_pCodecContext = avcodec_alloc_context3(pCodec); + m_pCodecContext->debug_mv = 0; + m_pCodecContext->debug = 0; + m_pCodecContext->workaround_bugs = 1; +@@ -89,18 +84,18 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) + if( hints.extradata && hints.extrasize > 0 ) + { + m_pCodecContext->extradata_size = hints.extrasize; +- m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); ++ m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); + } + +- if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) ++ if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) + { + CLog::Log(LOGDEBUG,"COMXAudioCodecOMX::Open() Unable to open codec"); + Dispose(); + return false; + } + +- m_pFrame1 = m_dllAvCodec.avcodec_alloc_frame(); ++ m_pFrame1 = avcodec_alloc_frame(); + m_bOpenedCodec = true; + m_iSampleFormat = AV_SAMPLE_FMT_NONE; + m_desiredSampleFormat = m_pCodecContext->sample_fmt == AV_SAMPLE_FMT_S16 ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLTP; +@@ -109,26 +104,22 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) + + void COMXAudioCodecOMX::Dispose() + { +- if (m_pFrame1) m_dllAvUtil.av_free(m_pFrame1); ++ if (m_pFrame1) av_free(m_pFrame1); + m_pFrame1 = NULL; + + if (m_pConvert) +- m_dllSwResample.swr_free(&m_pConvert); ++ swr_free(&m_pConvert); + + if (m_pCodecContext) + { +- if (m_pCodecContext->extradata) m_dllAvUtil.av_free(m_pCodecContext->extradata); ++ if (m_pCodecContext->extradata) av_free(m_pCodecContext->extradata); + m_pCodecContext->extradata = NULL; +- if (m_bOpenedCodec) m_dllAvCodec.avcodec_close(m_pCodecContext); ++ if (m_bOpenedCodec) avcodec_close(m_pCodecContext); + m_bOpenedCodec = false; +- m_dllAvUtil.av_free(m_pCodecContext); ++ av_free(m_pCodecContext); + m_pCodecContext = NULL; + } + +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); +- m_dllSwResample.Unload(); +- + m_bGotFrame = false; + } + +@@ -139,10 +130,10 @@ int COMXAudioCodecOMX::Decode(BYTE* pData, int iSize) + + AVPacket avpkt; + m_bGotFrame = false; +- m_dllAvCodec.av_init_packet(&avpkt); ++ av_init_packet(&avpkt); + avpkt.data = pData; + avpkt.size = iSize; +- iBytesUsed = m_dllAvCodec.avcodec_decode_audio4( m_pCodecContext ++ iBytesUsed = avcodec_decode_audio4( m_pCodecContext + , m_pFrame1 + , &got_frame + , &avpkt); +@@ -176,15 +167,15 @@ int COMXAudioCodecOMX::GetData(BYTE** dst) + return 0; + int inLineSize, outLineSize; + /* input audio is aligned */ +- int inputSize = m_dllAvUtil.av_samples_get_buffer_size(&inLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_pCodecContext->sample_fmt, 0); ++ int inputSize = av_samples_get_buffer_size(&inLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_pCodecContext->sample_fmt, 0); + /* output audio will be packed */ +- int outputSize = m_dllAvUtil.av_samples_get_buffer_size(&outLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1); ++ int outputSize = av_samples_get_buffer_size(&outLineSize, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1); + bool cont = !m_pFrame1->data[1] || (m_pFrame1->data[1] == m_pFrame1->data[0] + inLineSize && inLineSize == outLineSize && inLineSize * m_pCodecContext->channels == inputSize); + + if (m_iBufferOutputAlloced < outputSize) + { +- m_dllAvUtil.av_free(m_pBufferOutput); +- m_pBufferOutput = (BYTE*)m_dllAvUtil.av_malloc(outputSize + FF_INPUT_BUFFER_PADDING_SIZE); ++ av_free(m_pBufferOutput); ++ m_pBufferOutput = (BYTE*)av_malloc(outputSize + FF_INPUT_BUFFER_PADDING_SIZE); + m_iBufferOutputAlloced = outputSize; + } + *dst = m_pBufferOutput; +@@ -194,21 +185,21 @@ int COMXAudioCodecOMX::GetData(BYTE** dst) + { + if(m_pConvert && (m_pCodecContext->sample_fmt != m_iSampleFormat || m_channels != m_pCodecContext->channels)) + { +- m_dllSwResample.swr_free(&m_pConvert); ++ swr_free(&m_pConvert); + m_channels = m_pCodecContext->channels; + } + + if(!m_pConvert) + { + m_iSampleFormat = m_pCodecContext->sample_fmt; +- m_pConvert = m_dllSwResample.swr_alloc_set_opts(NULL, +- m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels), ++ m_pConvert = swr_alloc_set_opts(NULL, ++ av_get_default_channel_layout(m_pCodecContext->channels), + m_desiredSampleFormat, m_pCodecContext->sample_rate, +- m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels), ++ av_get_default_channel_layout(m_pCodecContext->channels), + m_pCodecContext->sample_fmt, m_pCodecContext->sample_rate, + 0, NULL); + +- if(!m_pConvert || m_dllSwResample.swr_init(m_pConvert) < 0) ++ if(!m_pConvert || swr_init(m_pConvert) < 0) + { + CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to initialise convert format %d to %d", m_pCodecContext->sample_fmt, m_desiredSampleFormat); + return 0; +@@ -217,8 +208,8 @@ int COMXAudioCodecOMX::GetData(BYTE** dst) + + /* use unaligned flag to keep output packed */ + uint8_t *out_planes[m_pCodecContext->channels]; +- if(m_dllAvUtil.av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 || +- m_dllSwResample.swr_convert(m_pConvert, out_planes, m_pFrame1->nb_samples, (const uint8_t **)m_pFrame1->data, m_pFrame1->nb_samples) < 0) ++ if(av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 || ++ swr_convert(m_pConvert, out_planes, m_pFrame1->nb_samples, (const uint8_t **)m_pFrame1->data, m_pFrame1->nb_samples) < 0) + { + CLog::Log(LOGERROR, "COMXAudioCodecOMX::Decode - Unable to convert format %d to %d", (int)m_pCodecContext->sample_fmt, m_desiredSampleFormat); + outputSize = 0; +@@ -235,8 +226,8 @@ int COMXAudioCodecOMX::GetData(BYTE** dst) + { + /* copy to a contiguous buffer */ + uint8_t *out_planes[m_pCodecContext->channels]; +- if (m_dllAvUtil.av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 || +- m_dllAvUtil.av_samples_copy(out_planes, m_pFrame1->data, 0, 0, m_pFrame1->nb_samples, m_pCodecContext->channels, m_desiredSampleFormat) < 0 ) ++ if (av_samples_fill_arrays(out_planes, NULL, m_pBufferOutput, m_pCodecContext->channels, m_pFrame1->nb_samples, m_desiredSampleFormat, 1) < 0 || ++ av_samples_copy(out_planes, m_pFrame1->data, 0, 0, m_pFrame1->nb_samples, m_pCodecContext->channels, m_desiredSampleFormat) < 0 ) + { + outputSize = 0; + } +@@ -253,7 +244,7 @@ int COMXAudioCodecOMX::GetData(BYTE** dst) + + void COMXAudioCodecOMX::Reset() + { +- if (m_pCodecContext) m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); ++ if (m_pCodecContext) avcodec_flush_buffers(m_pCodecContext); + m_bGotFrame = false; + } + +@@ -302,7 +293,7 @@ uint64_t COMXAudioCodecOMX::GetChannelMap() + else + { + CLog::Log(LOGINFO, "COMXAudioCodecOMX::GetChannelMap - FFmpeg reported %d channels, but the layout contains %d ignoring", m_pCodecContext->channels, bits); +- layout = m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels); ++ layout = av_get_default_channel_layout(m_pCodecContext->channels); + } + return layout; + } +diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.h b/xbmc/cores/omxplayer/OMXAudioCodecOMX.h +index 343465c..edfcf31 100644 +--- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.h ++++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.h +@@ -21,10 +21,13 @@ + */ + + #include "cores/AudioEngine/Utils/AEAudioFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvFormat.h" +-#include "DllAvUtil.h" +-#include "DllSwResample.h" ++ ++extern "C" { ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++#include "libavutil/avutil.h" ++#include "libswresample/swresample.h" ++} + + #include "DVDStreamInfo.h" + #include "linux/PlatformDefs.h" +@@ -63,7 +66,4 @@ class COMXAudioCodecOMX + + bool m_bFirstFrame; + bool m_bGotFrame; +- DllAvCodec m_dllAvCodec; +- DllAvUtil m_dllAvUtil; +- DllSwResample m_dllSwResample; + }; +diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp +index 0b80be5..502df4a 100644 +--- a/xbmc/cores/omxplayer/OMXPlayer.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayer.cpp +@@ -86,7 +86,7 @@ + #include "ApplicationMessenger.h" + #include "filesystem/File.h" + #include "pictures/Picture.h" +-#include "DllSwScale.h" ++#include "libswscale/swscale.h" + #ifdef HAS_VIDEO_PLAYBACK + #include "cores/VideoRenderers/RenderManager.h" + #endif +diff --git a/xbmc/linux/OMXCore.h b/xbmc/linux/OMXCore.h +index 54d35aa..1b24fc1 100644 +--- a/xbmc/linux/OMXCore.h ++++ b/xbmc/linux/OMXCore.h +@@ -48,7 +48,7 @@ + (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \ + (a).nVersion.s.nStep = OMX_VERSION_STEP + +-#include "DllAvFormat.h" ++#include "libavformat/avformat.h" + + #define OMX_MAX_PORTS 10 + +diff --git a/xbmc/music/karaoke/karaokevideobackground.cpp b/xbmc/music/karaoke/karaokevideobackground.cpp +index 8652197..ef08896 100644 +--- a/xbmc/music/karaoke/karaokevideobackground.cpp ++++ b/xbmc/music/karaoke/karaokevideobackground.cpp +@@ -24,15 +24,19 @@ + #include "guilib/Texture.h" + #include "guilib/GUITexture.h" + #include "Application.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" +-#include "DllSwScale.h" + #include "filesystem/SpecialProtocol.h" + #include "settings/AdvancedSettings.h" + #include "settings/DisplaySettings.h" + #include "video/FFmpegVideoDecoder.h" + #include "system.h" ++#include "utils/log.h" ++ ++extern "C" { ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++#include "libswscale/swscale.h" ++} + + KaraokeVideoBackground::KaraokeVideoBackground() + { +diff --git a/xbmc/pictures/Picture.cpp b/xbmc/pictures/Picture.cpp +index 9366414..384f2ce 100644 +--- a/xbmc/pictures/Picture.cpp ++++ b/xbmc/pictures/Picture.cpp +@@ -30,13 +30,17 @@ + #include "filesystem/File.h" + #include "utils/log.h" + #include "utils/URIUtils.h" +-#include "DllSwScale.h" + #include "guilib/Texture.h" + #include "guilib/imagefactory.h" ++#include "cores/FFmpeg.h" + #if defined(HAS_OMXPLAYER) + #include "cores/omxplayer/OMXImage.h" + #endif + ++extern "C" { ++#include "libswscale/swscale.h" ++} ++ + using namespace XFILE; + + bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const CStdString &thumbFile) +@@ -230,9 +234,7 @@ void CPicture::GetScale(unsigned int width, unsigned int height, unsigned int &o + bool CPicture::ScaleImage(uint8_t *in_pixels, unsigned int in_width, unsigned int in_height, unsigned int in_pitch, + uint8_t *out_pixels, unsigned int out_width, unsigned int out_height, unsigned int out_pitch) + { +- DllSwScale dllSwScale; +- dllSwScale.Load(); +- struct SwsContext *context = dllSwScale.sws_getContext(in_width, in_height, PIX_FMT_BGRA, ++ struct SwsContext *context = sws_getContext(in_width, in_height, PIX_FMT_BGRA, + out_width, out_height, PIX_FMT_BGRA, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); + +@@ -243,8 +245,8 @@ bool CPicture::ScaleImage(uint8_t *in_pixels, unsigned int in_width, unsigned in + + if (context) + { +- dllSwScale.sws_scale(context, src, srcStride, 0, in_height, dst, dstStride); +- dllSwScale.sws_freeContext(context); ++ sws_scale(context, src, srcStride, 0, in_height, dst, dstStride); ++ sws_freeContext(context); + return true; + } + return false; +diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp +index 80b4a22..0f19376 100644 +--- a/xbmc/utils/BitstreamConverter.cpp ++++ b/xbmc/utils/BitstreamConverter.cpp +@@ -18,6 +18,9 @@ + * + */ + ++#include "utils/log.h" ++#include "assert.h" ++ + #ifndef UINT16_MAX + #define UINT16_MAX (65535U) + #endif +@@ -285,8 +288,6 @@ CBitstreamConverter::CBitstreamConverter() + m_extradata = NULL; + m_extrasize = 0; + m_convert_3byteTo4byteNALSize = false; +- m_dllAvUtil = NULL; +- m_dllAvFormat = NULL; + m_convert_bytestream = false; + m_sps_pps_context.sps_pps_data = NULL; + } +@@ -315,12 +316,8 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + if ( in_extradata[0] == 1 ) + { + CLog::Log(LOGINFO, "CBitstreamConverter::Open bitstream to annexb init"); +- m_dllAvUtil = new DllAvUtil; +- if (!m_dllAvUtil->Load()) +- return false; +- + m_extrasize = in_extrasize; +- m_extradata = (uint8_t*)m_dllAvUtil->av_malloc(in_extrasize); ++ m_extradata = (uint8_t*)av_malloc(in_extrasize); + memcpy(m_extradata, in_extradata, in_extrasize); + m_convert_bitstream = BitstreamConvertInit(m_extradata, m_extrasize); + return true; +@@ -328,10 +325,6 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + } + else + { +- m_dllAvUtil = new DllAvUtil; +- if (!m_dllAvUtil->Load()) +- return false; +- + // valid avcC atom data always starts with the value 1 (version) + if ( in_extradata[0] != 1 ) + { +@@ -341,12 +334,8 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init"); + // video content is from x264 or from bytestream h264 (AnnexB format) + // NAL reformating to bitstream format needed +- m_dllAvFormat = new DllAvFormat; +- if (!m_dllAvFormat->Load()) +- return false; +- + AVIOContext *pb; +- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if (avio_open_dyn_buf(&pb) < 0) + return false; + m_convert_bytestream = true; + // create a valid avcC atom data from ffmpeg's extradata +@@ -354,13 +343,13 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + // unhook from ffmpeg's extradata + in_extradata = NULL; + // extract the avcC atom data into extradata then write it into avcCData for VDADecoder +- in_extrasize = m_dllAvFormat->avio_close_dyn_buf(pb, &in_extradata); ++ in_extrasize = avio_close_dyn_buf(pb, &in_extradata); + // make a copy of extradata contents +- m_extradata = (uint8_t *)m_dllAvUtil->av_malloc(in_extrasize); ++ m_extradata = (uint8_t *)av_malloc(in_extrasize); + memcpy(m_extradata, in_extradata, in_extrasize); + m_extrasize = in_extrasize; + // done with the converted extradata, we MUST free using av_free +- m_dllAvUtil->av_free(in_extradata); ++ av_free(in_extradata); + return true; + } + else +@@ -376,21 +365,17 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init 3 byte to 4 byte nal"); + // video content is from so silly encoder that think 3 byte NAL sizes + // are valid, setup to convert 3 byte NAL sizes to 4 byte. +- m_dllAvFormat = new DllAvFormat; +- if (!m_dllAvFormat->Load()) +- return false; +- + in_extradata[4] = 0xFF; + m_convert_3byteTo4byteNALSize = true; + +- m_extradata = (uint8_t *)m_dllAvUtil->av_malloc(in_extrasize); ++ m_extradata = (uint8_t *)av_malloc(in_extrasize); + memcpy(m_extradata, in_extradata, in_extrasize); + m_extrasize = in_extrasize; + return true; + } + } + // valid avcC atom +- m_extradata = (uint8_t*)m_dllAvUtil->av_malloc(in_extrasize); ++ m_extradata = (uint8_t*)av_malloc(in_extrasize); + memcpy(m_extradata, in_extradata, in_extrasize); + m_extrasize = in_extrasize; + return true; +@@ -407,14 +392,14 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int + void CBitstreamConverter::Close(void) + { + if (m_sps_pps_context.sps_pps_data) +- m_dllAvUtil->av_free(m_sps_pps_context.sps_pps_data), m_sps_pps_context.sps_pps_data = NULL; ++ av_free(m_sps_pps_context.sps_pps_data), m_sps_pps_context.sps_pps_data = NULL; + + if (m_convertBuffer) +- m_dllAvUtil->av_free(m_convertBuffer), m_convertBuffer = NULL; ++ av_free(m_convertBuffer), m_convertBuffer = NULL; + m_convertSize = 0; + + if (m_extradata) +- m_dllAvUtil->av_free(m_extradata), m_extradata = NULL; ++ av_free(m_extradata), m_extradata = NULL; + m_extrasize = 0; + + m_inputSize = 0; +@@ -423,18 +408,13 @@ void CBitstreamConverter::Close(void) + m_convert_bitstream = false; + m_convert_bytestream = false; + m_convert_3byteTo4byteNALSize = false; +- +- if (m_dllAvUtil) +- delete m_dllAvUtil, m_dllAvUtil = NULL; +- if (m_dllAvFormat) +- delete m_dllAvFormat, m_dllAvFormat = NULL; + } + + bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) + { + if (m_convertBuffer) + { +- m_dllAvUtil->av_free(m_convertBuffer); ++ av_free(m_convertBuffer); + m_convertBuffer = NULL; + } + m_inputSize = 0; +@@ -487,7 +467,7 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) + { + if(m_convertBuffer) + { +- m_dllAvUtil->av_free(m_convertBuffer); ++ av_free(m_convertBuffer); + m_convertBuffer = NULL; + } + m_convertSize = 0; +@@ -495,25 +475,25 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) + // convert demuxer packet from bytestream (AnnexB) to bitstream + AVIOContext *pb; + +- if(m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if(avio_open_dyn_buf(&pb) < 0) + { + return false; + } + m_convertSize = avc_parse_nal_units(pb, pData, iSize); +- m_convertSize = m_dllAvFormat->avio_close_dyn_buf(pb, &m_convertBuffer); ++ m_convertSize = avio_close_dyn_buf(pb, &m_convertBuffer); + } + else if (m_convert_3byteTo4byteNALSize) + { + if(m_convertBuffer) + { +- m_dllAvUtil->av_free(m_convertBuffer); ++ av_free(m_convertBuffer); + m_convertBuffer = NULL; + } + m_convertSize = 0; + + // convert demuxer packet from 3 byte NAL sizes to 4 byte + AVIOContext *pb; +- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0) ++ if (avio_open_dyn_buf(&pb) < 0) + return false; + + uint32_t nal_size; +@@ -522,13 +502,13 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) + while (nal_start < end) + { + nal_size = BS_RB24(nal_start); +- m_dllAvFormat->avio_wb16(pb, nal_size); ++ avio_wb16(pb, nal_size); + nal_start += 3; +- m_dllAvFormat->avio_write(pb, nal_start, nal_size); ++ avio_write(pb, nal_start, nal_size); + nal_start += nal_size; + } + +- m_convertSize = m_dllAvFormat->avio_close_dyn_buf(pb, &m_convertBuffer); ++ m_convertSize = avio_close_dyn_buf(pb, &m_convertBuffer); + } + return true; + } +@@ -611,14 +591,16 @@ bool CBitstreamConverter::BitstreamConvertInit(void *in_extradata, int in_extras + total_size += unit_size + 4; + + if (total_size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE || +- (extradata + 2 + unit_size) > ((uint8_t*)in_extradata + in_extrasize)) { +- m_dllAvUtil->av_free(out); ++ (extradata + 2 + unit_size) > ((uint8_t*)in_extradata + in_extrasize)) ++ { ++ av_free(out); + return false; + } +- tmp = m_dllAvUtil->av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE); +- if (!tmp) { +- m_dllAvUtil->av_free(out); +- return false; ++ tmp = av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE); ++ if (!tmp) ++ { ++ av_free(out); ++ return false; + } + out = (uint8_t*)tmp; + memcpy(out + total_size - unit_size - 4, nalu_header, 4); +@@ -698,7 +680,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** + return true; + + fail: +- m_dllAvUtil->av_free(*poutbuf), *poutbuf = NULL; ++ av_free(*poutbuf), *poutbuf = NULL; + *poutbuf_size = 0; + return false; + } +@@ -715,7 +697,7 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf + void *tmp; + + *poutbuf_size += sps_pps_size + in_size + nal_header_size; +- tmp = m_dllAvUtil->av_realloc(*poutbuf, *poutbuf_size); ++ tmp = av_realloc(*poutbuf, *poutbuf_size); + if (!tmp) + return; + *poutbuf = (uint8_t*)tmp; +@@ -750,8 +732,8 @@ const int CBitstreamConverter::avc_parse_nal_units(AVIOContext *pb, const uint8_ + break; + + nal_end = avc_find_startcode(nal_start, end); +- m_dllAvFormat->avio_wb32(pb, nal_end - nal_start); +- m_dllAvFormat->avio_write(pb, nal_start, nal_end - nal_start); ++ avio_wb32(pb, nal_end - nal_start); ++ avio_write(pb, nal_start, nal_end - nal_start); + size += 4 + nal_end - nal_start; + nal_start = nal_end; + } +@@ -761,14 +743,14 @@ const int CBitstreamConverter::avc_parse_nal_units(AVIOContext *pb, const uint8_ + const int CBitstreamConverter::avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size) + { + AVIOContext *pb; +- int ret = m_dllAvFormat->avio_open_dyn_buf(&pb); ++ int ret = avio_open_dyn_buf(&pb); + if (ret < 0) + return ret; + + avc_parse_nal_units(pb, buf_in, *size); + +- m_dllAvUtil->av_freep(buf); +- *size = m_dllAvFormat->avio_close_dyn_buf(pb, buf); ++ av_freep(buf); ++ *size = avio_close_dyn_buf(pb, buf); + return 0; + } + +@@ -813,26 +795,26 @@ const int CBitstreamConverter::isom_write_avcc(AVIOContext *pb, const uint8_t *d + if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX) + assert(0); + +- m_dllAvFormat->avio_w8(pb, 1); /* version */ +- m_dllAvFormat->avio_w8(pb, sps[1]); /* profile */ +- m_dllAvFormat->avio_w8(pb, sps[2]); /* profile compat */ +- m_dllAvFormat->avio_w8(pb, sps[3]); /* level */ +- m_dllAvFormat->avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ +- m_dllAvFormat->avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ ++ avio_w8(pb, 1); /* version */ ++ avio_w8(pb, sps[1]); /* profile */ ++ avio_w8(pb, sps[2]); /* profile compat */ ++ avio_w8(pb, sps[3]); /* level */ ++ avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ ++ avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ + +- m_dllAvFormat->avio_wb16(pb, sps_size); +- m_dllAvFormat->avio_write(pb, sps, sps_size); ++ avio_wb16(pb, sps_size); ++ avio_write(pb, sps, sps_size); + if (pps) + { +- m_dllAvFormat->avio_w8(pb, 1); /* number of pps */ +- m_dllAvFormat->avio_wb16(pb, pps_size); +- m_dllAvFormat->avio_write(pb, pps, pps_size); ++ avio_w8(pb, 1); /* number of pps */ ++ avio_wb16(pb, pps_size); ++ avio_write(pb, pps, pps_size); + } +- m_dllAvUtil->av_free(start); ++ av_free(start); + } + else + { +- m_dllAvFormat->avio_write(pb, data, len); ++ avio_write(pb, data, len); + } + } + return 0; +diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h +index d3ad346..c479a64 100644 +--- a/xbmc/utils/BitstreamConverter.h ++++ b/xbmc/utils/BitstreamConverter.h +@@ -22,10 +22,13 @@ + #define _BITSTREAMCONVERTER_H_ + + #include +-#include "DllAvUtil.h" +-#include "DllAvFormat.h" +-#include "DllAvFilter.h" +-#include "DllAvCodec.h" ++ ++extern "C" { ++#include "libavutil/avutil.h" ++#include "libavformat/avformat.h" ++#include "libavfilter/avfilter.h" ++#include "libavcodec/avcodec.h" ++} + + typedef struct { + int writer_le; +@@ -200,8 +203,6 @@ class CBitstreamConverter + int m_extrasize; + bool m_convert_3byteTo4byteNALSize; + bool m_convert_bytestream; +- DllAvUtil *m_dllAvUtil; +- DllAvFormat *m_dllAvFormat; + AVCodecID m_codec; + }; + +diff --git a/xbmc/video/FFmpegVideoDecoder.cpp b/xbmc/video/FFmpegVideoDecoder.cpp +index 1557812..1df859f 100644 +--- a/xbmc/video/FFmpegVideoDecoder.cpp ++++ b/xbmc/video/FFmpegVideoDecoder.cpp +@@ -19,14 +19,16 @@ + */ + + #include "system.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" +-#include "DllSwScale.h" + #include "guilib/Texture.h" + + #include "FFmpegVideoDecoder.h" + ++extern "C" { ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" ++#include "libswscale/swscale.h" ++} + + FFmpegVideoDecoder::FFmpegVideoDecoder() + { +@@ -35,61 +37,39 @@ FFmpegVideoDecoder::FFmpegVideoDecoder() + m_pCodec = 0; + m_pFrame = 0; + m_pFrameRGB = 0; +- +- m_dllAvFormat = new DllAvFormat(); +- m_dllAvCodec = new DllAvCodec(); +- m_dllAvUtil = new DllAvUtil(); +- m_dllSwScale = new DllSwScale(); + } + + FFmpegVideoDecoder::~FFmpegVideoDecoder() + { + close(); +- +- delete m_dllAvFormat; +- delete m_dllAvCodec; +- delete m_dllAvUtil; +- delete m_dllSwScale; + } + + void FFmpegVideoDecoder::close() + { + // Free the YUV frame + if ( m_pFrame ) +- m_dllAvUtil->av_free( m_pFrame ); ++ av_free( m_pFrame ); + + // Free the RGB frame + if ( m_pFrameRGB ) + { +- m_dllAvCodec->avpicture_free( m_pFrameRGB ); +- m_dllAvUtil->av_free( m_pFrameRGB ); ++ avpicture_free( m_pFrameRGB ); ++ av_free( m_pFrameRGB ); + } + + // Close the codec + if ( m_pCodecCtx ) +- m_dllAvCodec->avcodec_close( m_pCodecCtx ); ++ avcodec_close( m_pCodecCtx ); + + // Close the video file + if ( m_pFormatCtx ) +- m_dllAvFormat->avformat_close_input( &m_pFormatCtx ); ++ avformat_close_input( &m_pFormatCtx ); + + m_pFormatCtx = 0; + m_pCodecCtx = 0; + m_pCodec = 0; + m_pFrame = 0; + m_pFrameRGB = 0; +- +- if ( m_dllAvCodec->IsLoaded() ) +- m_dllAvCodec->Unload(); +- +- if ( m_dllAvUtil->IsLoaded() ) +- m_dllAvUtil->Unload(); +- +- if ( m_dllSwScale->IsLoaded() ) +- m_dllSwScale->Unload(); +- +- if ( m_dllAvFormat->IsLoaded() ) +- m_dllAvFormat->Unload(); + } + + bool FFmpegVideoDecoder::isOpened() const +@@ -108,7 +88,7 @@ double FFmpegVideoDecoder::getDuration() const + double FFmpegVideoDecoder::getFramesPerSecond() const + { + #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) +- return m_pFormatCtx ? av_q2d( m_dllAvFormat->av_stream_get_r_frame_rate( m_pFormatCtx->streams[ m_videoStream ] ) ) : 0.0; ++ return m_pFormatCtx ? av_q2d( av_stream_get_r_frame_rate( m_pFormatCtx->streams[ m_videoStream ] ) ) : 0.0; + #else + return m_pFormatCtx ? av_q2d( m_pFormatCtx->streams[ m_videoStream ]->r_frame_rate ) : 0.0; + #endif +@@ -161,17 +141,8 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + // See http://dranger.com/ffmpeg/tutorial01.html + close(); + +- if ( !m_dllAvUtil->Load() || !m_dllAvCodec->Load() || !m_dllSwScale->Load() || !m_dllAvFormat->Load() ) +- { +- m_errorMsg = "Failed to load FFMpeg libraries"; +- return false; +- } +- +- m_dllAvCodec->avcodec_register_all(); +- m_dllAvFormat->av_register_all(); +- + // Open the video file +- if ( m_dllAvFormat->avformat_open_input( &m_pFormatCtx, filename.c_str(), NULL, NULL ) < 0 ) ++ if ( avformat_open_input( &m_pFormatCtx, filename.c_str(), NULL, NULL ) < 0 ) + { + m_errorMsg = "Could not open the video file"; + close(); +@@ -179,7 +150,7 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + } + + // Retrieve the stream information +- if ( m_dllAvFormat->avformat_find_stream_info( m_pFormatCtx, 0 ) < 0 ) ++ if ( avformat_find_stream_info( m_pFormatCtx, 0 ) < 0 ) + { + m_errorMsg = "Could not find the stream information"; + close(); +@@ -209,7 +180,7 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + m_pCodecCtx = m_pFormatCtx->streams[ m_videoStream ]->codec; + + // Find the decoder for the video stream +- m_pCodec = m_dllAvCodec->avcodec_find_decoder( m_pCodecCtx->codec_id ); ++ m_pCodec = avcodec_find_decoder( m_pCodecCtx->codec_id ); + + if ( m_pCodec == NULL ) + { +@@ -219,7 +190,7 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + } + + // Open the codec +- if ( m_dllAvCodec->avcodec_open2( m_pCodecCtx, m_pCodec, 0 ) < 0 ) ++ if ( avcodec_open2( m_pCodecCtx, m_pCodec, 0 ) < 0 ) + { + m_errorMsg = "Could not open the video decoder"; + close(); +@@ -227,7 +198,7 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + } + + // Allocate video frames +- m_pFrame = m_dllAvCodec->avcodec_alloc_frame(); ++ m_pFrame = avcodec_alloc_frame(); + + if ( !m_pFrame ) + { +@@ -245,10 +216,10 @@ bool FFmpegVideoDecoder::seek( double time ) + // Convert the frame number into time stamp + int64_t timestamp = (int64_t) (time * AV_TIME_BASE * av_q2d( m_pFormatCtx->streams[ m_videoStream ]->time_base )); + +- if ( m_dllAvFormat->av_seek_frame( m_pFormatCtx, m_videoStream, timestamp, AVSEEK_FLAG_ANY ) < 0 ) ++ if ( av_seek_frame( m_pFormatCtx, m_videoStream, timestamp, AVSEEK_FLAG_ANY ) < 0 ) + return false; + +- m_dllAvCodec->avcodec_flush_buffers( m_pCodecCtx ); ++ avcodec_flush_buffers( m_pCodecCtx ); + return true; + } + +@@ -263,21 +234,21 @@ bool FFmpegVideoDecoder::nextFrame( CBaseTexture * texture ) + { + if ( m_pFrameRGB ) + { +- m_dllAvCodec->avpicture_free( m_pFrameRGB ); +- m_dllAvUtil->av_free( m_pFrameRGB ); ++ avpicture_free( m_pFrameRGB ); ++ av_free( m_pFrameRGB ); + } + + m_frameRGBwidth = texture->GetWidth(); + m_frameRGBheight = texture->GetHeight(); + + // Allocate the conversion frame and relevant picture +- m_pFrameRGB = (AVPicture*)m_dllAvUtil->av_mallocz(sizeof(AVPicture)); ++ m_pFrameRGB = (AVPicture*)av_mallocz(sizeof(AVPicture)); + + if ( !m_pFrameRGB ) + return false; + + // Due to a bug in swsscale we need to allocate one extra line of data +- if ( m_dllAvCodec->avpicture_alloc( m_pFrameRGB, PIX_FMT_RGB32, m_frameRGBwidth, m_frameRGBheight + 1 ) < 0 ) ++ if ( avpicture_alloc( m_pFrameRGB, PIX_FMT_RGB32, m_frameRGBwidth, m_frameRGBheight + 1 ) < 0 ) + return false; + } + +@@ -287,13 +258,13 @@ bool FFmpegVideoDecoder::nextFrame( CBaseTexture * texture ) + while ( true ) + { + // Read a frame +- if ( m_dllAvFormat->av_read_frame( m_pFormatCtx, &packet ) < 0 ) ++ if ( av_read_frame( m_pFormatCtx, &packet ) < 0 ) + return false; // Frame read failed (e.g. end of stream) + + if ( packet.stream_index == m_videoStream ) + { + // Is this a packet from the video stream -> decode video frame +- m_dllAvCodec->avcodec_decode_video2( m_pCodecCtx, m_pFrame, &frameFinished, &packet ); ++ avcodec_decode_video2( m_pCodecCtx, m_pFrame, &frameFinished, &packet ); + + // Did we get a video frame? + if ( frameFinished ) +@@ -307,17 +278,17 @@ bool FFmpegVideoDecoder::nextFrame( CBaseTexture * texture ) + } + } + +- m_dllAvCodec->av_free_packet( &packet ); ++ av_free_packet( &packet ); + } + + // We got the video frame, render it into the picture buffer +- struct SwsContext * context = m_dllSwScale->sws_getContext( m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt, ++ struct SwsContext * context = sws_getContext( m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt, + m_frameRGBwidth, m_frameRGBheight, PIX_FMT_RGB32, SWS_FAST_BILINEAR, NULL, NULL, NULL ); + +- m_dllSwScale->sws_scale( context, m_pFrame->data, m_pFrame->linesize, 0, m_pCodecCtx->height, ++ sws_scale( context, m_pFrame->data, m_pFrame->linesize, 0, m_pCodecCtx->height, + m_pFrameRGB->data, m_pFrameRGB->linesize ); +- m_dllSwScale->sws_freeContext( context ); +- m_dllAvCodec->av_free_packet( &packet ); ++ sws_freeContext( context ); ++ av_free_packet( &packet ); + + // And into the texture + texture->Update( m_frameRGBwidth, m_frameRGBheight, m_frameRGBwidth * 4, XB_FMT_A8R8G8B8, m_pFrameRGB->data[0], false ); +diff --git a/xbmc/video/FFmpegVideoDecoder.h b/xbmc/video/FFmpegVideoDecoder.h +index 718d487..5ce3f72 100644 +--- a/xbmc/video/FFmpegVideoDecoder.h ++++ b/xbmc/video/FFmpegVideoDecoder.h +@@ -24,15 +24,14 @@ + #include "utils/StdString.h" + + class CBaseTexture; +-class m_dllAvFormat; +-class m_dllAvCodec; +-class m_dllAvUtil; +-class m_dllSwScale; + ++extern "C" { + struct AVFormatContext; + struct AVCodecContext; + struct AVCodec; + struct AVFrame; ++struct AVPicture; ++} + + /** + * A simple FFMpeg-based background video decoder. +@@ -141,10 +140,6 @@ class FFmpegVideoDecoder + private: + bool readFrame( int frame ); + +- DllAvFormat *m_dllAvFormat; +- DllAvCodec *m_dllAvCodec; +- DllAvUtil *m_dllAvUtil; +- DllSwScale *m_dllSwScale; + AVFormatContext *m_pFormatCtx; + AVCodecContext *m_pCodecCtx; + AVCodec *m_pCodec; +-- +1.9.3 + + +From 064e8e9528917b1d861ca485020d4d12c9c7fa0b Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 24 Jan 2014 13:15:08 +0100 +Subject: [PATCH 004/122] add ffmpeg lock manager todo: refactor to own file + +--- + xbmc/Application.cpp | 16 +++++++++ + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 38 +++++++++++++++++++++- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 7 +--- + 3 files changed, 54 insertions(+), 7 deletions(-) + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index b7eaca3..4f626c6 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -348,6 +348,8 @@ + #include "utils/AMLUtils.h" + #endif + ++#include "lib/ffmpeg.h" ++ + using namespace std; + using namespace ADDON; + using namespace XFILE; +@@ -787,6 +789,17 @@ bool CApplication::Create() + CEnvironment::setenv("OS", "win32"); + #endif + ++ // register ffmpeg lockmanager callback ++ av_lockmgr_register(&ffmpeg_lockmgr_cb); ++ // register avcodec ++ avcodec_register_all(); ++ // register avformat ++ av_register_all(); ++ // register avfilter ++ avfilter_register_all(); ++ // set avutil callback ++ av_log_set_callback(ff_avutil_log); ++ + g_powerManager.Initialize(); + + // Load the AudioEngine before settings as they need to query the engine +@@ -3615,6 +3628,9 @@ void CApplication::Stop(int exitCode) + CAEFactory::Shutdown(); + CAEFactory::UnLoadEngine(); + ++ // unregister ffmpeg lock manager call back ++ av_lockmgr_register(NULL); ++ + CLog::Log(LOGNOTICE, "stopped"); + } + catch (...) +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 03fe65c..bce0e73 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -106,7 +106,7 @@ void ff_avutil_log(void* ptr, int level, const char* format, va_list va) + + AVClass* avc= ptr ? *(AVClass**)ptr : NULL; + +- if(level >= AV_LOG_DEBUG && ++ if(level >= AV_LOG_DEBUG && + (g_advancedSettings.m_extraLogLevels & LOGFFMPEG) == 0) + return; + else if(g_advancedSettings.m_logLevel <= LOG_LEVEL_NORMAL) +@@ -165,6 +165,42 @@ static int interrupt_cb(void* ctx) + return 0; + } + ++/* callback for the ffmpeg lock manager */ ++int ffmpeg_lockmgr_cb(void **mutex, enum AVLockOp operation) ++{ ++ CSharedSection **lock = (CSharedSection **)mutex; ++ ++ switch (operation) ++ { ++ case AV_LOCK_CREATE: ++ { ++ *lock = NULL; ++ *lock = new CSharedSection(); ++ if (*lock == NULL) ++ return 1; ++ break; ++ } ++ case AV_LOCK_OBTAIN: ++ (*lock)->lock(); ++ break; ++ ++ case AV_LOCK_RELEASE: ++ (*lock)->unlock(); ++ break; ++ ++ case AV_LOCK_DESTROY: ++ { ++ delete *lock; ++ *lock = NULL; ++ break; ++ } ++ ++ default: ++ return 1; ++ } ++ return 0; ++} ++ + //////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + /* +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index 34ddd57..b11da56 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -24,12 +24,7 @@ + #include "threads/CriticalSection.h" + #include "threads/SystemClock.h" + #include +- +-extern "C" { +-#include "libavformat/avformat.h" +-#include "libavcodec/avcodec.h" +-#include "libavutil/avutil.h" +-} ++#include "lib/ffmpeg.h" + + class CDVDDemuxFFmpeg; + class CURL; +-- +1.9.3 + + +From e859285d354fbbfc2adfedcb1e434e665bf7ac62 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 25 Jan 2014 12:26:42 +0100 +Subject: [PATCH 005/122] ffmpeg: move callbacks into separate file + +--- + xbmc/Application.cpp | 2 +- + xbmc/cores/FFmpeg.cpp | 126 +++++++++++++++++++++ + xbmc/cores/FFmpeg.h | 75 ++++++++++++ + xbmc/cores/Makefile.in | 1 + + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 100 +--------------- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 5 +- + 6 files changed, 208 insertions(+), 101 deletions(-) + create mode 100644 xbmc/cores/FFmpeg.cpp + create mode 100644 xbmc/cores/FFmpeg.h + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 4f626c6..0f649fc 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -348,7 +348,7 @@ + #include "utils/AMLUtils.h" + #endif + +-#include "lib/ffmpeg.h" ++#include "cores/FFmpeg.h" + + using namespace std; + using namespace ADDON; +diff --git a/xbmc/cores/FFmpeg.cpp b/xbmc/cores/FFmpeg.cpp +new file mode 100644 +index 0000000..91d36e6 +--- /dev/null ++++ b/xbmc/cores/FFmpeg.cpp +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program 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, or (at your option) ++ * any later version. ++ * ++ * This Program 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 XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "cores/FFmpeg.h" ++#include "utils/log.h" ++#include "threads/SharedSection.h" ++#include "utils/StdString.h" ++#include "utils/StringUtils.h" ++#include "threads/Thread.h" ++#include "settings/AdvancedSettings.h" ++#include ++ ++/* callback for the ffmpeg lock manager */ ++int ffmpeg_lockmgr_cb(void **mutex, enum AVLockOp operation) ++{ ++ CSharedSection **lock = (CSharedSection **)mutex; ++ ++ switch (operation) ++ { ++ case AV_LOCK_CREATE: ++ { ++ *lock = NULL; ++ *lock = new CSharedSection(); ++ if (*lock == NULL) ++ return 1; ++ break; ++ } ++ case AV_LOCK_OBTAIN: ++ (*lock)->lock(); ++ break; ++ ++ case AV_LOCK_RELEASE: ++ (*lock)->unlock(); ++ break; ++ ++ case AV_LOCK_DESTROY: ++ { ++ delete *lock; ++ *lock = NULL; ++ break; ++ } ++ ++ default: ++ return 1; ++ } ++ return 0; ++} ++ ++static CCriticalSection m_logSection; ++std::map g_logbuffer; ++ ++void ff_flush_avutil_log_buffers(void) ++{ ++ CSingleLock lock(m_logSection); ++ /* Loop through the logbuffer list and remove any blank buffers ++ If the thread using the buffer is still active, it will just ++ add a new buffer next time it writes to the log */ ++ std::map::iterator it; ++ for (it = g_logbuffer.begin(); it != g_logbuffer.end(); ) ++ if ((*it).second.empty()) ++ g_logbuffer.erase(it++); ++ else ++ ++it; ++} ++ ++void ff_avutil_log(void* ptr, int level, const char* format, va_list va) ++{ ++ CSingleLock lock(m_logSection); ++ uintptr_t threadId = (uintptr_t)CThread::GetCurrentThreadId(); ++ CStdString &buffer = g_logbuffer[threadId]; ++ ++ AVClass* avc= ptr ? *(AVClass**)ptr : NULL; ++ ++ if(level >= AV_LOG_DEBUG && ++ (g_advancedSettings.m_extraLogLevels & LOGFFMPEG) == 0) ++ return; ++ else if(g_advancedSettings.m_logLevel <= LOG_LEVEL_NORMAL) ++ return; ++ ++ int type; ++ switch(level) ++ { ++ case AV_LOG_INFO : type = LOGINFO; break; ++ case AV_LOG_ERROR : type = LOGERROR; break; ++ case AV_LOG_DEBUG : ++ default : type = LOGDEBUG; break; ++ } ++ ++ CStdString message = StringUtils::FormatV(format, va); ++ CStdString prefix = StringUtils::Format("ffmpeg[%X]: ", threadId); ++ if(avc) ++ { ++ if(avc->item_name) ++ prefix += CStdString("[") + avc->item_name(ptr) + "] "; ++ else if(avc->class_name) ++ prefix += CStdString("[") + avc->class_name + "] "; ++ } ++ ++ buffer += message; ++ int pos, start = 0; ++ while( (pos = buffer.find_first_of('\n', start)) >= 0 ) ++ { ++ if(pos>start) ++ CLog::Log(type, "%s%s", prefix.c_str(), buffer.substr(start, pos-start).c_str()); ++ start = pos+1; ++ } ++ buffer.erase(0, start); ++} ++ +diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h +new file mode 100644 +index 0000000..885c3b5 +--- /dev/null ++++ b/xbmc/cores/FFmpeg.h +@@ -0,0 +1,75 @@ ++#pragma once ++ ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program 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, or (at your option) ++ * any later version. ++ * ++ * This Program 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 XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++ ++#include "utils/CPUInfo.h" ++ ++extern "C" { ++#include "libswscale/swscale.h" ++#include "libavcodec/avcodec.h" ++#include "libavformat/avformat.h" ++#include "libavutil/avutil.h" ++#include "libavfilter/avfilter.h" ++#include "libpostproc/postprocess.h" ++} ++ ++inline int SwScaleCPUFlags() ++{ ++ unsigned int cpuFeatures = g_cpuInfo.GetCPUFeatures(); ++ int flags = 0; ++ ++ if (cpuFeatures & CPU_FEATURE_MMX) ++ flags |= SWS_CPU_CAPS_MMX; ++ if (cpuFeatures & CPU_FEATURE_MMX2) ++ flags |= SWS_CPU_CAPS_MMX2; ++ if (cpuFeatures & CPU_FEATURE_3DNOW) ++ flags |= SWS_CPU_CAPS_3DNOW; ++ if (cpuFeatures & CPU_FEATURE_ALTIVEC) ++ flags |= SWS_CPU_CAPS_ALTIVEC; ++ ++ return flags; ++} ++ ++inline int PPCPUFlags() ++{ ++ unsigned int cpuFeatures = g_cpuInfo.GetCPUFeatures(); ++ int flags = 0; ++ ++ if (cpuFeatures & CPU_FEATURE_MMX) ++ flags |= PP_CPU_CAPS_MMX; ++ if (cpuFeatures & CPU_FEATURE_MMX2) ++ flags |= PP_CPU_CAPS_MMX2; ++ if (cpuFeatures & CPU_FEATURE_3DNOW) ++ flags |= PP_CPU_CAPS_3DNOW; ++ if (cpuFeatures & CPU_FEATURE_ALTIVEC) ++ flags |= PP_CPU_CAPS_ALTIVEC; ++ ++ return flags; ++} ++ ++// callback used for locking ++int ffmpeg_lockmgr_cb(void **mutex, enum AVLockOp operation); ++ ++// callback used for logging ++void ff_avutil_log(void* ptr, int level, const char* format, va_list va); ++void ff_flush_avutil_log_buffers(void); ++ +diff --git a/xbmc/cores/Makefile.in b/xbmc/cores/Makefile.in +index 9c26adf..c77beeb 100644 +--- a/xbmc/cores/Makefile.in ++++ b/xbmc/cores/Makefile.in +@@ -1,4 +1,5 @@ + SRCS = DummyVideoPlayer.cpp ++SRCS += FFmpeg.cpp + + LIB = cores.a + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index bce0e73..7f7df15 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -50,6 +50,7 @@ + #include "utils/TimeUtils.h" + #include "utils/StringUtils.h" + #include "URL.h" ++#include "cores/FFmpeg.h" + + void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) + { +@@ -93,70 +94,6 @@ void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo) + strInfo = temp; + } + +-// these need to be put somewhere that are compiled, we should have some better place for it +- +-static CCriticalSection m_logSection; +-std::map g_logbuffer; +- +-void ff_avutil_log(void* ptr, int level, const char* format, va_list va) +-{ +- CSingleLock lock(m_logSection); +- uintptr_t threadId = (uintptr_t)CThread::GetCurrentThreadId(); +- CStdString &buffer = g_logbuffer[threadId]; +- +- AVClass* avc= ptr ? *(AVClass**)ptr : NULL; +- +- if(level >= AV_LOG_DEBUG && +- (g_advancedSettings.m_extraLogLevels & LOGFFMPEG) == 0) +- return; +- else if(g_advancedSettings.m_logLevel <= LOG_LEVEL_NORMAL) +- return; +- +- int type; +- switch(level) +- { +- case AV_LOG_INFO : type = LOGINFO; break; +- case AV_LOG_ERROR : type = LOGERROR; break; +- case AV_LOG_DEBUG : +- default : type = LOGDEBUG; break; +- } +- +- CStdString message = StringUtils::FormatV(format, va); +- CStdString prefix = StringUtils::Format("ffmpeg[%X]: ", threadId); +- if(avc) +- { +- if(avc->item_name) +- prefix += CStdString("[") + avc->item_name(ptr) + "] "; +- else if(avc->class_name) +- prefix += CStdString("[") + avc->class_name + "] "; +- } +- +- buffer += message; +- int pos, start = 0; +- while( (pos = buffer.find_first_of('\n', start)) >= 0 ) +- { +- if(pos>start) +- CLog::Log(type, "%s%s", prefix.c_str(), buffer.substr(start, pos-start).c_str()); +- start = pos+1; +- } +- buffer.erase(0, start); +-} +- +-static void ff_flush_avutil_log_buffers(void) +-{ +- CSingleLock lock(m_logSection); +- +- /* Loop through the logbuffer list and remove any blank buffers +- If the thread using the buffer is still active, it will just +- add a new buffer next time it writes to the log */ +- std::map::iterator it; +- for (it = g_logbuffer.begin(); it != g_logbuffer.end(); ) +- if ((*it).second.empty()) +- g_logbuffer.erase(it++); +- else +- ++it; +-} +- + static int interrupt_cb(void* ctx) + { + CDVDDemuxFFmpeg* demuxer = static_cast(ctx); +@@ -165,41 +102,6 @@ static int interrupt_cb(void* ctx) + return 0; + } + +-/* callback for the ffmpeg lock manager */ +-int ffmpeg_lockmgr_cb(void **mutex, enum AVLockOp operation) +-{ +- CSharedSection **lock = (CSharedSection **)mutex; +- +- switch (operation) +- { +- case AV_LOCK_CREATE: +- { +- *lock = NULL; +- *lock = new CSharedSection(); +- if (*lock == NULL) +- return 1; +- break; +- } +- case AV_LOCK_OBTAIN: +- (*lock)->lock(); +- break; +- +- case AV_LOCK_RELEASE: +- (*lock)->unlock(); +- break; +- +- case AV_LOCK_DESTROY: +- { +- delete *lock; +- *lock = NULL; +- break; +- } +- +- default: +- return 1; +- } +- return 0; +-} + + //////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index b11da56..44e101c 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -24,7 +24,10 @@ + #include "threads/CriticalSection.h" + #include "threads/SystemClock.h" + #include +-#include "lib/ffmpeg.h" ++ ++extern "C" { ++#include "libavformat/avformat.h" ++} + + class CDVDDemuxFFmpeg; + class CURL; +-- +1.9.3 + + +From a09d286386ba18d3bf3ca8efcbb9782cd2c56505 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 31 Jan 2014 09:46:08 +0100 +Subject: [PATCH 006/122] remove ffmpeg dlls from generated headers not + removing win32 as this might still be needed? + +--- + xbmc/DllPaths_generated.h.in | 9 --------- + xbmc/DllPaths_generated_android.h.in | 9 --------- + 2 files changed, 18 deletions(-) + +diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in +index 4953236..8e81555 100644 +--- a/xbmc/DllPaths_generated.h.in ++++ b/xbmc/DllPaths_generated.h.in +@@ -71,15 +71,6 @@ + #define DLL_PATH_LIBMPEG2 "@MPEG2_SONAME@" + #define DLL_PATH_LIBMAD "@MAD_SONAME@" + +-/* ffmpeg */ +-#define DLL_PATH_LIBAVCODEC "special://xbmcbin/system/players/dvdplayer/avcodec-54-@ARCH@.so" +-#define DLL_PATH_LIBAVFORMAT "special://xbmcbin/system/players/dvdplayer/avformat-54-@ARCH@.so" +-#define DLL_PATH_LIBAVUTIL "special://xbmcbin/system/players/dvdplayer/avutil-52-@ARCH@.so" +-#define DLL_PATH_LIBPOSTPROC "special://xbmcbin/system/players/dvdplayer/postproc-52-@ARCH@.so" +-#define DLL_PATH_LIBSWSCALE "special://xbmcbin/system/players/dvdplayer/swscale-2-@ARCH@.so" +-#define DLL_PATH_LIBAVFILTER "special://xbmcbin/system/players/dvdplayer/avfilter-3-@ARCH@.so" +-#define DLL_PATH_LIBSWRESAMPLE "special://xbmcbin/system/players/dvdplayer/swresample-0-@ARCH@.so" +- + /* cdrip */ + #define DLL_PATH_LAME_ENC "@LAMEENC_SONAME@" + #define DLL_PATH_OGG "@OGG_SONAME@" +diff --git a/xbmc/DllPaths_generated_android.h.in b/xbmc/DllPaths_generated_android.h.in +index e77c1bc..dfa2275 100644 +--- a/xbmc/DllPaths_generated_android.h.in ++++ b/xbmc/DllPaths_generated_android.h.in +@@ -75,15 +75,6 @@ + #define DLL_PATH_LIBMAD "@MAD_SONAME@" + #define DLL_PATH_LIBSTAGEFRIGHTICS "libXBMCvcodec_stagefrightICS-@ARCH@.so" + +-/* ffmpeg */ +-#define DLL_PATH_LIBAVCODEC "libavcodec-54-@ARCH@.so" +-#define DLL_PATH_LIBAVFORMAT "libavformat-54-@ARCH@.so" +-#define DLL_PATH_LIBAVUTIL "libavutil-52-@ARCH@.so" +-#define DLL_PATH_LIBPOSTPROC "libpostproc-52-@ARCH@.so" +-#define DLL_PATH_LIBSWSCALE "libswscale-2-@ARCH@.so" +-#define DLL_PATH_LIBAVFILTER "libavfilter-3-@ARCH@.so" +-#define DLL_PATH_LIBSWRESAMPLE "libswresample-0-@ARCH@.so" +- + /* cdrip */ + #define DLL_PATH_LAME_ENC "@LAMEENC_SONAME@" + #define DLL_PATH_OGG "@OGG_SONAME@" +-- +1.9.3 + + +From 34a4bd5cfae9b2f279a8de8168c4e8a69294a449 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 31 Jan 2014 10:54:08 +0100 +Subject: [PATCH 007/122] [rpi] setup-sdk.sh: allow overriding of buildroot and + xbmc install paths also don't require root if not needed + +--- + tools/rbp/setup-sdk.sh | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + mode change 100644 => 100755 tools/rbp/setup-sdk.sh + +diff --git a/tools/rbp/setup-sdk.sh b/tools/rbp/setup-sdk.sh +old mode 100644 +new mode 100755 +index 9da68cb..70f2a36 +--- a/tools/rbp/setup-sdk.sh ++++ b/tools/rbp/setup-sdk.sh +@@ -5,9 +5,9 @@ SCRIPT_PATH=$(cd `dirname $0` && pwd) + USE_BUILDROOT=1 + + if [ "$USE_BUILDROOT" = "1" ]; then +- BUILDROOT=/opt/xbmc-bcm/buildroot +- TARBALLS=/opt/xbmc-tarballs +- XBMCPREFIX=/opt/xbmc-bcm/xbmc-bin ++ BUILDROOT=${BUILDROOT:-"/opt/xbmc-bcm/buildroot"} ++ TARBALLS=${TARBALLS:-"/opt/xbmc-tarballs"} ++ XBMCPREFIX=${XBMCPREFIX:-"/opt/xbmc-bcm/xbmc-bin"} + + SDKSTAGE=$BUILDROOT/output/staging + TARGETFS=$BUILDROOT/output/target +@@ -21,8 +21,15 @@ else + BUILDROOT=/opt/bcm-rootfs + fi + +-sudo mkdir -p $XBMCPREFIX +-sudo chmod 777 $XBMCPREFIX ++if [ -d $XBMCPREFIX ] ++then ++ [ -O $XBMCPREFIX ] || SUDO="sudo" ++else ++ [ -w $(dirname $XBMCPREFIX) ] || SUDO="sudo" ++fi ++ ++$SUDO mkdir -p $XBMCPREFIX ++$SUDO chmod 777 $XBMCPREFIX + mkdir -p $XBMCPREFIX/lib + mkdir -p $XBMCPREFIX/include + +-- +1.9.3 + + +From 0543afcb0c798b8ab7e9935b20148eeae4f01b98 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sun, 2 Feb 2014 09:57:00 +0100 +Subject: [PATCH 008/122] add ffmpeg makefile for rpi + +--- + tools/rbp/depends/Makefile | 6 ++-- + tools/rbp/depends/ffmpeg/Makefile | 61 +++++++++++++++++++++++++++++++++++++++ + tools/rbp/depends/xbmc/Makefile | 1 + + 3 files changed, 65 insertions(+), 3 deletions(-) + create mode 100644 tools/rbp/depends/ffmpeg/Makefile + +diff --git a/tools/rbp/depends/Makefile b/tools/rbp/depends/Makefile +index 5afbc5a..12e7260 100644 +--- a/tools/rbp/depends/Makefile ++++ b/tools/rbp/depends/Makefile +@@ -2,10 +2,10 @@ include ../Makefile.include + + ifeq ($(USE_BUILDROOT),1) + BUILDTOOLS = +- SUBDIRS = xbmc ++ SUBDIRS = ffmpeg xbmc + else + BUILDTOOLS = help2man autoconf automake libtool pkg-config yasm cmake patchelf +- SUBDIRS = liblzo2 tiff libnfs jasper libplist libshairplay tinyxml xbmc ++ SUBDIRS = liblzo2 tiff libnfs jasper libplist libshairplay tinyxml ffmpeg xbmc + endif + + IMAGENAME = xbmc-rbp-`date +'%y%m%d'` +@@ -18,7 +18,7 @@ buildtools: + for d in $(BUILDTOOLS); do $(MAKE) -C $$d; done + + subdirs: +- for d in $(SUBDIRS); do $(MAKE) -C $$d; done ++ for d in $(SUBDIRS); do if test -f "$$d/.installed"; then :; else $(MAKE) -C $$d || exit 1; fi; done + + clean: + for d in $(BUILDTOOLS); do $(MAKE) -C $$d clean; done +diff --git a/tools/rbp/depends/ffmpeg/Makefile b/tools/rbp/depends/ffmpeg/Makefile +new file mode 100644 +index 0000000..93b5a02 +--- /dev/null ++++ b/tools/rbp/depends/ffmpeg/Makefile +@@ -0,0 +1,61 @@ ++include ../../Makefile.include ++include ../depends.mk ++include ../../../depends/target/ffmpeg/FFMPEG-VERSION ++DEPS= ../../Makefile.include ../depends.mk ../../../depends/target/ffmpeg/FFMPEG-VERSION Makefile ++ ++# set to "yes" to enable patching ++# we don't apply patches until we move to a vanilla ffmpeg tarball ++APPLY_PATCHES=no ++ ++# configuration settings ++ffmpg_config = --sysroot=$(SYSROOT) --prefix=$(PREFIX) ++ffmpg_config += --enable-cross-compile --target-os=linux --cpu=arm1176jzf-s --arch=arm ++ffmpg_config += --cc=$(CC) --cxx=$(CXX) ++ffmpg_config += --disable-devices --disable-doc ++ffmpg_config += --disable-ffplay --disable-ffmpeg ++ffmpg_config += --disable-ffprobe --disable-ffserver ++ffmpg_config += --enable-gpl --enable-runtime-cpudetect ++ffmpg_config += --enable-postproc --enable-pthreads ++ffmpg_config += --enable-muxer=spdif --enable-muxer=adts ++ffmpg_config += --enable-muxer=asf --enable-muxer=ipod ++ffmpg_config += --enable-encoder=ac3 --enable-encoder=aac ++ffmpg_config += --enable-encoder=wmav2 --enable-protocol=http ++ffmpg_config += --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis ++ffmpg_config += --disable-vaapi --disable-vdpau --disable-crystalhd ++#ffmpg_config += --enable-gnutls ++ifeq ($(Configuration), Release) ++ ffmpg_config += --disable-debug ++endif ++ ++ ++CLEAN_FILES=$(ARCHIVE) rpi ++ ++all: .installed ++ ++$(TARBALLS_LOCATION)/$(ARCHIVE): ++ cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) -Ls --create-dirs -f -o $(TARBALLS_LOCATION)/$(ARCHIVE) $(BASE_URL)/$(VERSION).tar.gz ++ ++rpi: $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) ++ rm -rf rpi; mkdir -p rpi ++ cd rpi; $(ARCHIVE_TOOL) --strip-components=1 -xf $(TARBALLS_LOCATION)/$(ARCHIVE) ++ if test "$(APPLY_PATCHES)" = "yes"; then \ ++ cd rpi; \ ++ for PATCH in ../patches/*.patch ; do \ ++ patch -p1 < $${PATCH}; \ ++ done; \ ++ fi ++ cd rpi;\ ++ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ ++ ./configure $(ffmpg_config) ++ ++.installed: rpi ++ $(MAKE) -j $(JOBS) -C rpi || exit 1 ++ $(MAKE) -C rpi install && touch $@ ++ ++clean: ++ $(MAKE) -C rpi clean ++ rm -f .installed ++ ++distclean:: ++ rm -rf rpi .installed ++ +diff --git a/tools/rbp/depends/xbmc/Makefile b/tools/rbp/depends/xbmc/Makefile +index 4e6862e..b0ba8d1 100644 +--- a/tools/rbp/depends/xbmc/Makefile ++++ b/tools/rbp/depends/xbmc/Makefile +@@ -5,6 +5,7 @@ SOURCE=../../../../ + + ifeq ($(USE_BUILDROOT),1) + export PATH:=$(PREFIX)/bin:$(BUILDROOT)/output/host/usr/bin:$(SYSROOT)/usr/bin:$(PATH) ++ export PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig + endif + + CONFIGURE=./configure --prefix=$(PREFIX) --build=$(BUILD) --host=$(HOST) \ +-- +1.9.3 + + +From 8ed99add5b82af46382268a7201b34551720a4bf Mon Sep 17 00:00:00 2001 +From: WiSo +Date: Sat, 1 Feb 2014 15:44:15 +0100 +Subject: [PATCH 009/122] [WIN32] download and compile ffmpeg from remote + source. + +--- + lib/win32/ffmpeg_dxva2/dxva2api.h | 502 +++++++++++++++++++++++++++++++++ + project/VS2010Express/XBMC.vcxproj | 4 +- + project/Win32BuildSetup/buildffmpeg.sh | 105 +++++++ + 3 files changed, 609 insertions(+), 2 deletions(-) + create mode 100644 lib/win32/ffmpeg_dxva2/dxva2api.h + create mode 100644 project/Win32BuildSetup/buildffmpeg.sh + +diff --git a/lib/win32/ffmpeg_dxva2/dxva2api.h b/lib/win32/ffmpeg_dxva2/dxva2api.h +new file mode 100644 +index 0000000..28e54c8 +--- /dev/null ++++ b/lib/win32/ffmpeg_dxva2/dxva2api.h +@@ -0,0 +1,502 @@ ++/***************************************************************************** ++ * dxva2api.h: DXVA 2 interface ++ ***************************************************************************** ++ * Copyright (C) 2009 Geoffroy Couprie ++ * Copyright (C) 2009 Laurent Aimar ++ * $Id$ ++ * ++ * Authors: Geoffroy Couprie ++ * Laurent Aimar ++ * ++ * This program 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. ++ * ++ * This program 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-1301, USA. ++ *****************************************************************************/ ++ ++#ifndef _DXVA2API_H ++#define _DXVA2API_H ++ ++#define MINGW_DXVA2API_H_VERSION (2) ++ ++#if __GNUC__ >=3 ++#pragma GCC system_header ++#endif ++ ++#include ++#include ++ ++/* Define it to allow using nameless struct/union (non C99 compliant) to match ++ * the official documentation. */ ++//#define DXVA2API_USE_BITFIELDS ++ ++/****************STRUCTURES******************/ ++#pragma pack(push, 1) ++ ++typedef struct _DXVA2_ExtendedFormat { ++#ifdef DXVA2API_USE_BITFIELDS ++ union { ++ struct { ++ UINT SampleFormat : 8; ++ UINT VideoChromaSubsampling : 4; ++ UINT NominalRange : 3; ++ UINT VideoTransferMatrix : 3; ++ UINT VideoLighting : 4; ++ UINT VideoPrimaries : 5; ++ UINT VideoTransferFunction : 5; ++ }; ++ UINT value; ++ }; ++#else ++ UINT value; ++#endif ++} DXVA2_ExtendedFormat; ++ ++typedef struct _DXVA2_Frequency { ++ UINT Numerator; ++ UINT Denominator; ++} DXVA2_Frequency; ++ ++typedef struct _DXVA2_VideoDesc { ++ UINT SampleWidth; ++ UINT SampleHeight; ++ DXVA2_ExtendedFormat SampleFormat; ++ D3DFORMAT Format; ++ DXVA2_Frequency InputSampleFreq; ++ DXVA2_Frequency OutputFrameFreq; ++ UINT UABProtectionLevel; ++ UINT Reserved; ++} DXVA2_VideoDesc; ++ ++typedef struct _DXVA2_ConfigPictureDecode { ++ GUID guidConfigBitstreamEncryption; ++ GUID guidConfigMBcontrolEncryption; ++ GUID guidConfigResidDiffEncryption; ++ UINT ConfigBitstreamRaw; ++ UINT ConfigMBcontrolRasterOrder; ++ UINT ConfigResidDiffHost; ++ UINT ConfigSpatialResid8; ++ UINT ConfigResid8Subtraction; ++ UINT ConfigSpatialHost8or9Clipping; ++ UINT ConfigSpatialResidInterleaved; ++ UINT ConfigIntraResidUnsigned; ++ UINT ConfigResidDiffAccelerator; ++ UINT ConfigHostInverseScan; ++ UINT ConfigSpecificIDCT; ++ UINT Config4GroupedCoefs; ++ USHORT ConfigMinRenderTargetBuffCount; ++ USHORT ConfigDecoderSpecific; ++} DXVA2_ConfigPictureDecode; ++ ++typedef struct _DXVA2_DecodeBufferDesc { ++ DWORD CompressedBufferType; ++ UINT BufferIndex; ++ UINT DataOffset; ++ UINT DataSize; ++ UINT FirstMBaddress; ++ UINT NumMBsInBuffer; ++ UINT Width; ++ UINT Height; ++ UINT Stride; ++ UINT ReservedBits; ++ PVOID pvPVPState; ++} DXVA2_DecodeBufferDesc; ++ ++typedef struct _DXVA2_DecodeExtensionData { ++ UINT Function; ++ PVOID pPrivateInputData; ++ UINT PrivateInputDataSize; ++ PVOID pPrivateOutputData; ++ UINT PrivateOutputDataSize; ++} DXVA2_DecodeExtensionData; ++ ++typedef struct _DXVA2_DecodeExecuteParams { ++ UINT NumCompBuffers; ++ DXVA2_DecodeBufferDesc *pCompressedBuffers; ++ DXVA2_DecodeExtensionData *pExtensionData; ++} DXVA2_DecodeExecuteParams; ++ ++enum { ++ DXVA2_VideoDecoderRenderTarget = 0, ++ DXVA2_VideoProcessorRenderTarget = 1, ++ DXVA2_VideoSoftwareRenderTarget = 2 ++}; ++ ++enum { ++ DXVA2_PictureParametersBufferType = 0, ++ DXVA2_MacroBlockControlBufferType = 1, ++ DXVA2_ResidualDifferenceBufferType = 2, ++ DXVA2_DeblockingControlBufferType = 3, ++ DXVA2_InverseQuantizationMatrixBufferType = 4, ++ DXVA2_SliceControlBufferType = 5, ++ DXVA2_BitStreamDateBufferType = 6, ++ DXVA2_MotionVectorBuffer = 7, ++ DXVA2_FilmGrainBuffer = 8 ++}; ++ ++/* DXVA MPEG-I/II and VC-1 */ ++typedef struct _DXVA_PictureParameters { ++ USHORT wDecodedPictureIndex; ++ USHORT wDeblockedPictureIndex; ++ USHORT wForwardRefPictureIndex; ++ USHORT wBackwardRefPictureIndex; ++ USHORT wPicWidthInMBminus1; ++ USHORT wPicHeightInMBminus1; ++ UCHAR bMacroblockWidthMinus1; ++ UCHAR bMacroblockHeightMinus1; ++ UCHAR bBlockWidthMinus1; ++ UCHAR bBlockHeightMinus1; ++ UCHAR bBPPminus1; ++ UCHAR bPicStructure; ++ UCHAR bSecondField; ++ UCHAR bPicIntra; ++ UCHAR bPicBackwardPrediction; ++ UCHAR bBidirectionalAveragingMode; ++ UCHAR bMVprecisionAndChromaRelation; ++ UCHAR bChromaFormat; ++ UCHAR bPicScanFixed; ++ UCHAR bPicScanMethod; ++ UCHAR bPicReadbackRequests; ++ UCHAR bRcontrol; ++ UCHAR bPicSpatialResid8; ++ UCHAR bPicOverflowBlocks; ++ UCHAR bPicExtrapolation; ++ UCHAR bPicDeblocked; ++ UCHAR bPicDeblockConfined; ++ UCHAR bPic4MVallowed; ++ UCHAR bPicOBMC; ++ UCHAR bPicBinPB; ++ UCHAR bMV_RPS; ++ UCHAR bReservedBits; ++ USHORT wBitstreamFcodes; ++ USHORT wBitstreamPCEelements; ++ UCHAR bBitstreamConcealmentNeed; ++ UCHAR bBitstreamConcealmentMethod; ++} DXVA_PictureParameters, *LPDXVA_PictureParameters; ++ ++typedef struct _DXVA_QmatrixData { ++ BYTE bNewQmatrix[4]; ++ WORD Qmatrix[4][8 * 8]; ++} DXVA_QmatrixData, *LPDXVA_QmatrixData; ++ ++typedef struct _DXVA_SliceInfo { ++ USHORT wHorizontalPosition; ++ USHORT wVerticalPosition; ++ UINT dwSliceBitsInBuffer; ++ UINT dwSliceDataLocation; ++ UCHAR bStartCodeBitOffset; ++ UCHAR bReservedBits; ++ USHORT wMBbitOffset; ++ USHORT wNumberMBsInSlice; ++ USHORT wQuantizerScaleCode; ++ USHORT wBadSliceChopping; ++} DXVA_SliceInfo, *LPDXVA_SliceInfo; ++ ++/* DXVA H264 */ ++typedef struct { ++#ifdef DXVA2API_USE_BITFIELDS ++ union { ++ struct { ++ UCHAR Index7Bits : 7; ++ UCHAR AssociatedFlag : 1; ++ }; ++ UCHAR bPicEntry; ++ }; ++#else ++ UCHAR bPicEntry; ++#endif ++} DXVA_PicEntry_H264; ++ ++ ++typedef struct { ++ USHORT wFrameWidthInMbsMinus1; ++ USHORT wFrameHeightInMbsMinus1; ++ DXVA_PicEntry_H264 CurrPic; ++ UCHAR num_ref_frames; ++#ifdef DXVA2API_USE_BITFIELDS ++ union { ++ struct { ++ USHORT field_pic_flag : 1; ++ USHORT MbaffFrameFlag : 1; ++ USHORT residual_colour_transform_flag : 1; ++ USHORT sp_for_switch_flag : 1; ++ USHORT chroma_format_idc : 2; ++ USHORT RefPicFlag : 1; ++ USHORT constrained_intra_pred_flag : 1; ++ USHORT weighted_pred_flag : 1; ++ USHORT weighted_bipred_idc : 2; ++ USHORT MbsConsecutiveFlag : 1; ++ USHORT frame_mbs_only_flag : 1; ++ USHORT transform_8x8_mode_flag : 1; ++ USHORT MinLumaBipredSize8x8Flag : 1; ++ USHORT IntraPicFlag : 1; ++ }; ++ USHORT wBitFields; ++ }; ++#else ++ USHORT wBitFields; ++#endif ++ UCHAR bit_depth_luma_minus8; ++ UCHAR bit_depth_chroma_minus8; ++ USHORT Reserved16Bits; ++ UINT StatusReportFeedbackNumber; ++ DXVA_PicEntry_H264 RefFrameList[16]; ++ INT CurrFieldOrderCnt[2]; ++ INT FieldOrderCntList[16][2]; ++ CHAR pic_init_qs_minus26; ++ CHAR chroma_qp_index_offset; ++ CHAR second_chroma_qp_index_offset; ++ UCHAR ContinuationFlag; ++ CHAR pic_init_qp_minus26; ++ UCHAR num_ref_idx_l0_active_minus1; ++ UCHAR num_ref_idx_l1_active_minus1; ++ UCHAR Reserved8BitsA; ++ USHORT FrameNumList[16]; ++ ++ UINT UsedForReferenceFlags; ++ USHORT NonExistingFrameFlags; ++ USHORT frame_num; ++ UCHAR log2_max_frame_num_minus4; ++ UCHAR pic_order_cnt_type; ++ UCHAR log2_max_pic_order_cnt_lsb_minus4; ++ UCHAR delta_pic_order_always_zero_flag; ++ UCHAR direct_8x8_inference_flag; ++ UCHAR entropy_coding_mode_flag; ++ UCHAR pic_order_present_flag; ++ UCHAR num_slice_groups_minus1; ++ UCHAR slice_group_map_type; ++ UCHAR deblocking_filter_control_present_flag; ++ UCHAR redundant_pic_cnt_present_flag; ++ UCHAR Reserved8BitsB; ++ USHORT slice_group_change_rate_minus1; ++ UCHAR SliceGroupMap[810]; ++} DXVA_PicParams_H264; ++ ++typedef struct { ++ UCHAR bScalingLists4x4[6][16]; ++ UCHAR bScalingLists8x8[2][64]; ++} DXVA_Qmatrix_H264; ++ ++ ++typedef struct { ++ UINT BSNALunitDataLocation; ++ UINT SliceBytesInBuffer; ++ USHORT wBadSliceChopping; ++ USHORT first_mb_in_slice; ++ USHORT NumMbsForSlice; ++ USHORT BitOffsetToSliceData; ++ UCHAR slice_type; ++ UCHAR luma_log2_weight_denom; ++ UCHAR chroma_log2_weight_denom; ++ ++ UCHAR num_ref_idx_l0_active_minus1; ++ UCHAR num_ref_idx_l1_active_minus1; ++ CHAR slice_alpha_c0_offset_div2; ++ CHAR slice_beta_offset_div2; ++ UCHAR Reserved8Bits; ++ DXVA_PicEntry_H264 RefPicList[2][32]; ++ SHORT Weights[2][32][3][2]; ++ CHAR slice_qs_delta; ++ CHAR slice_qp_delta; ++ UCHAR redundant_pic_cnt; ++ UCHAR direct_spatial_mv_pred_flag; ++ UCHAR cabac_init_idc; ++ UCHAR disable_deblocking_filter_idc; ++ USHORT slice_id; ++} DXVA_Slice_H264_Long; ++ ++typedef struct { ++ UINT BSNALunitDataLocation; ++ UINT SliceBytesInBuffer; ++ USHORT wBadSliceChopping; ++} DXVA_Slice_H264_Short; ++ ++typedef struct { ++ USHORT wFrameWidthInMbsMinus1; ++ USHORT wFrameHeightInMbsMinus1; ++ DXVA_PicEntry_H264 InPic; ++ DXVA_PicEntry_H264 OutPic; ++ USHORT PicOrderCnt_offset; ++ INT CurrPicOrderCnt; ++ UINT StatusReportFeedbackNumber; ++ UCHAR model_id; ++ UCHAR separate_colour_description_present_flag; ++ UCHAR film_grain_bit_depth_luma_minus8; ++ UCHAR film_grain_bit_depth_chroma_minus8; ++ UCHAR film_grain_full_range_flag; ++ UCHAR film_grain_colour_primaries; ++ UCHAR film_grain_transfer_characteristics; ++ UCHAR film_grain_matrix_coefficients; ++ UCHAR blending_mode_id; ++ UCHAR log2_scale_factor; ++ UCHAR comp_model_present_flag[4]; ++ UCHAR num_intensity_intervals_minus1[4]; ++ UCHAR num_model_values_minus1[4]; ++ UCHAR intensity_interval_lower_bound[3][16]; ++ UCHAR intensity_interval_upper_bound[3][16]; ++ SHORT comp_model_value[3][16][8]; ++} DXVA_FilmGrainChar_H264; ++ ++#pragma pack(pop) ++ ++/*************INTERFACES************/ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef _COM_interface IDirectXVideoDecoderService IDirectXVideoDecoderService; ++typedef _COM_interface IDirectXVideoDecoder IDirectXVideoDecoder; ++ ++#undef INTERFACE ++#define INTERFACE IDirectXVideoDecoder ++DECLARE_INTERFACE_(IDirectXVideoDecoder,IUnknown) ++{ ++ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; ++ STDMETHOD_(ULONG,AddRef)(THIS) PURE; ++ STDMETHOD_(ULONG,Release)(THIS) PURE; ++ STDMETHOD(GetVideoDecoderService)(THIS_ IDirectXVideoDecoderService**) PURE; ++ STDMETHOD(GetCreationParameters)(THIS_ GUID*,DXVA2_VideoDesc*,DXVA2_ConfigPictureDecode*,IDirect3DSurface9***,UINT*) PURE; ++ STDMETHOD(GetBuffer)(THIS_ UINT,void**,UINT*) PURE; ++ STDMETHOD(ReleaseBuffer)(THIS_ UINT) PURE; ++ STDMETHOD(BeginFrame)(THIS_ IDirect3DSurface9 *,void*) PURE; ++ STDMETHOD(EndFrame)(THIS_ HANDLE *) PURE; ++ STDMETHOD(Execute)(THIS_ const DXVA2_DecodeExecuteParams*) PURE; ++ ++ ++}; ++ ++#if !defined(__cplusplus) || defined(CINTERFACE) ++#define IDirectXVideoDecoder_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) ++#define IDirectXVideoDecoder_AddRef(p) (p)->lpVtbl->AddRef(p) ++#define IDirectXVideoDecoder_Release(p) (p)->lpVtbl->Release(p) ++#define IDirectXVideoDecoder_BeginFrame(p,a,b) (p)->lpVtbl->BeginFrame(p,a,b) ++#define IDirectXVideoDecoder_EndFrame(p,a) (p)->lpVtbl->EndFrame(p,a) ++#define IDirectXVideoDecoder_Execute(p,a) (p)->lpVtbl->Execute(p,a) ++#define IDirectXVideoDecoder_GetBuffer(p,a,b,c) (p)->lpVtbl->GetBuffer(p,a,b,c) ++#define IDirectXVideoDecoder_GetCreationParameters(p,a,b,c,d,e) (p)->lpVtbl->GetCreationParameters(p,a,b,c,d,e) ++#define IDirectXVideoDecoder_GetVideoDecoderService(p,a) (p)->lpVtbl->GetVideoDecoderService(p,a) ++#define IDirectXVideoDecoder_ReleaseBuffer(p,a) (p)->lpVtbl->ReleaseBuffer(p,a) ++#else ++#define IDirectXVideoDecoder_QueryInterface(p,a,b) (p)->QueryInterface(a,b) ++#define IDirectXVideoDecoder_AddRef(p) (p)->AddRef() ++#define IDirectXVideoDecoder_Release(p) (p)->Release() ++#define IDirectXVideoDecoder_BeginFrame(p,a,b) (p)->BeginFrame(a,b) ++#define IDirectXVideoDecoder_EndFrame(p,a) (p)->EndFrame(a) ++#define IDirectXVideoDecoder_Execute(p,a) (p)->Execute(a) ++#define IDirectXVideoDecoder_GetBuffer(p,a,b,c) (p)->GetBuffer(a,b,c) ++#define IDirectXVideoDecoder_GetCreationParameters(p,a,b,c,d,e) (p)->GetCreationParameters(a,b,c,d,e) ++#define IDirectXVideoDecoder_GetVideoDecoderService(p,a) (p)->GetVideoDecoderService(a) ++#define IDirectXVideoDecoder_ReleaseBuffer(p,a) (p)->ReleaseBuffer(a) ++#endif ++ ++#undef INTERFACE ++#define INTERFACE IDirectXVideoAccelerationService ++DECLARE_INTERFACE_(IDirectXVideoAccelerationService,IUnknown) ++{ ++ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; ++ STDMETHOD_(ULONG,AddRef)(THIS) PURE; ++ STDMETHOD_(ULONG,Release)(THIS) PURE; ++ STDMETHOD(CreateSurface)(THIS_ UINT,UINT,UINT,D3DFORMAT,D3DPOOL,DWORD,DWORD,IDirect3DSurface9**,HANDLE*) PURE; ++ ++}; ++ ++#if !defined(__cplusplus) || defined(CINTERFACE) ++#define IDirectXVideoAccelerationService_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) ++#define IDirectXVideoAccelerationService_AddRef(p) (p)->lpVtbl->AddRef(p) ++#define IDirectXVideoAccelerationService_Release(p) (p)->lpVtbl->Release(p) ++#define IDirectXVideoAccelerationService_CreateSurface(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateSurface(p,a,b,c,d,e,f,g,h,i) ++#else ++#define IDirectXVideoAccelerationService_QueryInterface(p,a,b) (p)->QueryInterface(a,b) ++#define IDirectXVideoAccelerationService_AddRef(p) (p)->AddRef() ++#define IDirectXVideoAccelerationService_Release(p) (p)->Release() ++#define IDirectXVideoAccelerationService_CreateSurface(p,a,b,c,d,e,f,g,h,i) (p)->CreateSurface(a,b,c,d,e,f,g,h,i) ++#endif ++ ++#undef INTERFACE ++#define INTERFACE IDirectXVideoDecoderService ++DECLARE_INTERFACE_(IDirectXVideoDecoderService,IDirectXVideoAccelerationService) ++{ ++ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; ++ STDMETHOD_(ULONG,AddRef)(THIS) PURE; ++ STDMETHOD_(ULONG,Release)(THIS) PURE; ++ STDMETHOD(CreateSurface)(THIS_ UINT,UINT,UINT,D3DFORMAT,D3DPOOL,DWORD,DWORD,IDirect3DSurface9**,HANDLE*) PURE; ++ STDMETHOD(GetDecoderDeviceGuids)(THIS_ UINT*,GUID **) PURE; ++ STDMETHOD(GetDecoderRenderTargets)(THIS_ REFGUID,UINT*,D3DFORMAT**) PURE; ++ STDMETHOD(GetDecoderConfigurations)(THIS_ REFGUID,const DXVA2_VideoDesc*,IUnknown*,UINT*,DXVA2_ConfigPictureDecode**) PURE; ++ STDMETHOD(CreateVideoDecoder)(THIS_ REFGUID,const DXVA2_VideoDesc*,DXVA2_ConfigPictureDecode*,IDirect3DSurface9**,UINT,IDirectXVideoDecoder**) PURE; ++}; ++ ++#if !defined(__cplusplus) || defined(CINTERFACE) ++#define IDirectXVideoDecoderService_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) ++#define IDirectXVideoDecoderService_AddRef(p) (p)->lpVtbl->AddRef(p) ++#define IDirectXVideoDecoderService_Release(p) (p)->lpVtbl->Release(p) ++#define IDirectXVideoDecoderService_CreateSurface(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateSurface(p,a,b,c,d,e,f,g,h,i) ++#define IDirectXVideoDecoderService_CreateVideoDecoder(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVideoDecoder(p,a,b,c,d,e,f) ++#define IDirectXVideoDecoderService_GetDecoderConfigurations(p,a,b,c,d,e) (p)->lpVtbl->GetDecoderConfigurations(p,a,b,c,d,e) ++#define IDirectXVideoDecoderService_GetDecoderDeviceGuids(p,a,b) (p)->lpVtbl->GetDecoderDeviceGuids(p,a,b) ++#define IDirectXVideoDecoderService_GetDecoderRenderTargets(p,a,b,c) (p)->lpVtbl->GetDecoderRenderTargets(p,a,b,c) ++#else ++#define IDirectXVideoDecoderService_QueryInterface(p,a,b) (p)->QueryInterface(a,b) ++#define IDirectXVideoDecoderService_AddRef(p) (p)->AddRef() ++#define IDirectXVideoDecoderService_Release(p) (p)->Release() ++#define IDirectXVideoDecoderService_CreateSurface(p,a,b,c,d,e,f,g,h,i) (p)->CreateSurface(a,b,c,d,e,f,g,h,i) ++#define IDirectXVideoDecoderService_CreateVideoDecoder(p,a,b,c,d,e,f) (p)->CreateVideoDecoder(a,b,c,d,e,f) ++#define IDirectXVideoDecoderService_GetDecoderConfigurations(p,a,b,c,d,e) (p)->GetDecoderConfigurations(a,b,c,d,e) ++#define IDirectXVideoDecoderService_GetDecoderDeviceGuids(p,a,b) (p)->GetDecoderDeviceGuids(a,b) ++#define IDirectXVideoDecoderService_GetDecoderRenderTargets(p,a,b,c) (p)->GetDecoderRenderTargets(a,b,c) ++#endif ++ ++#undef INTERFACE ++#define INTERFACE IDirect3DDeviceManager9 ++DECLARE_INTERFACE_(IDirect3DDeviceManager9,IUnknown) ++{ ++ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; ++ STDMETHOD_(ULONG,AddRef)(THIS) PURE; ++ STDMETHOD_(ULONG,Release)(THIS) PURE; ++ STDMETHOD(ResetDevice)(THIS_ IDirect3DDevice9*,UINT) PURE; ++ STDMETHOD(OpenDeviceHandle)(THIS_ HANDLE*) PURE; ++ STDMETHOD(CloseDeviceHandle)( THIS_ HANDLE) PURE; ++ STDMETHOD(TestDevice)( THIS_ HANDLE) PURE; ++ STDMETHOD(LockDevice)( THIS_ HANDLE,IDirect3DDevice9**,BOOL) PURE; ++ STDMETHOD(UnlockDevice)( THIS_ HANDLE,BOOL) PURE; ++ STDMETHOD(GetVideoService)( THIS_ HANDLE,REFIID,void**) PURE; ++}; ++ ++#if !defined(__cplusplus) || defined(CINTERFACE) ++#define IDirect3DDeviceManager9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) ++#define IDirect3DDeviceManager9_AddRef(p) (p)->lpVtbl->AddRef(p) ++#define IDirect3DDeviceManager9_Release(p) (p)->lpVtbl->Release(p) ++#define IDirect3DDeviceManager9_ResetDevice(p,a,b) (p)->lpVtbl->ResetDevice(p,a,b) ++#define IDirect3DDeviceManager9_OpenDeviceHandle(p,a) (p)->lpVtbl->OpenDeviceHandle(p,a) ++#define IDirect3DDeviceManager9_CloseDeviceHandle(p,a) (p)->lpVtbl->CloseDeviceHandle(p,a) ++#define IDirect3DDeviceManager9_TestDevice(p,a) (p)->lpVtbl->TestDevice(p,a) ++#define IDirect3DDeviceManager9_LockDevice(p,a,b,c) (p)->lpVtbl->LockDevice(p,a,b,c) ++#define IDirect3DDeviceManager9_UnlockDevice(p,a,b) (p)->lpVtbl->UnlockDevice(p,a,b) ++#define IDirect3DDeviceManager9_GetVideoService(p,a,b,c) (p)->lpVtbl->GetVideoService(p,a,b,c) ++#else ++#define IDirect3DDeviceManager9_QueryInterface(p,a,b) (p)->QueryInterface(a,b) ++#define IDirect3DDeviceManager9_AddRef(p) (p)->AddRef() ++#define IDirect3DDeviceManager9_Release(p) (p)->Release() ++#define IDirect3DDeviceManager9_ResetDevice(p,a,b) (p)->ResetDevice(a,b) ++#define IDirect3DDeviceManager9_OpenDeviceHandle(p,a) (p)->OpenDeviceHandle(a) ++#define IDirect3DDeviceManager9_CloseDeviceHandle(p,a) (p)->CloseDeviceHandle(a) ++#define IDirect3DDeviceManager9_TestDevice(p,a) (p)->TestDevice(a) ++#define IDirect3DDeviceManager9_LockDevice(p,a,b,c) (p)->LockDevice(a,b,c) ++#define IDirect3DDeviceManager9_UnlockDevice(p,a,b) (p)->UnlockDevice(a,b) ++#define IDirect3DDeviceManager9_GetVideoService(p,a,b,c) (p)->GetVideoService(a,b,c) ++#endif ++ ++#ifdef __cplusplus ++}; ++#endif ++ ++#endif //_DXVA2API_H +diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj +index c6de5ca..6e74e00 100644 +--- a/project/VS2010Express/XBMC.vcxproj ++++ b/project/VS2010Express/XBMC.vcxproj +@@ -142,7 +142,7 @@ + + + +- ..\..\;..\..\xbmc\;..\..\xbmc\cores\dvdplayer;..\..\xbmc\win32;..\..\lib;..\..\lib\ffmpeg;..\..\lib\ffmpeg\include-xbmc-win32;..\..\lib\libUPnP\Platinum\Source\Devices\MediaRenderer;..\..\lib\libUPnP\Platinum\Source\Devices\MediaConnect;..\..\lib\libUPnP\Platinum\Source\Devices\MediaServer;..\..\lib\libUPnP\Platinum\Source\Platinum;..\..\lib\libUPnP\Platinum\Source\Core;..\..\lib\libUPnP\Platinum\Source\Extras;..\..\lib\libUPnP\Neptune\Source\Core;..\..\lib\libUPnP\Neptune\Source\System\Win32;..\..\lib\win32\pcre;..\..\lib\win32;..\..\xbmc\cores\AudioEngine\;..\..\addons\library.xbmc.gui;..\..\addons\library.xbmc.addon;..\..\addons\library.xbmc.pvr;..\..\addons\library.xbmc.codec;%(AdditionalIncludeDirectories) ++ ..\..\;..\..\xbmc\;..\..\xbmc\cores\dvdplayer;..\..\xbmc\win32;..\..\lib;..\..\lib\win32\ffmpeg;..\..\lib\libUPnP\Platinum\Source\Devices\MediaRenderer;..\..\lib\libUPnP\Platinum\Source\Devices\MediaConnect;..\..\lib\libUPnP\Platinum\Source\Devices\MediaServer;..\..\lib\libUPnP\Platinum\Source\Platinum;..\..\lib\libUPnP\Platinum\Source\Core;..\..\lib\libUPnP\Platinum\Source\Extras;..\..\lib\libUPnP\Neptune\Source\Core;..\..\lib\libUPnP\Neptune\Source\System\Win32;..\..\lib\win32\pcre;..\..\lib\win32;..\..\xbmc\cores\AudioEngine\;..\..\addons\library.xbmc.gui;..\..\addons\library.xbmc.addon;..\..\addons\library.xbmc.pvr;..\..\addons\library.xbmc.codec;%(AdditionalIncludeDirectories) + NOMINMAX;_USE_32BIT_TIME_T;HAS_DX;D3D_DEBUG_INFO;__STDC_CONSTANT_MACROS;_SECURE_SCL=0;TAGLIB_STATIC;%(PreprocessorDefinitions) + Async + Use +@@ -2911,4 +2911,4 @@ + + + +- +\ No newline at end of file ++ +diff --git a/project/Win32BuildSetup/buildffmpeg.sh b/project/Win32BuildSetup/buildffmpeg.sh +new file mode 100644 +index 0000000..c69f84f +--- /dev/null ++++ b/project/Win32BuildSetup/buildffmpeg.sh +@@ -0,0 +1,105 @@ ++#!/bin/bash ++ ++MAKEFLAGS="" ++BGPROCESSFILE="$2" ++ ++BASE_URL=https://github.com/FernetMenta/FFmpeg/archive ++VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++LIBNAME=ffmpeg ++ARCHIVE=$LIBNAME-$VERSION.tar.gz ++ ++CUR_DIR=`pwd` ++DEPS_DIR=$CUR_DIR/../BuildDependencies ++LIB_DIR=$CUR_DIR/../../lib/win32 ++WGET=$DEPS_DIR/bin/wget ++UNZIP=$CUR_DIR/tools/7z/7za ++ ++cd $LIB_DIR ++ ++if [ "$1" == "clean" ] ++then ++ echo removing $LIBNAME ++ if [ -d $LIBNAME ] ++ then ++ rm -r $LIBNAME ++ fi ++fi ++ ++if [ ! -d $LIBNAME ]; then ++ if [ ! -f $VERSION.tar.gz ]; then ++ $WGET --no-check-certificate $BASE_URL/$VERSION.tar.gz -O $VERSION.tar.gz ++ fi ++ $UNZIP x -y $VERSION.tar.gz ++ $UNZIP x -y $VERSION.tar ++ mv $LIBNAME-$VERSION $LIBNAME ++ cd $LIBNAME ++else ++ cd $LIBNAME ++ if [ -d .libs ]; then ++ rm -r .libs ++ fi ++fi ++ ++if [ ! -d .libs ]; then ++ mkdir .libs ++fi ++ ++if [ $NUMBER_OF_PROCESSORS > 1 ]; then ++ if [ $NUMBER_OF_PROCESSORS > 4 ]; then ++ MAKEFLAGS=-j4 ++ else ++ MAKEFLAGS=-j$NUMBER_OF_PROCESSORS ++ fi ++fi ++ ++# add --enable-debug (remove --disable-debug ofc) to get ffmpeg log messages in xbmc.log ++# the resulting debug dll's are twice to fourth time the size of the release binaries ++ ++OPTIONS=" ++--enable-shared \ ++--enable-memalign-hack \ ++--enable-gpl \ ++--enable-w32threads \ ++--enable-postproc \ ++--enable-zlib \ ++--disable-static \ ++--disable-debug \ ++--disable-ffplay \ ++--disable-ffserver \ ++--disable-ffmpeg \ ++--disable-ffprobe \ ++--disable-devices \ ++--disable-doc \ ++--disable-crystalhd \ ++--enable-muxer=spdif \ ++--enable-muxer=adts \ ++--enable-muxer=asf \ ++--enable-muxer=ipod \ ++--enable-muxer=ogg \ ++--enable-encoder=ac3 \ ++--enable-encoder=aac \ ++--enable-encoder=wmav2 \ ++--enable-encoder=libvorbis \ ++--enable-protocol=http \ ++--enable-runtime-cpudetect \ ++--enable-dxva2 \ ++--cpu=i686 \ ++--enable-gnutls" ++ ++echo configuring $LIBNAME ++./configure --extra-cflags="-fno-common -I/xbmc/lib/win32/ffmpeg_dxva2 -DNDEBUG" --extra-ldflags="-L/xbmc/system/players/dvdplayer" ${OPTIONS} && ++ ++make $MAKEFLAGS && ++cp lib*/*.dll .libs/ && ++cp .libs/avcodec-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/avformat-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/avutil-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/avfilter-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/postproc-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/swresample-*.dll /xbmc/system/players/dvdplayer/ && ++cp .libs/swscale-*.dll /xbmc/system/players/dvdplayer/ ++ ++#remove the bgprocessfile for signaling the process end ++if [ -f $BGPROCESSFILE ]; then ++ rm $BGPROCESSFILE ++fi +\ No newline at end of file +-- +1.9.3 + + +From 1fabf89c8c49eed6faff8961246184e64432bbda Mon Sep 17 00:00:00 2001 +From: wsoltys +Date: Wed, 19 Feb 2014 11:19:50 +0100 +Subject: [PATCH 010/122] [WIN32] make XBMC compile, build and run with the + ffmpeg link libraries. + +--- + project/VS2010Express/XBMC.vcxproj | 10 ++++-- + project/VS2010Express/XBMC.vcxproj.filters | 8 ++++- + project/Win32BuildSetup/buildffmpeg.sh | 1 + + xbmc/cores/VideoRenderers/WinRenderer.cpp | 17 +++------- + xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 10 ++++++ + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 1 + + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp | 1 + + xbmc/win32/Win32DelayedDllLoad.cpp | 42 ++++++++++++++++++++++++ + 8 files changed, 73 insertions(+), 17 deletions(-) + +diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj +index 6e74e00..dfaf62d 100644 +--- a/project/VS2010Express/XBMC.vcxproj ++++ b/project/VS2010Express/XBMC.vcxproj +@@ -158,12 +158,13 @@ + libc;msvcrt;libcmt;msvcrtd;msvcprtd;%(IgnoreSpecificDefaultLibraries) + + +- libxslt.dll;dnssd.dll;dwmapi.dll;libmicrohttpd-5.dll;ssh.dll;sqlite3.dll;libsamplerate-0.dll;%(DelayLoadDLLs) ++ libxslt.dll;dnssd.dll;dwmapi.dll;libmicrohttpd-5.dll;ssh.dll;sqlite3.dll;libsamplerate-0.dll;avcodec-55.dll;avfilter-4.dll;avformat-55.dll;avutil-52.dll;postproc-52.dll;swresample-0.dll;swscale-2.dll;%(DelayLoadDLLs) + $(OutDir)XBMC.pdb + + + true + true ++ ..\..\lib\win32\ffmpeg\.libs;%(AdditionalLibraryDirectories) + + + VC90.CRT.x86.manifest;win81.manifest;%(AdditionalManifestFiles) +@@ -206,7 +207,7 @@ + + + /MP %(AdditionalOptions) +- ..\..\;..\..\xbmc\;..\..\xbmc\cores\dvdplayer;..\..\xbmc\win32;..\..\lib;..\..\lib\ffmpeg;..\..\lib\ffmpeg\include-xbmc-win32;..\..\lib\libUPnP\Platinum\Source\Devices\MediaRenderer;..\..\lib\libUPnP\Platinum\Source\Devices\MediaConnect;..\..\lib\libUPnP\Platinum\Source\Devices\MediaServer;..\..\lib\libUPnP\Platinum\Source\Platinum;..\..\lib\libUPnP\Platinum\Source\Core;..\..\lib\libUPnP\Platinum\Source\Extras;..\..\lib\libUPnP\Neptune\Source\Core;..\..\lib\libUPnP\Neptune\Source\System\Win32;..\..\lib\win32\pcre;..\..\lib\win32;..\..\xbmc\cores\AudioEngine\;..\..\addons\library.xbmc.gui;..\..\addons\library.xbmc.addon;..\..\addons\library.xbmc.pvr;..\..\addons\library.xbmc.codec;%(AdditionalIncludeDirectories) ++ ..\..\;..\..\xbmc\;..\..\xbmc\cores\dvdplayer;..\..\xbmc\win32;..\..\lib;..\..\lib\win32\ffmpeg;..\..\lib\libUPnP\Platinum\Source\Devices\MediaRenderer;..\..\lib\libUPnP\Platinum\Source\Devices\MediaConnect;..\..\lib\libUPnP\Platinum\Source\Devices\MediaServer;..\..\lib\libUPnP\Platinum\Source\Platinum;..\..\lib\libUPnP\Platinum\Source\Core;..\..\lib\libUPnP\Platinum\Source\Extras;..\..\lib\libUPnP\Neptune\Source\Core;..\..\lib\libUPnP\Neptune\Source\System\Win32;..\..\lib\win32\pcre;..\..\lib\win32;..\..\xbmc\cores\AudioEngine\;..\..\addons\library.xbmc.gui;..\..\addons\library.xbmc.addon;..\..\addons\library.xbmc.pvr;..\..\addons\library.xbmc.codec;%(AdditionalIncludeDirectories) + NOMINMAX;_USE_32BIT_TIME_T;HAS_DX;__STDC_CONSTANT_MACROS;TAGLIB_STATIC;%(PreprocessorDefinitions) + Async + Use +@@ -220,11 +221,12 @@ + D3dx9.lib;DInput8.lib;DSound.lib;winmm.lib;Mpr.lib;Iphlpapi.lib;PowrProf.lib;setupapi.lib;dwmapi.lib;yajl.lib;dxguid.lib;%(AdditionalDependencies) + $(OutDir)XBMC.exe + libc;msvcrt;libci;msvcprt;%(IgnoreSpecificDefaultLibraries) +- libxslt.dll;dnssd.dll;dwmapi.dll;libmicrohttpd-5.dll;ssh.dll;sqlite3.dll;libsamplerate-0.dll;%(DelayLoadDLLs) ++ libxslt.dll;dnssd.dll;dwmapi.dll;libmicrohttpd-5.dll;ssh.dll;sqlite3.dll;libsamplerate-0.dll;avcodec-55.dll;avfilter-4.dll;avformat-55.dll;avutil-52.dll;postproc-52.dll;swresample-0.dll;swscale-2.dll;%(DelayLoadDLLs) + true + $(OutDir)XBMC.pdb + true + true ++ ..\..\lib\win32\ffmpeg\.libs;%(AdditionalLibraryDirectories) + + + VC90.CRT.x86.manifest;win81.manifest;%(AdditionalManifestFiles) +@@ -323,6 +325,7 @@ + + + ++ + + + +@@ -994,6 +997,7 @@ + + + ++ + + + +diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters +index b536eb3..eb54988 100644 +--- a/project/VS2010Express/XBMC.vcxproj.filters ++++ b/project/VS2010Express/XBMC.vcxproj.filters +@@ -3104,6 +3104,9 @@ + + cores\dvdplayer\DVDCodecs\Video + ++ ++ cores ++ + + + +@@ -6094,6 +6097,9 @@ + + win32 + ++ ++ cores ++ + + + +@@ -6123,4 +6129,4 @@ + interfaces\swig + + +- +\ No newline at end of file ++ +diff --git a/project/Win32BuildSetup/buildffmpeg.sh b/project/Win32BuildSetup/buildffmpeg.sh +index c69f84f..5fbd1b3 100644 +--- a/project/Win32BuildSetup/buildffmpeg.sh ++++ b/project/Win32BuildSetup/buildffmpeg.sh +@@ -91,6 +91,7 @@ echo configuring $LIBNAME + + make $MAKEFLAGS && + cp lib*/*.dll .libs/ && ++cp lib*/*.lib .libs/ && + cp .libs/avcodec-*.dll /xbmc/system/players/dvdplayer/ && + cp .libs/avformat-*.dll /xbmc/system/players/dvdplayer/ && + cp .libs/avutil-*.dll /xbmc/system/players/dvdplayer/ && +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp +index 7e82dd4..700dadb 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp +@@ -20,7 +20,6 @@ + + #ifdef HAS_DX + +-#include "libswscale/swscale.h" + #include "Util.h" + #include "WinRenderer.h" + #include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h" +@@ -39,6 +38,7 @@ + #include "VideoShaders/WinVideoFilter.h" + #include "win32/WIN32Util.h" + #include "windowing/WindowingFactory.h" ++#include "cores/FFmpeg.h" + + typedef struct { + RenderMethod method; +@@ -84,11 +84,8 @@ CWinRenderer::CWinRenderer() + m_VideoBuffers[i] = NULL; + + m_sw_scale_ctx = NULL; +- m_dllSwScale = NULL; + m_destWidth = 0; + m_destHeight = 0; +- m_dllAvUtil = NULL; +- m_dllAvCodec = NULL; + m_bConfigured = false; + m_clearColour = 0; + m_format = RENDER_FMT_NONE; +@@ -210,11 +207,6 @@ bool CWinRenderer::UpdateRenderMethod() + + if (m_renderMethod == RENDER_SW) + { +- m_dllSwScale = new DllSwScale(); +- +- if (!m_dllSwScale->Load()) +- CLog::Log(LOGERROR,"CDVDDemuxFFmpeg::Open - failed to load ffmpeg libraries"); +- + if(!m_SWTarget.Create(m_sourceWidth, m_sourceHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT)) + { + CLog::Log(LOGNOTICE, __FUNCTION__": Failed to create sw render target."); +@@ -462,10 +454,9 @@ void CWinRenderer::UnInit() + + if (m_sw_scale_ctx) + { +- m_dllSwScale->sws_freeContext(m_sw_scale_ctx); ++ sws_freeContext(m_sw_scale_ctx); + m_sw_scale_ctx = NULL; + } +- SAFE_DELETE(m_dllSwScale); + + if (m_processor) + { +@@ -727,7 +718,7 @@ void CWinRenderer::RenderSW() + enum PixelFormat format = PixelFormatFromFormat(m_format); + + // 1. convert yuv to rgb +- m_sw_scale_ctx = m_dllSwScale->sws_getCachedContext(m_sw_scale_ctx, ++ m_sw_scale_ctx = sws_getCachedContext(m_sw_scale_ctx, + m_sourceWidth, m_sourceHeight, format, + m_sourceWidth, m_sourceHeight, PIX_FMT_BGRA, + SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); +@@ -756,7 +747,7 @@ void CWinRenderer::RenderSW() + uint8_t *dst[] = { (uint8_t*) destlr.pBits, 0, 0, 0 }; + int dstStride[] = { destlr.Pitch, 0, 0, 0 }; + +- m_dllSwScale->sws_scale(m_sw_scale_ctx, src, srcStride, 0, m_sourceHeight, dst, dstStride); ++ sws_scale(m_sw_scale_ctx, src, srcStride, 0, m_sourceHeight, dst, dstStride); + + for (unsigned int idx = 0; idx < buf->GetActivePlanes(); idx++) + if(!(buf->planes[idx].texture.UnlockRect(0))) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +index 46841a1..2958d43 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +@@ -25,6 +25,16 @@ + #include "utils/fastmemcpy.h" + #include "cores/FFmpeg.h" + ++#ifdef TARGET_WINDOWS ++#pragma comment(lib, "avcodec.lib") ++#pragma comment(lib, "avfilter.lib") ++#pragma comment(lib, "avformat.lib") ++#pragma comment(lib, "avutil.lib") ++#pragma comment(lib, "postproc.lib") ++#pragma comment(lib, "swresample.lib") ++#pragma comment(lib, "swscale.lib") ++#endif ++ + extern "C" { + #include "libswscale/swscale.h" + } +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +index 369a447..f564673 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +@@ -44,6 +44,7 @@ + #include "settings/MediaSettings.h" + #include "cores/VideoRenderers/RenderManager.h" + #include "win32/WIN32Util.h" ++#include "utils/Log.h" + + #define ALLOW_ADDING_SURFACES 0 + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp +index f92ab7c..3a90d6a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp +@@ -44,6 +44,7 @@ + #include "settings/MediaSettings.h" + #include "cores/VideoRenderers/RenderManager.h" + #include "win32/WIN32Util.h" ++#include "utils/Log.h" + + #define ALLOW_ADDING_SURFACES 0 + +diff --git a/xbmc/win32/Win32DelayedDllLoad.cpp b/xbmc/win32/Win32DelayedDllLoad.cpp +index 174be08..def089e 100644 +--- a/xbmc/win32/Win32DelayedDllLoad.cpp ++++ b/xbmc/win32/Win32DelayedDllLoad.cpp +@@ -66,6 +66,48 @@ FARPROC WINAPI delayHookNotifyFunc (unsigned dliNotify, PDelayLoadInfo pdli) + HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); + return (FARPROC)hMod; + } ++ if (stricmp(pdli->szDll, "avcodec-55.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/avcodec-55.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "avfilter-4.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/avfilter-4.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "avformat-55.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/avformat-55.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "avutil-52.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/avutil-52.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "postproc-52.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/postproc-52.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "swresample-0.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/swresample-0.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } ++ if (stricmp(pdli->szDll, "swscale-2.dll") == 0) ++ { ++ CStdString strDll = CSpecialProtocol::TranslatePath("special://xbmcbin/system/players/dvdplayer/swscale-2.dll"); ++ HMODULE hMod = LoadLibraryEx(strDll.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); ++ return (FARPROC)hMod; ++ } + break; + } + return NULL; +-- +1.9.3 + + +From 4eda95e1823d502a8cc8817cdd4503a5c92bd464 Mon Sep 17 00:00:00 2001 +From: wsoltys +Date: Wed, 19 Feb 2014 11:46:45 +0100 +Subject: [PATCH 011/122] [WIN32] use ffmpeg version from + tools\depends\target\ffmpeg\FFMPEG-VERSION + +--- + project/Win32BuildSetup/buildffmpeg.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/project/Win32BuildSetup/buildffmpeg.sh b/project/Win32BuildSetup/buildffmpeg.sh +index 5fbd1b3..55336f3 100644 +--- a/project/Win32BuildSetup/buildffmpeg.sh ++++ b/project/Win32BuildSetup/buildffmpeg.sh +@@ -3,8 +3,8 @@ + MAKEFLAGS="" + BGPROCESSFILE="$2" + +-BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++BASE_URL=$(grep "BASE_URL=" ../../tools/depends/target/ffmpeg/FFMPEG-VERSION | sed 's/BASE_URL=//g') ++VERSION=$(grep "VERSION=" ../../tools/depends/target/ffmpeg/FFMPEG-VERSION | sed 's/VERSION=//g') + LIBNAME=ffmpeg + ARCHIVE=$LIBNAME-$VERSION.tar.gz + +-- +1.9.3 + + +From 6b8251138924b6c37dbf66cc2318b0da874cbd4d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 23 Feb 2014 08:38:30 +0100 +Subject: [PATCH 014/122] ffmpeg: bump version to 2.2 + +--- + tools/depends/target/ffmpeg/FFMPEG-VERSION | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION +index 850943e..8fa07a5 100644 +--- a/tools/depends/target/ffmpeg/FFMPEG-VERSION ++++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION +@@ -1,5 +1,5 @@ + LIBNAME=ffmpeg +-BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=11086c540305ffb208e6fc17d301db989d3c4151 ++BASE_URL=https://github.com/xbmc/FFmpeg/archive ++VERSION=2.2-Helix-alpha1 + ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz + +-- +1.9.3 + + +From 0bef49f7b629858557a9ba8416901799fba44d46 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sun, 23 Mar 2014 10:22:04 +0100 +Subject: [PATCH 015/122] [depends] add --with-platform=raspberry-pi switch + +--- + tools/buildsteps/defaultenv | 2 +- + tools/buildsteps/rbpi/configure-depends | 22 ++----------- + tools/depends/Makefile.include.in | 1 + + tools/depends/README | 3 ++ + tools/depends/configure.in | 58 +++++++++++++++++++++++++++++---- + tools/depends/target/Makefile | 4 +-- + 6 files changed, 60 insertions(+), 30 deletions(-) + +diff --git a/tools/buildsteps/defaultenv b/tools/buildsteps/defaultenv +index 567d66c..0d14e16 100644 +--- a/tools/buildsteps/defaultenv ++++ b/tools/buildsteps/defaultenv +@@ -45,7 +45,7 @@ case $XBMC_PLATFORM_DIR in + ;; + + rbpi) +- JENKINS_RBPI_DEVENV=/home/jenkins/rbpi-dev ++ JENKINS_RBPI_DEVENV=${JENKINS_RBPI_DEVENV:-"/home/jenkins/rbpi-dev"} + DEFAULT_XBMC_DEPENDS_ROOT=$WORKSPACE/tools/depends/xbmc-depends + DEFAULT_CONFIGURATION="Debug" + ;; +diff --git a/tools/buildsteps/rbpi/configure-depends b/tools/buildsteps/rbpi/configure-depends +index 43d7c1f..556469f 100755 +--- a/tools/buildsteps/rbpi/configure-depends ++++ b/tools/buildsteps/rbpi/configure-depends +@@ -7,25 +7,7 @@ then + cd $WORKSPACE/tools/depends; + + PATH="$PATH:$JENKINS_RBPI_DEVENV/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin" \ +- CFLAGS="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard \ +- -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated \ +- -Wno-deprecated-declarations -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vcos/pthreads \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vmcs_host/linux" \ +- CXXFLAGS="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s \ +- -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi \ +- -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vcos/pthreads \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vmcs_host/linux" \ +- LDFLAGS="-L$JENKINS_RBPI_DEVENV/firmware/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos \ +- -lvchiq_arm" \ +- ./configure --host=arm-linux-gnueabihf --prefix=$XBMC_DEPENDS_ROOT --with-tarballs=$TARBALLS \ ++ ./configure --with-platform=raspberry-pi --host=arm-linux-gnueabihf --prefix=$XBMC_DEPENDS_ROOT --with-tarballs=$TARBALLS \ + --with-toolchain=$JENKINS_RBPI_DEVENV/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/arm-bcm2708hardfp-linux-gnueabi/sysroot \ +- --build=i686-linux \ +- CFLAGS="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard \ +- -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated \ +- -Wno-deprecated-declarations -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vcos/pthreads \ +- -isystem$JENKINS_RBPI_DEVENV/firmware/opt/vc/include/interface/vmcs_host/linux" ++ --with-firmware=$JENKINS_RBPI_DEVENV/firmware --build=i686-linux + fi +diff --git a/tools/depends/Makefile.include.in b/tools/depends/Makefile.include.in +index c63ae04..560e33b 100644 +--- a/tools/depends/Makefile.include.in ++++ b/tools/depends/Makefile.include.in +@@ -18,6 +18,7 @@ ARCHIVE_TOOL_NATIVE=$(NATIVEPREFIX)/bin/tar + OS=@platform_os@ + CROSS_COMPILING=@cross_compiling@ + ARCH_DEFINES=@ARCH_DEFINES@ ++TARGET_PLATFORM=@use_platform@ + + HAS_ZLIB=@has_zlib@ + NEED_LIBICONV=@need_libiconv@ +diff --git a/tools/depends/README b/tools/depends/README +index 32d86bee..33e5672 100644 +--- a/tools/depends/README ++++ b/tools/depends/README +@@ -23,6 +23,9 @@ Android (the pathes are examples and have to match those of docs/READM.android): + Linux: + ARM toolchain (codesourcery/lenaro/etc) + ./configure --with-toolchain=/opt/toolchains/my-example-toolchain/ --prefix=/opt/xbmc-deps --host=arm-linux-gnueabi ++ RASPBERRY-PI: ++ PATH="/opt/rbp-dev/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH" ./configure --with-platform=raspberry-pi --host=arm-linux-gnueabihf --prefix=/opt/xbmc-deps --with-tarballs=/opt/xbmc-tarballs --with-toolchain=/opt/rbp-dev/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/arm-bcm2708hardfp-linux-gnueabi/sysroot --with-firmware=/opt/rbp-dev/firmware --build=i686-linux ++ + Native toolchain + ./configure --with-toolchain=/usr --prefix=/opt/xbmc-deps --host=x86_64-linux-gnu + +diff --git a/tools/depends/configure.in b/tools/depends/configure.in +index 642c708..6370fc8 100644 +--- a/tools/depends/configure.in ++++ b/tools/depends/configure.in +@@ -11,6 +11,16 @@ AC_ARG_WITH([toolchain], + [specify path to toolchain. Required for android. Defaults to xcode root for darwin, /usr for linux])], + [use_toolchain=$withval]) + ++AC_ARG_WITH([platform], ++ [AS_HELP_STRING([--with-platform], ++ [target platform [auto]])], ++ [use_platform=$withval]) ++ ++AC_ARG_WITH([firmware], ++ [AS_HELP_STRING([--with-firmware], ++ [platform specific firmware []])], ++ [use_firmware=$withval]) ++ + AC_ARG_WITH([tarballs], + [AS_HELP_STRING([--with-tarballs], + [path where tarballs will be saved [prefix/xbmc-tarballs]])], +@@ -120,14 +130,16 @@ case $host in + cross_compiling="yes" + ;; + arm*-*-linux-gnu*|arm*-*-linux-uclibc*) +- if test "x$use_cpu" = "xauto"; then +- use_cpu=$host_cpu ++ if test "$use_platform" = "auto"; then ++ if test "x$use_cpu" = "xauto"; then ++ use_cpu=$host_cpu ++ fi ++ use_toolchain="${use_toolchain:-/usr}" ++ platform_cflags="-Os -fPIC -DPIC" ++ platform_ldflags="-Wl,-rpath-link=$prefix/$deps_dir/lib" ++ platform_cxxflags="$platform_cflags" ++ platform_os="linux" + fi +- use_toolchain="${use_toolchain:-/usr}" +- platform_cflags="-Os -fPIC -DPIC" +- platform_ldflags="-Wl,-rpath-link=$prefix/$deps_dir/lib" +- platform_cxxflags="$platform_cflags" +- platform_os="linux" + ;; + *i686*-linux-gnu*|i*86*-*-linux-uclibc*) + use_cpu=$host_cpu +@@ -269,6 +281,37 @@ case $host in + AC_MSG_ERROR(unsupported host ($use_host)) + esac + ++if test "$use_platform" = "raspberry-pi"; then ++ if test -d "${use_firmware}/opt/vc/include"; then ++ : ++ else ++ AC_MSG_ERROR([Raspberry Pi firmware not found]) ++ fi ++ use_neon=no ++ use_arch="arm" ++ use_cpu="arm1176jzf-s" ++ use_hardcoded_tables="yes" ++ use_alsa="no" ++ ARCH="arm" ++ platform_os="linux" ++ cross_compiling="yes" ++ use_host="arm-linux-gnueabihf" ++ deps_dir="$use_host" ++ platform_cflags="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard \ ++ -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated \ ++ -Wno-deprecated-declarations -isystem${use_firmware}/opt/vc/include \ ++ -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" ++ platform_cxxflags="-pipe -mcpu=arm1176jzf-s -mtune=arm1176jzf-s \ ++ -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi \ ++ -Wa,-mno-warn-deprecated -Wno-deprecated-declarations \ ++ -isystem${use_firmware}/opt/vc/include \ ++ -isystem${use_firmware}/opt/vc/include/interface/vcos/pthreads \ ++ -isystem${use_firmware}/opt/vc/include/interface/vmcs_host/linux" ++ platform_ldflags="-L${use_firmware}/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos \ ++ -lvchiq_arm" ++fi ++ + XBMC_SETUP_ARCH_DEFINES() + + platform_cflags+=" $passed_cflags" +@@ -407,6 +450,7 @@ AC_SUBST(use_cpu) + AC_SUBST(use_toolchain) + AC_SUBST(use_build_toolchain) + AC_SUBST(use_tarballs) ++AC_SUBST(use_platform) + AC_SUBST(cross_compiling) + AC_SUBST(platform_cflags) + AC_SUBST(platform_cxxflags) +diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile +index 1d5f129..b1d67bc 100644 +--- a/tools/depends/target/Makefile ++++ b/tools/depends/target/Makefile +@@ -56,12 +56,12 @@ ALSA_LIB= + LINUX_SYSTEM_LIBS= + ifeq ($(OS),linux) + #not for raspberry pi +- ifneq ($(CPU),arm) ++ ifneq ($(TARGET_PLATFORM),raspberry-pi) + DEPENDS += alsa-lib libsdl linux-system-libs + ALSA_LIB = alsa-lib + LINUX_SYSTEM_LIBS = linux-system-libs +- FFMPEG_DEPENDS = gnutls + endif ++ FFMPEG_DEPENDS = gnutls + endif + + .PHONY: $(DEPENDS) +-- +1.9.3 + + +From 260baac34521d17b1374e061e3a7c7deb9ee5efe Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 25 Mar 2014 17:56:34 +0100 +Subject: [PATCH 016/122] ffmpeg: change depreciated functions + avcodev_alloc/free_frame + +--- + xbmc/cdrip/EncoderFFmpeg.cpp | 24 +++++++++++----------- + .../cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 12 +++++------ + .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 2 +- + .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 2 +- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 2 +- + xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 2 +- + xbmc/video/FFmpegVideoDecoder.cpp | 2 +- + 7 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp +index c6756e7..c581153 100644 +--- a/xbmc/cdrip/EncoderFFmpeg.cpp ++++ b/xbmc/cdrip/EncoderFFmpeg.cpp +@@ -145,11 +145,11 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + m_Buffer = (uint8_t*)av_malloc(m_NeededBytes); + m_BufferSize = 0; + +- m_BufferFrame = avcodec_alloc_frame(); ++ m_BufferFrame = av_frame_alloc(); + if(!m_BufferFrame || !m_Buffer) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate necessary buffers"); +- if(m_BufferFrame) avcodec_free_frame(&m_BufferFrame); ++ if(m_BufferFrame) av_frame_free(&m_BufferFrame); + if(m_Buffer) av_freep(&m_Buffer); + av_freep(&m_Stream); + av_freep(&m_Format->pb); +@@ -172,7 +172,7 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + if(!m_SwrCtx || swr_init(m_SwrCtx) < 0) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to initialize the resampler"); +- avcodec_free_frame(&m_BufferFrame); ++ av_frame_free(&m_BufferFrame); + av_freep(&m_Buffer); + av_freep(&m_Stream); + av_freep(&m_Format->pb); +@@ -182,14 +182,14 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + + m_ResampledBufferSize = av_samples_get_buffer_size(NULL, iInChannels, m_NeededFrames, m_OutFormat, 0); + m_ResampledBuffer = (uint8_t*)av_malloc(m_ResampledBufferSize); +- m_ResampledFrame = avcodec_alloc_frame(); ++ m_ResampledFrame = av_frame_alloc(); + if(!m_ResampledBuffer || !m_ResampledFrame) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to allocate a frame for resampling"); +- if (m_ResampledFrame) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledFrame) av_frame_free(&m_ResampledFrame); + if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); + if (m_SwrCtx) swr_free(&m_SwrCtx); +- avcodec_free_frame(&m_BufferFrame); ++ av_frame_free(&m_BufferFrame); + av_freep(&m_Buffer); + av_freep(&m_Stream); + av_freep(&m_Format->pb); +@@ -206,10 +206,10 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + if (!CEncoder::Init(strFile, iInChannels, iInRate, iInBits)) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to call CEncoder::Init"); +- if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledFrame ) av_frame_free(&m_ResampledFrame); + if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); + if (m_SwrCtx) swr_free(&m_SwrCtx); +- avcodec_free_frame(&m_BufferFrame); ++ av_frame_free(&m_BufferFrame); + av_freep(&m_Buffer); + av_freep(&m_Stream); + av_freep(&m_Format->pb); +@@ -229,10 +229,10 @@ bool CEncoderFFmpeg::Init(const char* strFile, int iInChannels, int iInRate, int + if (avformat_write_header(m_Format, NULL) != 0) + { + CLog::Log(LOGERROR, "CEncoderFFmpeg::Init - Failed to write the header"); +- if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledFrame ) av_frame_free(&m_ResampledFrame); + if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); + if (m_SwrCtx) swr_free(&m_SwrCtx); +- avcodec_free_frame(&m_BufferFrame); ++ av_frame_free(&m_BufferFrame); + av_freep(&m_Buffer); + av_freep(&m_Stream); + av_freep(&m_Format->pb); +@@ -345,10 +345,10 @@ bool CEncoderFFmpeg::Close() + + /* Flush if needed */ + av_freep(&m_Buffer); +- avcodec_free_frame(&m_BufferFrame); ++ av_frame_free(&m_BufferFrame); + + if (m_SwrCtx) swr_free(&m_SwrCtx); +- if (m_ResampledFrame ) avcodec_free_frame(&m_ResampledFrame); ++ if (m_ResampledFrame ) av_frame_free(&m_ResampledFrame); + if (m_ResampledBuffer) av_freep(&m_ResampledBuffer); + m_NeedConversion = false; + +diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +index 5d9e2fb..b3cbe4a 100644 +--- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp ++++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +@@ -286,7 +286,7 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + * sadly, we have to alloc/dealloc it everytime since we have no guarantee the + * data argument will be constant over iterated calls and the frame needs to + * setup pointers inside data */ +- frame = avcodec_alloc_frame(); ++ frame = av_frame_alloc(); + if (!frame) + return 0; + +@@ -302,7 +302,7 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + if (!m_ResampBuffer) + { + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Failed to allocate %i bytes buffer for resampling", buf_size); +- avcodec_free_frame(&frame); ++ av_frame_free(&frame); + return 0; + } + m_ResampBufferSize = buf_size; +@@ -317,7 +317,7 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + if (swr_convert(m_SwrCtx, frame->extended_data, frames, &input, frames) < 0) + { + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Resampling failed"); +- avcodec_free_frame(&frame); ++ av_frame_free(&frame); + return 0; + } + } +@@ -334,7 +334,7 @@ int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) + int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); + + /* free temporary data */ +- avcodec_free_frame(&frame); ++ av_frame_free(&frame); + + if (ret < 0 || !got_output) + { +@@ -369,7 +369,7 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz + * sadly, we have to alloc/dealloc it everytime since we have no guarantee the + * data argument will be constant over iterated calls and the frame needs to + * setup pointers inside data */ +- frame = avcodec_alloc_frame(); ++ frame = av_frame_alloc(); + if (!frame) + return 0; + +@@ -389,7 +389,7 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz + int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); + + /* free temporary data */ +- avcodec_free_frame(&frame); ++ av_frame_free(&frame); + + if (ret < 0 || !got_output) + { +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +index b23a501..4bd2c32 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -2482,7 +2482,7 @@ IAESound *CActiveAE::MakeSound(const std::string& file) + + AVPacket avpkt; + AVFrame *decoded_frame = NULL; +- decoded_frame = avcodec_alloc_frame(); ++ decoded_frame = av_frame_alloc(); + + if (avcodec_open2(dec_ctx, dec, NULL) >= 0) + { +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +index aeb3995..5fdb08b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +@@ -101,7 +101,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + return false; + } + +- m_pFrame1 = avcodec_alloc_frame(); ++ m_pFrame1 = av_frame_alloc(); + m_bOpenedCodec = true; + m_iSampleFormat = AV_SAMPLE_FMT_NONE; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 7348d5f..39076d1 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -301,7 +301,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + return false; + } + +- m_pFrame = avcodec_alloc_frame(); ++ m_pFrame = av_frame_alloc(); + if (!m_pFrame) return false; + + m_pFilterFrame = av_frame_alloc(); +diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp +index dd4c11f..b6a53a8 100644 +--- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp ++++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp +@@ -95,7 +95,7 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) + return false; + } + +- m_pFrame1 = avcodec_alloc_frame(); ++ m_pFrame1 = av_frame_alloc(); + m_bOpenedCodec = true; + m_iSampleFormat = AV_SAMPLE_FMT_NONE; + m_desiredSampleFormat = m_pCodecContext->sample_fmt == AV_SAMPLE_FMT_S16 ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLTP; +diff --git a/xbmc/video/FFmpegVideoDecoder.cpp b/xbmc/video/FFmpegVideoDecoder.cpp +index 1df859f..f25e147 100644 +--- a/xbmc/video/FFmpegVideoDecoder.cpp ++++ b/xbmc/video/FFmpegVideoDecoder.cpp +@@ -198,7 +198,7 @@ bool FFmpegVideoDecoder::open( const CStdString& filename ) + } + + // Allocate video frames +- m_pFrame = avcodec_alloc_frame(); ++ m_pFrame = av_frame_alloc(); + + if ( !m_pFrame ) + { +-- +1.9.3 + + +From 4365f5fd0148643a04404391f82f85c2306151d9 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 28 Mar 2014 08:01:54 +0100 +Subject: [PATCH 017/122] ffmpeg: change depreciated attributes qscale, qstride + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 ++-- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 6 +++--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp | 6 +++--- + xbmc/cores/omxplayer/OMXVideoCodec.h | 4 ++-- + 4 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +index d82e4bb..1553789 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -108,8 +108,8 @@ struct DVDVideoPicture + unsigned int extended_format; + char stereo_mode[32]; + +- int8_t* qscale_table; // Quantization parameters, primarily used by filters +- int qscale_stride; ++ int8_t* qp_table; // Quantization parameters, primarily used by filters ++ int qstride; + int qscale_type; + + unsigned int iWidth; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 39076d1..021d5db 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -613,10 +613,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + else + pDvdVideoPicture->color_range = 0; + +- pDvdVideoPicture->qscale_table = m_pFrame->qscale_table; +- pDvdVideoPicture->qscale_stride = m_pFrame->qstride; ++ int qscale_type; ++ pDvdVideoPicture->qp_table = av_frame_get_qp_table(m_pFrame, &pDvdVideoPicture->qstride, &qscale_type); + +- switch (m_pFrame->qscale_type) { ++ switch (qscale_type) { + case FF_QSCALE_TYPE_MPEG1: + pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1; + break; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +index a83b7d7..6ce5eb4 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +@@ -134,7 +134,7 @@ bool CDVDVideoPPFFmpeg::Process(DVDVideoPicture* pPicture) + pp_postprocess((const uint8_t**)m_pSource->data, m_pSource->iLineSize, + m_pTarget->data, m_pTarget->iLineSize, + m_pSource->iWidth, m_pSource->iHeight, +- m_pSource->qscale_table, m_pSource->qscale_stride, ++ m_pSource->qp_table, m_pSource->qstride, + m_pMode, m_pContext, + pict_type); //m_pSource->iFrameType); + +@@ -145,8 +145,8 @@ bool CDVDVideoPPFFmpeg::Process(DVDVideoPicture* pPicture) + m_pTarget->iFrameType = m_pSource->iFrameType; + m_pTarget->iRepeatPicture = m_pSource->iRepeatPicture;; + m_pTarget->iDuration = m_pSource->iDuration; +- m_pTarget->qscale_table = m_pSource->qscale_table; +- m_pTarget->qscale_stride = m_pSource->qscale_stride; ++ m_pTarget->qp_table = m_pSource->qp_table; ++ m_pTarget->qstride = m_pSource->qstride; + m_pTarget->qscale_type = m_pSource->qscale_type; + m_pTarget->iDisplayHeight = m_pSource->iDisplayHeight; + m_pTarget->iDisplayWidth = m_pSource->iDisplayWidth; +diff --git a/xbmc/cores/omxplayer/OMXVideoCodec.h b/xbmc/cores/omxplayer/OMXVideoCodec.h +index 955b780..c2ff27d 100644 +--- a/xbmc/cores/omxplayer/OMXVideoCodec.h ++++ b/xbmc/cores/omxplayer/OMXVideoCodec.h +@@ -89,8 +89,8 @@ struct DVDVideoPicture + unsigned int extended_format; + int iGroupId; + +- int8_t* qscale_table; // Quantization parameters, primarily used by filters +- int qscale_stride; ++ int8_t* qp_table; // Quantization parameters, primarily used by filters ++ int qstride; + int qscale_type; + + unsigned int iWidth; +-- +1.9.3 + + +From f2bd078deeccd4b6a3a34f656830573d9302d987 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 28 Mar 2014 08:35:57 +0100 +Subject: [PATCH 018/122] vaapi: change depreciated get_buffer, release_buffer + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 33 +++++++++++++------------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 9 +++---- + 2 files changed, 22 insertions(+), 20 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index 47c84e6..386d50a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -74,11 +74,11 @@ static int compare_version(int major_l, int minor_l, int micro_l, int major_r, i + return 0; + } + +-static void RelBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->RelBuffer(avctx, pic); } ++static void RelBufferS(void *opaque, uint8_t *data) ++{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)opaque)->GetHardware())->RelBuffer(data); } + +-static int GetBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic); } ++static int GetBufferS(AVCodecContext *avctx, AVFrame *pic, int flags) ++{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic, flags); } + + static inline VASurfaceID GetSurfaceID(AVFrame *pic) + { return (VASurfaceID)(uintptr_t)pic->data[3]; } +@@ -176,9 +176,9 @@ CDecoder::~CDecoder() + free(m_hwaccel); + } + +-void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) ++void CDecoder::RelBuffer(uint8_t *data) + { +- VASurfaceID surface = GetSurfaceID(pic); ++ VASurfaceID surface = (VASurfaceID)(uintptr_t)data; + + for(std::list::iterator it = m_surfaces_used.begin(); it != m_surfaces_used.end(); ++it) + { +@@ -189,13 +189,9 @@ void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) + break; + } + } +- pic->data[0] = NULL; +- pic->data[1] = NULL; +- pic->data[2] = NULL; +- pic->data[3] = NULL; + } + +-int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) ++int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) + { + VASurfaceID surface = GetSurfaceID(pic); + CSurface* wrapper = NULL; +@@ -245,16 +241,23 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) + m_surfaces_free.erase(it); + } + +- pic->type = FF_BUFFER_TYPE_USER; + pic->data[0] = (uint8_t*)wrapper; + pic->data[1] = NULL; + pic->data[2] = NULL; +- pic->data[3] = (uint8_t*)surface; ++ pic->data[3] = (uint8_t*)(uintptr_t)surface; + pic->linesize[0] = 0; + pic->linesize[1] = 0; + pic->linesize[2] = 0; + pic->linesize[3] = 0; + pic->reordered_opaque= avctx->reordered_opaque; ++ ++ AVBufferRef *buffer = av_buffer_create(pic->data[3], 0, RelBufferS, avctx->opaque, 0); ++ if (!buffer) ++ { ++ CLog::Log(LOGERROR, "VAAPI::%s - error creating buffer", __FUNCTION__); ++ return -1; ++ } ++ pic->buf[0] = buffer; + return 0; + } + +@@ -394,9 +397,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + + avctx->hwaccel_context = m_hwaccel; + avctx->thread_count = 1; +- avctx->get_buffer = GetBufferS; +- avctx->reget_buffer = GetBufferS; +- avctx->release_buffer = RelBufferS; ++ avctx->get_buffer2 = GetBufferS; + avctx->draw_horiz_band = NULL; + avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; + return true; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +index 9744c80..ec99162 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +@@ -21,15 +21,16 @@ + + #include "system_gl.h" + +-#include "libavcodec/avcodec.h" + #include "DVDVideoCodecFFmpeg.h" +-#include + #include + #include + #include + #include + #include + ++extern "C" { ++#include "libavcodec/vaapi.h" ++} + + namespace VAAPI { + +@@ -118,8 +119,8 @@ class CDecoder + virtual CCriticalSection* Section() { if(m_display) return m_display.get(); else return NULL; } + virtual unsigned GetAllowedReferences(); + +- int GetBuffer(AVCodecContext *avctx, AVFrame *pic); +- void RelBuffer(AVCodecContext *avctx, AVFrame *pic); ++ int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); ++ void RelBuffer(uint8_t *data); + + VADisplay GetDisplay() { return m_display->get(); } + protected: +-- +1.9.3 + + +From 1d4c12495550665c46b130474fef6d7923c23f35 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 28 Mar 2014 12:32:04 +0100 +Subject: [PATCH 019/122] vdpau: change depreciated get_buffer, release_buffer + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 79 +++++++++----------------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 14 ++--- + 2 files changed, 32 insertions(+), 61 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 5993767..e58681b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -488,7 +488,6 @@ CDecoder::CDecoder() : m_vdpauOutput(&m_inMsgEvent) + m_vdpauConfig.videoSurfaces = &m_videoSurfaces; + + m_vdpauConfigured = false; +- m_hwContext.bitstream_buffers_allocated = 0; + m_DisplayState = VDPAU_OPEN; + m_vdpauConfig.context = 0; + } +@@ -578,12 +577,8 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned + + // finally setup ffmpeg + memset(&m_hwContext, 0, sizeof(AVVDPAUContext)); +- m_hwContext.render = CDecoder::Render; +- m_hwContext.bitstream_buffers_allocated = 0; +- avctx->get_buffer = CDecoder::FFGetBuffer; +- avctx->reget_buffer = CDecoder::FFGetBuffer; +- avctx->release_buffer = CDecoder::FFReleaseBuffer; +- avctx->draw_horiz_band = CDecoder::FFDrawSlice; ++ m_hwContext.render2 = CDecoder::Render; ++ avctx->get_buffer2 = CDecoder::FFGetBuffer; + avctx->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; + avctx->hwaccel_context = &m_hwContext; + avctx->thread_count = 1; +@@ -611,11 +606,6 @@ void CDecoder::Close() + FiniVDPAUOutput(); + m_vdpauOutput.Dispose(); + +- if (m_hwContext.bitstream_buffers_allocated) +- { +- av_freep(&m_hwContext.bitstream_buffers); +- } +- + if (m_vdpauConfig.context) + m_vdpauConfig.context->Release(); + m_vdpauConfig.context = 0; +@@ -949,7 +939,7 @@ bool CDecoder::ConfigVDPAU(AVCodecContext* avctx, int ref_frames) + return true; + } + +-int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) ++int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) + { + //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); + CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; +@@ -991,59 +981,50 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) + pic->data[1] = pic->data[2] = NULL; + pic->data[0] = (uint8_t*)(uintptr_t)surf; + pic->data[3] = (uint8_t*)(uintptr_t)surf; +- + pic->linesize[0] = pic->linesize[1] = pic->linesize[2] = 0; +- +- pic->type= FF_BUFFER_TYPE_USER; ++ AVBufferRef *buffer = av_buffer_create(pic->data[3], 0, FFReleaseBuffer, ctx, 0); ++ if (!buffer) ++ { ++ CLog::Log(LOGERROR, "CVDPAU::%s - error creating buffer", __FUNCTION__); ++ return -1; ++ } ++ pic->buf[0] = buffer; + + pic->reordered_opaque= avctx->reordered_opaque; + return 0; + } + +-void CDecoder::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) ++void CDecoder::FFReleaseBuffer(void *opaque, uint8_t *data) + { +- CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; +- CDecoder* vdp = (CDecoder*)ctx->GetHardware(); ++ CDecoder *vdp = (CDecoder*)((CDVDVideoCodecFFmpeg*)opaque)->GetHardware(); + + VdpVideoSurface surf; + unsigned int i; + + CSingleLock lock(vdp->m_DecoderSection); + +- surf = (VdpVideoSurface)(uintptr_t)pic->data[3]; ++ surf = (VdpVideoSurface)(uintptr_t)data; + + vdp->m_videoSurfaces.ClearReference(surf); +- +- for(i=0; i<4; i++) +- pic->data[i]= NULL; +-} +- +-VdpStatus CDecoder::Render( VdpDecoder decoder, VdpVideoSurface target, +- VdpPictureInfo const *picture_info, +- uint32_t bitstream_buffer_count, +- VdpBitstreamBuffer const * bitstream_buffers) +-{ +- return VDP_STATUS_OK; + } + +-void CDecoder::FFDrawSlice(struct AVCodecContext *s, +- const AVFrame *src, int offset[4], +- int y, int type, int height) ++int CDecoder::Render(struct AVCodecContext *s, struct AVFrame *src, ++ const VdpPictureInfo *info, uint32_t buffers_used, ++ const VdpBitstreamBuffer *buffers) + { + CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)s->opaque; +- CDecoder* vdp = (CDecoder*)ctx->GetHardware(); ++ CDecoder* vdp = (CDecoder*)ctx->GetHardware(); + + // while we are waiting to recover we can't do anything + CSingleLock lock(vdp->m_DecoderSection); + + if(vdp->m_DisplayState != VDPAU_OPEN) +- return; ++ return -1; + +- if(src->linesize[0] || src->linesize[1] || src->linesize[2] +- || offset[0] || offset[1] || offset[2]) ++ if(src->linesize[0] || src->linesize[1] || src->linesize[2]) + { + CLog::Log(LOGERROR, "CVDPAU::FFDrawSlice - invalid linesizes or offsets provided"); +- return; ++ return -1; + } + + VdpStatus vdp_st; +@@ -1053,37 +1034,34 @@ void CDecoder::FFDrawSlice(struct AVCodecContext *s, + if (!vdp->m_videoSurfaces.IsValid(surf)) + { + CLog::Log(LOGWARNING, "CVDPAU::FFDrawSlice - ignoring invalid buffer"); +- return; ++ return -1; + } + + uint32_t max_refs = 0; + if(s->codec_id == AV_CODEC_ID_H264) +- max_refs = vdp->m_hwContext.info.h264.num_ref_frames; ++ max_refs = s->refs; + + if(vdp->m_vdpauConfig.vdpDecoder == VDP_INVALID_HANDLE + || vdp->m_vdpauConfigured == false + || vdp->m_vdpauConfig.maxReferences < max_refs) + { + if(!vdp->ConfigVDPAU(s, max_refs)) +- return; ++ return -1; + } + + uint64_t startTime = CurrentHostCounter(); + uint16_t decoded, processed, rend; + vdp->m_bufferStats.Get(decoded, processed, rend); + vdp_st = vdp->m_vdpauConfig.context->GetProcs().vdp_decoder_render(vdp->m_vdpauConfig.vdpDecoder, +- surf, +- (VdpPictureInfo const *)&(vdp->m_hwContext.info), +- vdp->m_hwContext.bitstream_buffers_used, +- vdp->m_hwContext.bitstream_buffers); ++ surf, info, buffers_used, buffers); + if (vdp->CheckStatus(vdp_st, __LINE__)) +- vdp->m_DecoderError = true; +- else +- vdp->m_DecoderError = false; ++ return -1; + + uint64_t diff = CurrentHostCounter() - startTime; + if (diff*1000/CurrentHostFrequency() > 30) + CLog::Log(LOGDEBUG, "CVDPAU::DrawSlice - VdpDecoderRender long decoding: %d ms, dec: %d, proc: %d, rend: %d", (int)((diff*1000)/CurrentHostFrequency()), decoded, processed, rend); ++ ++ return 0; + } + + +@@ -1095,9 +1073,6 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + + CSingleLock lock(m_DecoderSection); + +- if (m_DecoderError && pFrame) +- return VC_ERROR; +- + if (!m_vdpauConfigured) + return VC_ERROR; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index 86a1714..eac67b0 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -577,15 +577,11 @@ class CDecoder + EINTERLACEMETHOD AutoInterlaceMethod(); + static bool IsVDPAUFormat(PixelFormat fmt); + +- static void FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic); +- static void FFDrawSlice(struct AVCodecContext *s, +- const AVFrame *src, int offset[4], +- int y, int type, int height); +- static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic); +- static VdpStatus Render( VdpDecoder decoder, VdpVideoSurface target, +- VdpPictureInfo const *picture_info, +- uint32_t bitstream_buffer_count, +- VdpBitstreamBuffer const * bitstream_buffers); ++ static void FFReleaseBuffer(void *opaque, uint8_t *data); ++ static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); ++ static int Render(struct AVCodecContext *s, struct AVFrame *src, ++ const VdpPictureInfo *info, uint32_t buffers_used, ++ const VdpBitstreamBuffer *buffers); + + virtual void OnLostDevice(); + virtual void OnResetDevice(); +-- +1.9.3 + + +From 480278c066838e705761f814fac8112e4f749d02 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 28 Mar 2014 17:00:01 +0100 +Subject: [PATCH 020/122] dxva2: change depreciated get_buffer, release_buffer + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 27 +++++++++++++++------------ + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 4 ++-- + 2 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +index f564673..cbcec26 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +@@ -73,11 +73,11 @@ static bool LoadDXVA() + + + +-static void RelBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->RelBuffer(avctx, pic); } ++static void RelBufferS(void *opaque, uint8_t *data) ++{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)opaque)->GetHardware())->RelBuffer(data); } + +-static int GetBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic); } ++static int GetBufferS(AVCodecContext *avctx, AVFrame *pic, int flags) ++{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic, flags); } + + + DEFINE_GUID(DXVADDI_Intel_ModeH264_A, 0x604F8E64,0x4951,0x4c54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6); +@@ -696,8 +696,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + if(!OpenDecoder()) + return false; + +- avctx->get_buffer = GetBufferS; +- avctx->release_buffer = RelBufferS; ++ avctx->get_buffer2 = GetBufferS; + avctx->hwaccel_context = m_context; + + D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier(); +@@ -903,10 +902,10 @@ bool CDecoder::Supports(enum PixelFormat fmt) + return false; + } + +-void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) ++void CDecoder::RelBuffer(uint8_t *data) + { + CSingleLock lock(m_section); +- IDirect3DSurface9* surface = (IDirect3DSurface9*)pic->data[3]; ++ IDirect3DSurface9* surface = (IDirect3DSurface9*)data; + + for(unsigned i = 0; i < m_buffer_count; i++) + { +@@ -917,11 +916,9 @@ void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) + break; + } + } +- for(unsigned i = 0; i < 4; i++) +- pic->data[i] = NULL; + } + +-int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) ++int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) + { + CSingleLock lock(m_section); + if(avctx->coded_width != m_format.SampleWidth +@@ -968,7 +965,6 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) + } + + pic->reordered_opaque = avctx->reordered_opaque; +- pic->type = FF_BUFFER_TYPE_USER; + + for(unsigned i = 0; i < 4; i++) + { +@@ -978,6 +974,13 @@ int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) + + pic->data[0] = (uint8_t*)buf->surface; + pic->data[3] = (uint8_t*)buf->surface; ++ AVBufferRef *buffer = av_buffer_create(pic->data[3], 0, RelBufferS, avctx->opaque, 0); ++ if (!buffer) ++ { ++ CLog::Log(LOGERROR, "DXVA - error creating buffer"); ++ return -1; ++ } ++ pic->buf[0] = buffer; + buf->used = true; + + return 0; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +index b0025ed..b6b2096 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +@@ -62,8 +62,8 @@ class CDecoder + + bool OpenTarget(const GUID &guid); + bool OpenDecoder(); +- int GetBuffer(AVCodecContext *avctx, AVFrame *pic); +- void RelBuffer(AVCodecContext *avctx, AVFrame *pic); ++ int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); ++ void RelBuffer(uint8_t *data); + + static bool Supports(enum PixelFormat fmt); + +-- +1.9.3 + + +From 64beb1e3efca1cca3798ca2e30497ab3cc9442dc Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Thu, 17 Apr 2014 15:18:07 +0200 +Subject: [PATCH 021/122] [linux] log how ffmpeg was linked, ffmpeg version + check and logging + +--- + configure.in | 5 ++++- + tools/depends/target/ffmpeg/Makefile | 2 +- + tools/depends/target/ffmpeg/autobuild.sh | 1 + + tools/rbp/depends/ffmpeg/Makefile | 2 +- + xbmc/Application.cpp | 8 ++++++++ + xbmc/cores/FFmpeg.h | 1 + + 6 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/configure.in b/configure.in +index a324a0d..d9e0dab 100644 +--- a/configure.in ++++ b/configure.in +@@ -1721,6 +1721,10 @@ FFMPEG_LIBNAMES="libavcodec >= 55.39.101 + libswscale >= 2.5.101 + libswresample >= 0.17.104" + ++ffmpeg_build="${abs_top_srcdir}/tools/depends/target/ffmpeg" ++FFMPEG_VER_SHA=$(grep "VERSION=" ${ffmpeg_build}/FFMPEG-VERSION | sed 's/VERSION=//g') ++AC_DEFINE_UNQUOTED([FFMPEG_VER_SHA], ["$FFMPEG_VER_SHA"], [FFmpeg version hash]) ++ + if test "$with_ffmpeg" = "shared"; then + # allow linking against shared ffmpeg libs + # a proper version must be installed, we won't build ffmpeg +@@ -1741,7 +1745,6 @@ if test "${USE_STATIC_FFMPEG}" = "1"; then + fi + + if test "$cross_compiling" != "yes"; then +- ffmpeg_build="${abs_top_srcdir}/tools/depends/target/ffmpeg" + if test "$use_debug" != "yes"; then + FFMPEG_OPTS="-r" + fi +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index 8b95d5c..4abc3f0 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -7,7 +7,7 @@ DEPS= ../../Makefile.include FFMPEG-VERSION Makefile + APPLY_PATCHES=no + + # configuration settings +-ffmpg_config = --prefix=$(PREFIX) ++ffmpg_config = --prefix=$(PREFIX) --extra-version="xbmc-$(VERSION)" + ffmpg_config += --cc=$(CC) --cxx=$(CXX) + ffmpg_config += --disable-devices --disable-doc + ffmpg_config += --disable-ffplay --disable-ffmpeg +diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh +index b7a1ba6..543c10e 100755 +--- a/tools/depends/target/ffmpeg/autobuild.sh ++++ b/tools/depends/target/ffmpeg/autobuild.sh +@@ -126,6 +126,7 @@ tar --strip-components=1 -xf ../${ARCHIVE} + + CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" \ + ./configure --prefix=$FFMPEG_PREFIX \ ++ --extra-version="xbmc-${VERSION}" \ + --disable-devices \ + --disable-ffplay \ + --disable-ffmpeg \ +diff --git a/tools/rbp/depends/ffmpeg/Makefile b/tools/rbp/depends/ffmpeg/Makefile +index 93b5a02..0c11cea 100644 +--- a/tools/rbp/depends/ffmpeg/Makefile ++++ b/tools/rbp/depends/ffmpeg/Makefile +@@ -8,7 +8,7 @@ DEPS= ../../Makefile.include ../depends.mk ../../../depends/target/ffmpeg/FFMPEG + APPLY_PATCHES=no + + # configuration settings +-ffmpg_config = --sysroot=$(SYSROOT) --prefix=$(PREFIX) ++ffmpg_config = --sysroot=$(SYSROOT) --prefix=$(PREFIX) --extra-version="xbmc-$(VERSION)" + ffmpg_config += --enable-cross-compile --target-os=linux --cpu=arm1176jzf-s --arch=arm + ffmpg_config += --cc=$(CC) --cxx=$(CXX) + ffmpg_config += --disable-devices --disable-doc +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 0f649fc..98eda81 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -741,6 +741,14 @@ bool CApplication::Create() + CLog::Log(LOGNOTICE, "Running on Android %d-bit API level %d (%s, %s)", g_sysinfo.GetKernelBitness(), CJNIBuild::SDK_INT, g_sysinfo.GetLinuxDistro().c_str(), g_sysinfo.GetUnameVersion().c_str()); + #elif defined(TARGET_POSIX) + CLog::Log(LOGNOTICE, "Running on Linux %d-bit (%s, %s)", g_sysinfo.GetKernelBitness(), g_sysinfo.GetLinuxDistro().c_str(), g_sysinfo.GetUnameVersion().c_str()); ++ CLog::Log(LOGNOTICE, "FFmpeg version: %s, statically linked: %d", FFMPEG_VERSION, USE_STATIC_FFMPEG); ++if (!strstr(FFMPEG_VERSION, FFMPEG_VER_SHA)) ++{ ++ if (strstr(FFMPEG_VERSION, "xbmc")) ++ CLog::Log(LOGNOTICE, "WARNING: unknown ffmpeg-xbmc version detected"); ++ else ++ CLog::Log(LOGNOTICE, "WARNING: unsupported ffmpeg version detected"); ++} + #elif defined(TARGET_WINDOWS) + CLog::Log(LOGNOTICE, "Running on %s", g_sysinfo.GetKernelVersion().c_str()); + #endif +diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h +index 885c3b5..2a5e6be 100644 +--- a/xbmc/cores/FFmpeg.h ++++ b/xbmc/cores/FFmpeg.h +@@ -28,6 +28,7 @@ extern "C" { + #include "libavcodec/avcodec.h" + #include "libavformat/avformat.h" + #include "libavutil/avutil.h" ++#include "libavutil/ffversion.h" + #include "libavfilter/avfilter.h" + #include "libpostproc/postprocess.h" + } +-- +1.9.3 + + +From 7ff825286866069e5d33fb1baade3158d2369255 Mon Sep 17 00:00:00 2001 +From: Jonathan Marshall +Date: Fri, 25 Apr 2014 15:29:03 +1200 +Subject: [PATCH 022/122] [osx] specify target-os as 'darwin' for osx/ios, and + amend sed to be compatible with BSD + +--- + tools/depends/target/ffmpeg/Makefile | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index 4abc3f0..cb6b6be 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -37,9 +37,11 @@ endif + ifeq ($(OS), ios) + ffmpg_config += --cpu=cortex-a8 --yasmexe=$(NATIVEPREFIX)/bin/yasm + ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd ++ ffmpg_config += --target-os=darwin + endif + ifeq ($(OS), osx) + ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd ++ ffmpg_config += --target-os=darwin + endif + ifeq ($(findstring arm, $(CPU)), arm) + ffmpg_config += --enable-pic --disable-armv5te --disable-armv6t2 +@@ -59,7 +61,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE): + $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) + rm -rf $(PLATFORM); mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) +- cd $(PLATFORM); sed -i "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig\npkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure ++ cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig\npkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure + cd $(PLATFORM);\ + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ + ./configure $(ffmpg_config) +-- +1.9.3 + + +From 31b51ba939c50aefb79d1abdb2257f88b33fd185 Mon Sep 17 00:00:00 2001 +From: Jonathan Marshall +Date: Fri, 25 Apr 2014 17:20:47 +1200 +Subject: [PATCH 023/122] [osx] support building with depends ffmpeg instead of + internal + +--- + XBMC.xcodeproj/project.pbxproj | 48 +++++----------------- + tools/darwin/Configurations/App.xcconfig | 4 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp | 4 ++ + xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h | 1 - + 4 files changed, 16 insertions(+), 41 deletions(-) + +diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj +index fdd10a1..a9e4822 100644 +--- a/XBMC.xcodeproj/project.pbxproj ++++ b/XBMC.xcodeproj/project.pbxproj +@@ -359,6 +359,9 @@ + 7CDAEA8D1001EBA70040B25F /* PltIconsData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CDAEA8B1001EBA70040B25F /* PltIconsData.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; }; + 7CEBD8A80F33A0D800CAF6AD /* SpecialProtocolDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEBD8A60F33A0D800CAF6AD /* SpecialProtocolDirectory.cpp */; }; + 7CEE2E5B13D6B71E000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E5913D6B71E000ABF2A /* TimeSmoother.cpp */; }; ++ 7CF0504B190A1D7200222135 /* FFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF05049190A1D7200222135 /* FFmpeg.cpp */; }; ++ 7CF0504C190A1D7200222135 /* FFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF05049190A1D7200222135 /* FFmpeg.cpp */; }; ++ 7CF0504D190A1D7200222135 /* FFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF05049190A1D7200222135 /* FFmpeg.cpp */; }; + 7CF1FB0C123B1AF000B2CBCB /* Variant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF1FB09123B1AF000B2CBCB /* Variant.cpp */; }; + 810C9F630D67BD2F0095F5DD /* PltMediaConnect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9F600D67BD2F0095F5DD /* PltMediaConnect.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; }; + 810C9FA90D67D1FB0095F5DD /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; }; +@@ -3888,6 +3891,8 @@ + 7CEBD8A70F33A0D800CAF6AD /* SpecialProtocolDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialProtocolDirectory.h; sourceTree = ""; }; + 7CEE2E5913D6B71E000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = ""; }; + 7CEE2E5A13D6B71E000ABF2A /* TimeSmoother.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeSmoother.h; sourceTree = ""; }; ++ 7CF05049190A1D7200222135 /* FFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FFmpeg.cpp; sourceTree = ""; }; ++ 7CF0504A190A1D7200222135 /* FFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFmpeg.h; sourceTree = ""; }; + 7CF1FB09123B1AF000B2CBCB /* Variant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Variant.cpp; sourceTree = ""; }; + 7CF1FB0A123B1AF000B2CBCB /* Variant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Variant.h; sourceTree = ""; }; + 810C9F600D67BD2F0095F5DD /* PltMediaConnect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PltMediaConnect.cpp; path = MediaConnect/PltMediaConnect.cpp; sourceTree = ""; }; +@@ -7609,6 +7614,8 @@ + E38E16580D25F9FA00618676 /* VideoRenderers */, + E38E14F60D25F9F900618676 /* DummyVideoPlayer.cpp */, + E38E14F70D25F9F900618676 /* DummyVideoPlayer.h */, ++ 7CF05049190A1D7200222135 /* FFmpeg.cpp */, ++ 7CF0504A190A1D7200222135 /* FFmpeg.h */, + E38E15B50D25F9FA00618676 /* IAudioCallback.h */, + E38E15B60D25F9FA00618676 /* IPlayer.h */, + ); +@@ -10930,6 +10937,7 @@ + 7C8AE850189DE3CD00C33786 /* CoreAudioHardware.cpp in Sources */, + 7C8AE851189DE3CD00C33786 /* CoreAudioStream.cpp in Sources */, + 7C8AE854189DE47F00C33786 /* CoreAudioHelpers.cpp in Sources */, ++ 7CF0504B190A1D7200222135 /* FFmpeg.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +@@ -11978,6 +11986,7 @@ + F5CC234818150277006B5E91 /* AESinkNULL.cpp in Sources */, + F5CC238918150768006B5E91 /* AESinkProfiler.cpp in Sources */, + DF374B2518AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */, ++ 7CF0504D190A1D7200222135 /* FFmpeg.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +@@ -13028,6 +13037,7 @@ + F5CC234718150277006B5E91 /* AESinkNULL.cpp in Sources */, + F5CC238818150768006B5E91 /* AESinkProfiler.cpp in Sources */, + DF374B2418AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */, ++ 7CF0504C190A1D7200222135 /* FFmpeg.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +@@ -13124,14 +13134,6 @@ + "$(SRCROOT)/lib/libsquish", + "$(SRCROOT)/lib/SlingboxLib", + "$(SRCROOT)/xbmc/interfaces/json-rpc", +- "\"$(SRCROOT)/lib/ffmpeg/libavcodec\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavutil\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavformat\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavfilter\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavdevice\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswresample\"", +- "\"$(SRCROOT)/lib/ffmpeg/libpostproc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswscale\"", + "\"$(SRCROOT)/xbmc/interfaces/python\"", + "\"$(SRCROOT)/xbmc/interfaces/legacy\"", + ); +@@ -13259,14 +13261,6 @@ + "$(SRCROOT)/lib/libsquish", + "$(SRCROOT)/lib/SlingboxLib", + "$(SRCROOT)/xbmc/interfaces/json-rpc", +- "\"$(SRCROOT)/lib/ffmpeg/libavcodec\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavutil\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavformat\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavfilter\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavdevice\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswresample\"", +- "\"$(SRCROOT)/lib/ffmpeg/libpostproc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswscale\"", + "\"$(SRCROOT)/xbmc/interfaces/python\"", + "\"$(SRCROOT)/xbmc/interfaces/legacy\"", + ); +@@ -13409,7 +13403,6 @@ + xbmc/cores/AudioEngine, + xbmc/cores/AudioEngine/Utils, + lib, +- lib/ffmpeg, + addons/library.xbmc.addon, + $XBMC_DEPENDS/include, + $XBMC_DEPENDS/include/mysql, +@@ -13429,15 +13422,6 @@ + "\"$(SRCROOT)/lib/libsquish\"", + "\"$(SRCROOT)/lib/SlingboxLib\"", + "\"$(SRCROOT)/xbmc/interfaces/json-rpc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavcodec\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavutil\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavformat\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavfilter\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavdevice\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswresample\"", +- "\"$(SRCROOT)/lib/ffmpeg/libpostproc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswscale\"", +- "\"$(SRCROOT)/xbmc/interfaces\"", + "\"$(SRCROOT)/xbmc/interfaces/legacy\"", + "\"$(SRCROOT)/xbmc/interfaces/python\"", + ); +@@ -13525,7 +13509,6 @@ + xbmc/cores/AudioEngine, + xbmc/cores/AudioEngine/Utils, + lib, +- lib/ffmpeg, + addons/library.xbmc.addon, + $XBMC_DEPENDS/include, + $XBMC_DEPENDS/include/mysql, +@@ -13545,15 +13528,6 @@ + "\"$(SRCROOT)/lib/libsquish\"", + "\"$(SRCROOT)/lib/SlingboxLib\"", + "\"$(SRCROOT)/xbmc/interfaces/json-rpc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavcodec\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavutil\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavformat\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavfilter\"", +- "\"$(SRCROOT)/lib/ffmpeg/libavdevice\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswresample\"", +- "\"$(SRCROOT)/lib/ffmpeg/libpostproc\"", +- "\"$(SRCROOT)/lib/ffmpeg/libswscale\"", +- "\"$(SRCROOT)/xbmc/interfaces\"", + "\"$(SRCROOT)/xbmc/interfaces/legacy\"", + "\"$(SRCROOT)/xbmc/interfaces/python\"", + ); +@@ -13640,7 +13614,6 @@ + xbmc/osx, + xbmc/cores/dvdplayer, + lib, +- lib/ffmpeg, + addons/library.xbmc.addon, + $XBMC_DEPENDS/include, + $XBMC_DEPENDS/include/libcec, +@@ -13681,7 +13654,6 @@ + xbmc/osx, + xbmc/cores/dvdplayer, + lib, +- lib/ffmpeg, + addons/library.xbmc.addon, + $XBMC_DEPENDS/include, + $XBMC_DEPENDS/include/libcec, +diff --git a/tools/darwin/Configurations/App.xcconfig b/tools/darwin/Configurations/App.xcconfig +index dc4735e..3b7cf49 100644 +--- a/tools/darwin/Configurations/App.xcconfig ++++ b/tools/darwin/Configurations/App.xcconfig +@@ -20,9 +20,9 @@ + + XBMC_DEPENDS_ROOT = /Users/Shared/xbmc-depends + +-HEADER_SEARCH_PATHS = $(inherited) $SRCROOT xbmc xbmc/linux xbmc/osx xbmc/cores/dvdplayer lib lib/ffmpeg $XBMC_DEPENDS/include $XBMC_DEPENDS/include/libcec $XBMC_DEPENDS/include/mysql $XBMC_DEPENDS/include/freetype2 $XBMC_DEPENDS/include/python2.6 ++HEADER_SEARCH_PATHS = $(inherited) $SRCROOT xbmc xbmc/linux xbmc/osx xbmc/cores/dvdplayer lib $XBMC_DEPENDS/include $XBMC_DEPENDS/include/libcec $XBMC_DEPENDS/include/mysql $XBMC_DEPENDS/include/freetype2 $XBMC_DEPENDS/include/python2.6 + +-LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT) $(SRCROOT)/lib/libRTV $(SRCROOT)/lib/libXDAAP $(SRCROOT)/lib/cmyth/libcmyth $(SRCROOT)/lib/cmyth/librefmem $(SRCROOT)/lib/libsquish $(SRCROOT)/lib/SlingboxLib $(SRCROOT)/xbmc/interfaces/json-rpc "$(SRCROOT)/lib/ffmpeg/libavcodec" "$(SRCROOT)/lib/ffmpeg/libavutil" "$(SRCROOT)/lib/ffmpeg/libavformat" "$(SRCROOT)/lib/ffmpeg/libavfilter" "$(SRCROOT)/lib/ffmpeg/libavdevice" "$(SRCROOT)/lib/ffmpeg/libswresample" "$(SRCROOT)/lib/ffmpeg/libpostproc" "$(SRCROOT)/lib/ffmpeg/libswscale" "$(SRCROOT)/xbmc/interfaces/python" "$(SRCROOT)/xbmc/interfaces/legacy" ++LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT) $(SRCROOT)/lib/libRTV $(SRCROOT)/lib/libXDAAP $(SRCROOT)/lib/cmyth/libcmyth $(SRCROOT)/lib/cmyth/librefmem $(SRCROOT)/lib/libsquish $(SRCROOT)/lib/SlingboxLib $(SRCROOT)/xbmc/interfaces/json-rpc "$(SRCROOT)/xbmc/interfaces/python" "$(SRCROOT)/xbmc/interfaces/legacy" + FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/System/Library/PrivateFrameworks/" "$(SDKROOT)/System/Library/Frameworks/" + + XBMC_OTHER_LDFLAGS_COMMON = $(inherited) -Wl,-headerpad_max_install_names -Wl,-all_load -L$XBMC_DEPENDS/lib -lbz2 -lintl -lexpat -lssl -lgpg-error -lresolv -lffi -lssh -llzo2 -lpcre -lpcrecpp -lfribidi -lfreetype -lfontconfig -lsqlite3 -lsamplerate -ltinyxml -lmicrohttpd -lsmbclient -lpython2.6 -lyajl -ljpeg -lcrypto -lgcrypt -lavdevice -lavfilter -lavcodec -lavformat -lpostproc -lavutil -lswresample -lswscale -ltag -L$XBMC_DEPENDS/lib/mysql -lmysqlclient -lxml2 -lxslt +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp +index 31a118d..5538cef 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp +@@ -24,10 +24,14 @@ + #include "system_gl.h" + #include "DVDVideoCodecVDA.h" + ++extern "C" { + #include "libswscale/swscale.h" ++} ++ + #include "DVDClock.h" + #include "DVDStreamInfo.h" + #include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h" ++#include "cores/FFmpeg.h" + #include "osx/CocoaInterface.h" + #include "windowing/WindowingFactory.h" + #include "utils/BitstreamConverter.h" +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +index a7cd60a..05f2ebf 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +@@ -21,7 +21,6 @@ + + #include "system_gl.h" + +-#include "libavcodec/avcodec.h" + #include "DVDVideoCodecFFmpeg.h" + + struct vda_context; +-- +1.9.3 + + +From 16e4144de7af5a7b43698dab2b97b7c6f1243d87 Mon Sep 17 00:00:00 2001 +From: Jonathan Marshall +Date: Fri, 25 Apr 2014 17:21:02 +1200 +Subject: [PATCH 024/122] [cosmetic] drop unused variable + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 021d5db..34b371b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -671,7 +671,6 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) + int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + { + int result; +- AVBufferSinkParams *buffersink_params; + + if (m_pFilterGraph) + FilterClose(); +-- +1.9.3 + + +From ac7aae69a7688092970a58aaabd60afb796b0280 Mon Sep 17 00:00:00 2001 +From: Jonathan Marshall +Date: Fri, 25 Apr 2014 17:21:38 +1200 +Subject: [PATCH 025/122] [osx] drop deprecated get/release_buffer + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp | 36 +++++++++++++++------------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h | 4 ++-- + 2 files changed, 22 insertions(+), 18 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp +index c73661b..54de7b9 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp +@@ -22,21 +22,22 @@ + #include "osx/CocoaInterface.h" + #include "DVDVideoCodec.h" + #include "DVDCodecs/DVDCodecUtils.h" ++#include "utils/log.h" + #include "VDA.h" + + extern "C" { +- #include ++ #include "libavcodec/vda.h" + } + + using namespace std; + using namespace VDA; + + +-static void RelBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->RelBuffer(avctx, pic); } ++static void RelBufferS(void *opaque, uint8_t *data) ++{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)opaque)->GetHardware())->RelBuffer(data); } + +-static int GetBufferS(AVCodecContext *avctx, AVFrame *pic) +-{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic); } ++static int GetBufferS(AVCodecContext *avctx, AVFrame *pic, int flags) ++{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic, flags); } + + CDecoder::CDecoder() + : m_renderbuffers_count(0) +@@ -50,20 +51,25 @@ CDecoder::~CDecoder() + free(m_ctx); + } + +-void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) ++void CDecoder::RelBuffer(uint8_t *data) + { +- CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3]; ++ CVPixelBufferRef cv_buffer = (CVPixelBufferRef)data; + CVPixelBufferRelease(cv_buffer); +- +- for (int i = 0; i < 4; i++) +- pic->data[i] = NULL; + } + +-int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic) ++int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) + { +- pic->type = FF_BUFFER_TYPE_USER; +- pic->data[0] = (uint8_t *)1; ++ pic->data[3] = (uint8_t *)(uintptr_t)1; + pic->reordered_opaque = avctx->reordered_opaque; ++ ++ AVBufferRef *buffer = av_buffer_create(pic->data[3], 0, RelBufferS, avctx->opaque, 0); ++ if (!buffer) ++ { ++ CLog::Log(LOGERROR, "VAAPI::%s - error creating buffer", __FUNCTION__); ++ return -1; ++ } ++ pic->buf[0] = buffer; ++ + return 0; + } + +@@ -234,9 +240,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + + avctx->pix_fmt = fmt; + avctx->hwaccel_context = m_ctx; +- avctx->get_buffer = GetBufferS; +- avctx->release_buffer = RelBufferS; +- ++ avctx->get_buffer2 = GetBufferS; + return true; + } + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +index 05f2ebf..ad53203 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h +@@ -42,8 +42,8 @@ class CDecoder + virtual CCriticalSection* Section() { return NULL; } + virtual unsigned GetAllowedReferences(); + +- int GetBuffer(AVCodecContext *avctx, AVFrame *pic); +- void RelBuffer(AVCodecContext *avctx, AVFrame *pic); ++ int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); ++ void RelBuffer(uint8_t *data); + protected: + bool Create(AVCodecContext* avctx); + unsigned m_renderbuffers_count; +-- +1.9.3 + + +From bcfaee81d754505402c830f4352b8216ae0a96d6 Mon Sep 17 00:00:00 2001 +From: Jonathan Marshall +Date: Fri, 25 Apr 2014 17:51:12 +1200 +Subject: [PATCH 026/122] [ios] fix build + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp +index d55853a..f6d4023 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp +@@ -33,8 +33,8 @@ + #include "osx/DarwinUtils.h" + + extern "C" { +-#include "lib/libswscale/swscale.h" +-#include "lib/libavformat/avformat.h" ++#include "libswscale/swscale.h" ++#include "libavformat/avformat.h" + } + + #if defined(__cplusplus) +-- +1.9.3 + + +From 69965300543d339b919d3f5ef5432cc6c4a7e029 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 26 Apr 2014 09:37:33 +0200 +Subject: [PATCH 027/122] [depends] add neon and tegra switches + +--- + tools/depends/configure.in | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +diff --git a/tools/depends/configure.in b/tools/depends/configure.in +index 6370fc8..e849e5f 100644 +--- a/tools/depends/configure.in ++++ b/tools/depends/configure.in +@@ -31,6 +31,18 @@ AC_ARG_WITH([cpu], + [optional. specify target cpu. guessed if not specified])], + [use_cpu=$withval],use_cpu=auto) + ++AC_ARG_ENABLE([neon], ++ [AS_HELP_STRING([--enable-neon], ++ [enable neon support (default is no)])], ++ [use_neon=$enableval], ++ [use_neon=no]) ++ ++AC_ARG_ENABLE([tegra], ++ [AS_HELP_STRING([--enable-tegra], ++ [enable Tegra2 arm (default is no)])], ++ [use_tegra=$enableval], ++ [use_tegra=no]) ++ + AC_ARG_WITH([ndk], + [AS_HELP_STRING([--with-ndk], + [specify path to ndk (required for android only)])], +@@ -93,15 +105,20 @@ platform_cc=gcc + platform_cxx=g++ + case $host in + arm*-*linux-android*) +- if test "x$use_cpu" = "xauto"; then ++ if test "x$use_cpu" = "xauto" || test "x$use_cpu" = "xarmeabi-v7a"; then + use_cpu="armeabi-v7a" ++ platform_cflags+=" -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp" ++ use_neon="yes" ++ fi ++ if test "$use_neon" = "yes"; then ++ platform_cflags+="-mfpu=neon -mvectorize-with-neon-quad" ++ fi ++ if test "$use_tegra" = "yes"; then ++ platform_cflags+="-Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" + fi + use_sdk="${use_sdk:-android-14}" + deps_dir="$use_host-$use_sdk" + platform_cflags="-DANDROID -Os -fexceptions" +- if test "x$use_cpu" = "xarmeabi-v7a"; then +- platform_cflags+=" -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon" +- fi + platform_ldflags="-L$prefix/$deps_dir/lib/$use_sdk" + platform_cxxflags="$platform_cflags -frtti" + platform_includes="-I$prefix/$deps_dir/include/$use_sdk" +@@ -134,6 +151,12 @@ case $host in + if test "x$use_cpu" = "xauto"; then + use_cpu=$host_cpu + fi ++ if test "$use_neon" = "yes"; then ++ platform_cflags+="-mfpu=neon -mvectorize-with-neon-quad" ++ fi ++ if test "$use_tegra" = "yes"; then ++ platform_cflags+="-Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" ++ fi + use_toolchain="${use_toolchain:-/usr}" + platform_cflags="-Os -fPIC -DPIC" + platform_ldflags="-Wl,-rpath-link=$prefix/$deps_dir/lib" +-- +1.9.3 + + +From 8baddf30f814842ee5385344385e24418484d15a Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 26 Apr 2014 11:11:34 +0200 +Subject: [PATCH 028/122] [depends] add m4 macros for compiler flag testing + +--- + m4/ax_append_compile_flags.m4 | 100 ++++++++++++++++++++++++++++++++++++++++++ + m4/ax_append_flag.m4 | 69 +++++++++++++++++++++++++++++ + m4/ax_check_compile_flag.m4 | 74 +++++++++++++++++++++++++++++++ + m4/ax_require_defined.m4 | 37 ++++++++++++++++ + tools/depends/configure.in | 25 ++++++++--- + 5 files changed, 300 insertions(+), 5 deletions(-) + create mode 100644 m4/ax_append_compile_flags.m4 + create mode 100644 m4/ax_append_flag.m4 + create mode 100644 m4/ax_check_compile_flag.m4 + create mode 100644 m4/ax_require_defined.m4 + +diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 +new file mode 100644 +index 0000000..2723aff +--- /dev/null ++++ b/m4/ax_append_compile_flags.m4 +@@ -0,0 +1,100 @@ ++# =========================================================================== ++# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) ++# ++# DESCRIPTION ++# ++# For every FLAG1, FLAG2 it is checked whether the compiler works with the ++# flag. If it does, the flag is added FLAGS-VARIABLE ++# ++# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. ++# CFLAGS) is used. During the check the flag is always added to the ++# current language's flags. ++# ++# If EXTRA-FLAGS is defined, it is added to the current language's default ++# flags (e.g. CFLAGS) when the check is done. The check is thus made with ++# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to ++# force the compiler to issue an error when a bad flag is given. ++# ++# NOTE: This macro depends on the AX_APPEND_FLAG and ++# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with ++# AX_APPEND_LINK_FLAGS. ++# ++# LICENSE ++# ++# Copyright (c) 2011 Maarten Bosmans ++# ++# This program 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 3 of the License, or (at your ++# option) any later version. ++# ++# This program 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, see . ++# ++# As a special exception, the respective Autoconf Macro's copyright owner ++# gives unlimited permission to copy, distribute and modify the configure ++# scripts that are the output of Autoconf when processing the Macro. You ++# need not follow the terms of the GNU General Public License when using ++# or distributing such scripts, even though portions of the text of the ++# Macro appear in them. The GNU General Public License (GPL) does govern ++# all other use of the material that constitutes the Autoconf Macro. ++# ++# This special exception to the GPL applies to versions of the Autoconf ++# Macro released by the Autoconf Archive. When you make and distribute a ++# modified version of the Autoconf Macro, you may extend this special ++# exception to the GPL to apply to your modified version as well. ++ ++#serial 4 ++ ++AC_DEFUN([AX_APPEND_COMPILE_FLAGS], ++[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) ++AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) ++for flag in $1; do ++ AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3]) ++done ++])dnl AX_APPEND_COMPILE_FLAGS ++ ++ ++AC_DEFUN([AX_APPEND_FLAG], ++[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX ++AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl ++AS_VAR_SET_IF(FLAGS, ++ [case " AS_VAR_GET(FLAGS) " in ++ *" $1 "*) ++ AC_RUN_LOG([: FLAGS already contains $1]) ++ ;; ++ *) ++ AC_RUN_LOG([: FLAGS="$FLAGS $1"]) ++ AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) ++ ;; ++ esac], ++ [AS_VAR_SET(FLAGS,["$1"])]) ++AS_VAR_POPDEF([FLAGS])dnl ++])dnl AX_APPEND_FLAG ++ ++ ++AC_DEFUN([AX_CHECK_COMPILE_FLAG], ++[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX ++AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl ++AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ++ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS ++ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" ++ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], ++ [AS_VAR_SET(CACHEVAR,[yes])], ++ [AS_VAR_SET(CACHEVAR,[no])]) ++ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) ++AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], ++ [m4_default([$2], :)], ++ [m4_default([$3], :)]) ++AS_VAR_POPDEF([CACHEVAR])dnl ++])dnl AX_CHECK_COMPILE_FLAGS +diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 +new file mode 100644 +index 0000000..1d38b76 +--- /dev/null ++++ b/m4/ax_append_flag.m4 +@@ -0,0 +1,69 @@ ++# =========================================================================== ++# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) ++# ++# DESCRIPTION ++# ++# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space ++# added in between. ++# ++# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. ++# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains ++# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly ++# FLAG. ++# ++# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. ++# ++# LICENSE ++# ++# Copyright (c) 2008 Guido U. Draheim ++# Copyright (c) 2011 Maarten Bosmans ++# ++# This program 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 3 of the License, or (at your ++# option) any later version. ++# ++# This program 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, see . ++# ++# As a special exception, the respective Autoconf Macro's copyright owner ++# gives unlimited permission to copy, distribute and modify the configure ++# scripts that are the output of Autoconf when processing the Macro. You ++# need not follow the terms of the GNU General Public License when using ++# or distributing such scripts, even though portions of the text of the ++# Macro appear in them. The GNU General Public License (GPL) does govern ++# all other use of the material that constitutes the Autoconf Macro. ++# ++# This special exception to the GPL applies to versions of the Autoconf ++# Macro released by the Autoconf Archive. When you make and distribute a ++# modified version of the Autoconf Macro, you may extend this special ++# exception to the GPL to apply to your modified version as well. ++ ++#serial 2 ++ ++AC_DEFUN([AX_APPEND_FLAG], ++[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX ++AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl ++AS_VAR_SET_IF(FLAGS, ++ [case " AS_VAR_GET(FLAGS) " in ++ *" $1 "*) ++ AC_RUN_LOG([: FLAGS already contains $1]) ++ ;; ++ *) ++ AC_RUN_LOG([: FLAGS="$FLAGS $1"]) ++ AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) ++ ;; ++ esac], ++ [AS_VAR_SET(FLAGS,["$1"])]) ++AS_VAR_POPDEF([FLAGS])dnl ++])dnl AX_APPEND_FLAG +diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 +new file mode 100644 +index 0000000..51df0c0 +--- /dev/null ++++ b/m4/ax_check_compile_flag.m4 +@@ -0,0 +1,74 @@ ++# =========================================================================== ++# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) ++# ++# DESCRIPTION ++# ++# Check whether the given FLAG works with the current language's compiler ++# or gives an error. (Warnings, however, are ignored) ++# ++# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on ++# success/failure. ++# ++# If EXTRA-FLAGS is defined, it is added to the current language's default ++# flags (e.g. CFLAGS) when the check is done. The check is thus made with ++# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to ++# force the compiler to issue an error when a bad flag is given. ++# ++# INPUT gives an alternative input source to AC_COMPILE_IFELSE. ++# ++# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this ++# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. ++# ++# LICENSE ++# ++# Copyright (c) 2008 Guido U. Draheim ++# Copyright (c) 2011 Maarten Bosmans ++# ++# This program 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 3 of the License, or (at your ++# option) any later version. ++# ++# This program 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, see . ++# ++# As a special exception, the respective Autoconf Macro's copyright owner ++# gives unlimited permission to copy, distribute and modify the configure ++# scripts that are the output of Autoconf when processing the Macro. You ++# need not follow the terms of the GNU General Public License when using ++# or distributing such scripts, even though portions of the text of the ++# Macro appear in them. The GNU General Public License (GPL) does govern ++# all other use of the material that constitutes the Autoconf Macro. ++# ++# This special exception to the GPL applies to versions of the Autoconf ++# Macro released by the Autoconf Archive. When you make and distribute a ++# modified version of the Autoconf Macro, you may extend this special ++# exception to the GPL to apply to your modified version as well. ++ ++#serial 3 ++ ++AC_DEFUN([AX_CHECK_COMPILE_FLAG], ++[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX ++AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl ++AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ++ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS ++ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" ++ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], ++ [AS_VAR_SET(CACHEVAR,[yes])], ++ [AS_VAR_SET(CACHEVAR,[no])]) ++ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) ++AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], ++ [m4_default([$2], :)], ++ [m4_default([$3], :)]) ++AS_VAR_POPDEF([CACHEVAR])dnl ++])dnl AX_CHECK_COMPILE_FLAGS +diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 +new file mode 100644 +index 0000000..cae1111 +--- /dev/null ++++ b/m4/ax_require_defined.m4 +@@ -0,0 +1,37 @@ ++# =========================================================================== ++# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_REQUIRE_DEFINED(MACRO) ++# ++# DESCRIPTION ++# ++# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have ++# been defined and thus are available for use. This avoids random issues ++# where a macro isn't expanded. Instead the configure script emits a ++# non-fatal: ++# ++# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found ++# ++# It's like AC_REQUIRE except it doesn't expand the required macro. ++# ++# Here's an example: ++# ++# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) ++# ++# LICENSE ++# ++# Copyright (c) 2014 Mike Frysinger ++# ++# Copying and distribution of this file, with or without modification, are ++# permitted in any medium without royalty provided the copyright notice ++# and this notice are preserved. This file is offered as-is, without any ++# warranty. ++ ++#serial 1 ++ ++AC_DEFUN([AX_REQUIRE_DEFINED], [dnl ++ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) ++])dnl AX_REQUIRE_DEFINED +diff --git a/tools/depends/configure.in b/tools/depends/configure.in +index e849e5f..5a75ba6 100644 +--- a/tools/depends/configure.in ++++ b/tools/depends/configure.in +@@ -5,6 +5,11 @@ AC_CONFIG_AUX_DIR([build-aux]) + AC_CONFIG_FILES([target/config.site native/config.site.native Makefile.include target/Toolchain.cmake]) + AC_CANONICAL_HOST + m4_include([../../m4/xbmc_arch.m4]) ++m4_include([../../m4/ax_require_defined.m4]) ++m4_include([../../m4/ax_append_flag.m4]) ++m4_include([../../m4/ax_check_compile_flag.m4]) ++m4_include([../../m4/ax_append_compile_flags.m4]) ++ + + AC_ARG_WITH([toolchain], + [AS_HELP_STRING([--with-toolchain], +@@ -107,14 +112,19 @@ case $host in + arm*-*linux-android*) + if test "x$use_cpu" = "xauto" || test "x$use_cpu" = "xarmeabi-v7a"; then + use_cpu="armeabi-v7a" +- platform_cflags+=" -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp" ++ AX_APPEND_COMPILE_FLAGS([$passed_cflags -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp], [platform_cflags]) + use_neon="yes" + fi + if test "$use_neon" = "yes"; then +- platform_cflags+="-mfpu=neon -mvectorize-with-neon-quad" ++ AX_APPEND_COMPILE_FLAGS([$passed_cflags -mfpu=neon -mvectorize-with-neon-quad], [platform_cflags]) + fi + if test "$use_tegra" = "yes"; then +- platform_cflags+="-Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" ++ AX_CHECK_COMPILE_FLAG(-mfpu=vfpv3-d16, ++ [AX_APPEND_COMPILE_FLAGS([$passed_cflags -Wno-psabi -Wa,-march=arv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork], ++ [platform_cflags])], ++ [AX_APPEND_COMPILE_FLAGS([$passed_cflags -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork], ++ [platform_cflags])], ++ ) + fi + use_sdk="${use_sdk:-android-14}" + deps_dir="$use_host-$use_sdk" +@@ -152,10 +162,15 @@ case $host in + use_cpu=$host_cpu + fi + if test "$use_neon" = "yes"; then +- platform_cflags+="-mfpu=neon -mvectorize-with-neon-quad" ++ AX_APPEND_COMPILE_FLAGS([$passed_cflags -mfpu=neon -mvectorize-with-neon-quad], [platform_cflags]) + fi + if test "$use_tegra" = "yes"; then +- platform_cflags+="-Wno-psabi -Wa,-march=armv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork" ++ AX_CHECK_COMPILE_FLAG(-mfpu=vfpv3-d16, ++ [AX_APPEND_COMPILE_FLAGS([$passed_cflags -Wno-psabi -Wa,-march=arv7a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mthumb-interwork], ++ [platform_cflags])], ++ [AX_APPEND_COMPILE_FLAGS([$passed_cflags -Wa,-march=armv6 -mtune=cortex-a8 -mthumb-interwork], ++ [platform_cflags])], ++ ) + fi + use_toolchain="${use_toolchain:-/usr}" + platform_cflags="-Os -fPIC -DPIC" +-- +1.9.3 + + +From e4d8effb4b935176b146940636a36316c2c0e072 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Mon, 28 Apr 2014 07:56:07 +0200 +Subject: [PATCH 029/122] [jenkins] - enable-neon for android + +--- + tools/buildsteps/android/configure-depends | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/buildsteps/android/configure-depends b/tools/buildsteps/android/configure-depends +index 73f9be5..0847e50 100644 +--- a/tools/buildsteps/android/configure-depends ++++ b/tools/buildsteps/android/configure-depends +@@ -11,5 +11,6 @@ then + --with-ndk=$NDK_PATH \ + $(if [ "$SDK_VERSION" != "Default" ]; then echo --with-sdk=android-$SDK_VERSION;fi) \ + --with-toolchain=$TOOLCHAIN \ +- --prefix=$XBMC_DEPENDS_ROOT ++ --prefix=$XBMC_DEPENDS_ROOT \ ++ --enable-neon + fi +-- +1.9.3 + + +From 1bd2995aad332fbabe675262457226293118de0e Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:34:39 +0200 +Subject: [PATCH 030/122] videoplayer: adapt lateness detection and dropping to + buffering + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 16 +- + xbmc/cores/VideoRenderers/RenderManager.h | 12 +- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 15 +- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 31 ++++ + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 + + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 194 +++++++++++++++++---- + xbmc/cores/dvdplayer/DVDPlayerVideo.h | 23 +++ + 7 files changed, 260 insertions(+), 38 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index 6832721..f4b381e 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -286,6 +286,8 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi + m_bIsStarted = true; + m_bReconfigured = true; + m_presentstep = PRESENT_IDLE; ++ m_presentpts = DVD_NOPTS_VALUE; ++ m_sleeptime = 1.0; + m_presentevent.notifyAll(); + + m_firstFlipPage = false; // tempfix +@@ -629,7 +631,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) + m_pRenderer->SetViewMode(iViewMode); + } + +-void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) ++void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) + { + { CSharedLock lock(m_sharedSection); + +@@ -697,6 +699,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + m.timestamp = timestamp; + m.presentfield = sync; + m.presentmethod = presentmethod; ++ m.pts = pts; + requeue(m_queued, m_free); + + /* signal to any waiters to check state */ +@@ -1065,6 +1068,8 @@ void CXBMCRenderManager::PrepareNextRender() + m_discard.push_back(m_presentsource); + m_presentsource = idx; + m_queued.pop_front(); ++ m_sleeptime = m_Queue[idx].timestamp - clocktime; ++ m_presentpts = m_Queue[idx].pts; + m_presentevent.notifyAll(); + } + } +@@ -1081,3 +1086,12 @@ void CXBMCRenderManager::DiscardBuffer() + m_presentstep = PRESENT_IDLE; + m_presentevent.notifyAll(); + } ++ ++bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel) ++{ ++ CSingleLock lock(m_presentlock); ++ sleeptime = m_sleeptime; ++ pts = m_presentpts; ++ bufferLevel = m_queued.size() + m_discard.size(); ++ return true; ++} +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index c469795..949c652b 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -98,10 +98,11 @@ class CXBMCRenderManager + * + * @param bStop reference to stop flag of calling thread + * @param timestamp of frame delivered with AddVideoPicture ++ * @param pts used for lateness detection + * @param source depreciated + * @param sync signals frame, top, or bottom field + */ +- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); ++ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); + unsigned int PreInit(); + void UnInit(); + bool Flush(); +@@ -176,6 +177,12 @@ class CXBMCRenderManager + int WaitForBuffer(volatile bool& bStop, int timeout = 100); + + /** ++ * Can be called by player for lateness detection. This is done best by ++ * looking at the end of the queue. ++ */ ++ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); ++ ++ /** + * Video player call this on flush in oder to discard any queued frames + */ + void DiscardBuffer(); +@@ -222,6 +229,7 @@ class CXBMCRenderManager + + struct SPresent + { ++ double pts; + double timestamp; + EFIELDSYNC presentfield; + EPRESENTMETHOD presentmethod; +@@ -233,6 +241,8 @@ class CXBMCRenderManager + + ERenderFormat m_format; + ++ double m_sleeptime; ++ double m_presentpts; + double m_presentcorr; + double m_presenterr; + double m_errorbuff[ERRORBUFFSIZE]; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +index 1553789..7761f7fa 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -134,6 +134,10 @@ struct DVDVideoUserData + #define DVP_FLAG_NOSKIP 0x00000010 // indicate this picture should never be dropped + #define DVP_FLAG_DROPPED 0x00000020 // indicate that this picture has been dropped in decoder stage, will have no data + ++#define DVP_FLAG_DROPDEINT 0x00000040 // indicate that this picture was requested to have been dropped in deint stage ++#define DVP_FLAG_NO_POSTPROC 0x00000100 ++#define DVP_FLAG_DRAIN 0x00000200 ++ + // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2! + + #define DVP_QSCALE_UNKNOWN 0 +@@ -151,6 +155,9 @@ class CDVDCodecOptions; + #define VC_PICTURE 0x00000004 // the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data + #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data + #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again ++#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped ++#define VC_HURRY 0x00000040 ++ + class CDVDVideoCodec + { + public: +@@ -268,7 +275,6 @@ class CDVDVideoCodec + return 0; + } + +- + /** + * Number of references to old pictures that are allowed to + * be retained when calling decode on the next demux packet +@@ -285,4 +291,11 @@ class CDVDVideoCodec + * Interact with user settings so that user disabled codecs are disabled + */ + static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id); ++ ++ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) ++ { ++ return false; ++ } ++ ++ virtual void SetCodecControl(int flags) {} + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 34b371b..afe133c 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -167,6 +167,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() + m_iLastKeyframe = 0; + m_dts = DVD_NOPTS_VALUE; + m_started = false; ++ m_decoderPts = DVD_NOPTS_VALUE; + } + + CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() +@@ -339,6 +340,14 @@ void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop) + { + if( m_pCodecContext ) + { ++ if (bDrop && m_pHardware && m_pHardware->CanSkipDeint()) ++ { ++ m_requestSkipDeint = true; ++ bDrop = false; ++ } ++ else ++ m_requestSkipDeint = false; ++ + // i don't know exactly how high this should be set + // couldn't find any good docs on it. think it varies + // from codec to codec on what it does +@@ -540,6 +549,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + void CDVDVideoCodecFFmpeg::Reset() + { + m_started = false; ++ m_decoderPts = DVD_NOPTS_VALUE; + m_iLastKeyframe = m_pCodecContext->has_b_frames; + avcodec_flush_buffers(m_pCodecContext); + +@@ -637,6 +647,22 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + else + pDvdVideoPicture->pts = DVD_NOPTS_VALUE; + ++ if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE) ++ m_decoderPts = pDvdVideoPicture->pts; ++ else ++ m_decoderPts = m_dts; ++ ++ if (m_requestSkipDeint) ++ { ++ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPDEINT; ++ m_skippedDeint = 1; ++ } ++ else ++ m_skippedDeint = 0; ++ ++ m_requestSkipDeint = false; ++ pDvdVideoPicture->iFlags |= m_codecControlFlags; ++ + if(!m_started) + pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; + +@@ -818,3 +844,8 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences() + else + return 0; + } ++ ++void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) ++{ ++ m_codecControlFlags = flags; ++} +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index ab5e565..ed98955 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -50,6 +50,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + virtual int Check (AVCodecContext* avctx) = 0; + virtual void Reset () {} + virtual unsigned GetAllowedReferences() { return 0; } ++ virtual bool CanSkipDeint() {return false; } + virtual const std::string Name() = 0; + virtual CCriticalSection* Section() { return NULL; } + }; +@@ -67,6 +68,8 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open + virtual unsigned GetConvergeCount(); + virtual unsigned GetAllowedReferences(); ++ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} ++ virtual void SetCodecControl(int flags); + + bool IsHardwareAllowed() { return !m_bSoftware; } + IHardwareDecoder * GetHardware() { return m_pHardware; }; +@@ -122,4 +125,8 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + double m_dts; + bool m_started; + std::vector m_formats; ++ double m_decoderPts, m_decoderInterval; ++ int m_skippedDeint; ++ bool m_requestSkipDeint; ++ int m_codecControlFlags; + }; +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 99b3155..4fad1a3 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -38,6 +38,7 @@ + #include "DVDCodecs/DVDCodecs.h" + #include "DVDCodecs/Overlay/DVDOverlayCodecCC.h" + #include "DVDCodecs/Overlay/DVDOverlaySSA.h" ++#include "guilib/GraphicContext.h" + #include + #include + #include +@@ -320,8 +321,10 @@ void CDVDPlayerVideo::Process() + + int iDropped = 0; //frames dropped in a row + bool bRequestDrop = false; ++ int iDropDirective; + + m_videoStats.Start(); ++ m_droppingStats.Reset(); + + while (!m_bStop) + { +@@ -431,6 +434,7 @@ void CDVDPlayerVideo::Process() + picture.iFlags &= ~DVP_FLAG_ALLOCATED; + m_packets.clear(); + m_started = false; ++ m_droppingStats.Reset(); + } + else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) + { +@@ -443,6 +447,7 @@ void CDVDPlayerVideo::Process() + //we need to recalculate the framerate + //TODO: this needs to be set on a streamchange instead + ResetFrameRateCalc(); ++ m_droppingStats.Reset(); + + m_stalled = true; + m_started = false; +@@ -460,8 +465,10 @@ void CDVDPlayerVideo::Process() + m_speed = static_cast(pMsg)->m_value; + if(m_speed == DVD_PLAYSPEED_PAUSE) + m_iNrOfPicturesNotToSkip = 0; ++ + if (m_pVideoCodec) + m_pVideoCodec->SetSpeed(m_speed); ++ m_droppingStats.Reset(); + } + else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) + { +@@ -507,6 +514,28 @@ void CDVDPlayerVideo::Process() + m_iNrOfPicturesNotToSkip = 1; + } + ++ bRequestDrop = false; ++ iDropDirective = CalcDropRequirement(pts); ++ if (iDropDirective & EOS_VERYLATE) ++ { ++ if (m_bAllowDrop) ++ { ++ m_pullupCorrection.Flush(); ++ bRequestDrop = true; ++ } ++ } ++ int codecControl = 0; ++ if (iDropDirective & EOS_BUFFER_LEVEL) ++ codecControl |= DVP_FLAG_DRAIN; ++ if (m_speed > DVD_PLAYSPEED_NORMAL) ++ codecControl |= DVP_FLAG_NO_POSTPROC; ++ m_pVideoCodec->SetCodecControl(codecControl); ++ if (iDropDirective & EOS_DROPPED) ++ { ++ m_iDroppedFrames++; ++ iDropped++; ++ } ++ + if (m_messageQueue.GetDataSize() == 0 + || m_speed < 0) + { +@@ -559,15 +588,7 @@ void CDVDPlayerVideo::Process() + } + + m_videoStats.AddSampleBytes(pPacket->iSize); +- // assume decoder dropped a picture if it didn't give us any +- // picture from a demux packet, this should be reasonable +- // for libavformat as a demuxer as it normally packetizes +- // pictures when they come from demuxer +- if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE)) +- { +- m_iDroppedFrames++; +- iDropped++; +- } ++ + // reset the request, the following while loop may break before + // setting the flag to a new value + bRequestDrop = false; +@@ -1176,33 +1197,12 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + m_FlipTimeStamp += max(0.0, iSleepTime); + m_FlipTimeStamp += iFrameDuration; + +- if (iSleepTime <= 0 && m_speed) +- m_iLateFrames++; +- else +- m_iLateFrames = 0; +- +- // ask decoder to drop frames next round, as we are very late +- if(m_iLateFrames > 10) ++ if ((pPicture->iFlags & DVP_FLAG_DROPPED)) + { +- if (!(pPicture->iFlags & DVP_FLAG_NOSKIP)) +- { +- //if we're calculating the framerate, +- //don't drop frames until we've calculated a stable framerate +- if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL) +- { +- result |= EOS_VERYLATE; +- m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it +- } +- m_iDroppedRequest++; +- } +- } +- else +- { +- m_iDroppedRequest = 0; +- } +- +- if( (pPicture->iFlags & DVP_FLAG_DROPPED) ) ++ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); ++ CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__); + return result | EOS_DROPPED; ++ } + + // set fieldsync if picture is interlaced + EFIELDSYNC mDisplayField = FS_NONE; +@@ -1235,7 +1235,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + if (index < 0) + return EOS_DROPPED; + +- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); ++ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); + + return result; + #else +@@ -1535,3 +1535,127 @@ void CDVDPlayerVideo::CalcFrameRate() + m_iFrameRateCount = 0; + } + } ++ ++int CDVDPlayerVideo::CalcDropRequirement(double pts) ++{ ++ int result = 0; ++ double iSleepTime; ++ double iDecoderPts, iRenderPts; ++ double iInterval; ++ int interlaced; ++ double iGain; ++ double iLateness; ++ bool bNewFrame; ++ int iSkippedDeint = 0; ++ int iBufferLevel; ++ ++ // get decoder stats ++ if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) ++ iDecoderPts = pts; ++ if (iDecoderPts == DVD_NOPTS_VALUE) ++ iDecoderPts = pts; ++ ++ // get render stats ++ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); ++ ++ if (iBufferLevel < 0) ++ result |= EOS_BUFFER_LEVEL; ++ else if (iBufferLevel < 2) ++ { ++ result |= EOS_BUFFER_LEVEL; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - hurry: %d", iBufferLevel); ++ } ++ ++ bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts; ++ ++ if (interlaced) ++ iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE; ++ else ++ iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; ++ ++ if (m_droppingStats.m_lastDecoderPts > 0 ++ && bNewFrame ++ && m_bAllowDrop ++ && m_droppingStats.m_dropRequests > 0) ++ { ++ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE; ++ if (iSkippedDeint) ++ { ++ CDroppingStats::CGain gain; ++ gain.gain = 1/m_fFrameRate; ++ gain.pts = iDecoderPts; ++ m_droppingStats.m_gain.push_back(gain); ++ m_droppingStats.m_totalGain += gain.gain; ++ result |= EOS_DROPPED; ++ m_droppingStats.m_dropRequests = 0; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped de-interlacing cycle, Sleeptime: %f, Bufferlevel: %d", iSleepTime, iBufferLevel); ++ } ++ else if (iGain > 1/m_fFrameRate) ++ { ++ CDroppingStats::CGain gain; ++ gain.gain = iGain; ++ gain.pts = iDecoderPts; ++ m_droppingStats.m_gain.push_back(gain); ++ m_droppingStats.m_totalGain += iGain; ++ result |= EOS_DROPPED; ++ m_droppingStats.m_dropRequests = 0; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped in decoder, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain); ++ } ++ } ++ m_droppingStats.m_lastDecoderPts = iDecoderPts; ++ ++ // subtract gains ++ while (!m_droppingStats.m_gain.empty() && ++ iRenderPts >= m_droppingStats.m_gain.front().pts) ++ { ++ m_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().gain; ++ m_droppingStats.m_gain.pop_front(); ++ } ++ ++ // calculate lateness ++ iLateness = iSleepTime + m_droppingStats.m_totalGain; ++ if (iLateness < 0 && m_speed) ++ { ++ if (bNewFrame) ++ m_droppingStats.m_lateFrames++; ++ ++ // if lateness is smaller than frametime, we observe this state ++ // for 10 cycles ++ if (m_droppingStats.m_lateFrames > 10 || iLateness < -2/m_fFrameRate) ++ { ++ // is frame allowed to skip ++ if (m_iNrOfPicturesNotToSkip <= 0) ++ { ++ result |= EOS_VERYLATE; ++ if (bNewFrame) ++ m_droppingStats.m_dropRequests++; ++ } ++ } ++ } ++ else ++ { ++ m_droppingStats.m_dropRequests = 0; ++ m_droppingStats.m_lateFrames = 0; ++ } ++ m_droppingStats.m_lastRenderPts = iRenderPts; ++ return result; ++} ++ ++void CDroppingStats::Reset() ++{ ++ m_gain.clear(); ++ m_totalGain = 0; ++ m_lastDecoderPts = 0; ++ m_lastRenderPts = 0; ++ m_lateFrames = 0; ++ m_dropRequests = 0; ++} ++ ++void CDroppingStats::AddOutputDropGain(double pts, double frametime) ++{ ++ CDroppingStats::CGain gain; ++ gain.gain = frametime; ++ gain.pts = pts; ++ m_gain.push_back(gain); ++ m_totalGain += frametime; ++} +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +index f8ad541..186e271 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +@@ -36,6 +36,25 @@ class CDVDOverlayCodecCC; + + #define VIDEO_PICTURE_QUEUE_SIZE 1 + ++class CDroppingStats ++{ ++public: ++ void Reset(); ++ void AddOutputDropGain(double pts, double frametime); ++ struct CGain ++ { ++ double gain; ++ double pts; ++ }; ++ std::deque m_gain; ++ double m_totalGain; ++ double m_lastDecoderPts; ++ double m_lastRenderPts; ++ unsigned int m_lateFrames; ++ unsigned int m_dropRequests; ++}; ++ ++ + class CDVDPlayerVideo : public CThread + { + public: +@@ -104,6 +123,7 @@ class CDVDPlayerVideo : public CThread + #define EOS_ABORT 1 + #define EOS_DROPPED 2 + #define EOS_VERYLATE 4 ++#define EOS_BUFFER_LEVEL 8 + + void AutoCrop(DVDVideoPicture* pPicture); + void AutoCrop(DVDVideoPicture *pPicture, RECT &crop); +@@ -129,6 +149,7 @@ class CDVDPlayerVideo : public CThread + + void ResetFrameRateCalc(); + void CalcFrameRate(); ++ int CalcDropRequirement(double pts); + + double m_fFrameRate; //framerate of the video currently playing + bool m_bCalcFrameRate; //if we should calculate the framerate from the timestamps +@@ -182,5 +203,7 @@ class CDVDPlayerVideo : public CThread + CPullupCorrection m_pullupCorrection; + + std::list m_packets; ++ ++ CDroppingStats m_droppingStats; + }; + +-- +1.9.3 + + +From bf0544fa3f1fedb6b0bd152c19f296e1f92f10d0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 2 Sep 2012 16:05:21 +0200 +Subject: [PATCH 031/122] video player: present correct pts to user for a/v + sync (after buffering in renderer) + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 25 +++++++++++++++++++++++++ + xbmc/cores/dvdplayer/DVDPlayerVideo.h | 2 +- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 4fad1a3..1d29b6f 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1455,6 +1455,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc() + g_advancedSettings.m_videoFpsDetect == 0; + } + ++double CDVDPlayerVideo::GetCurrentPts() ++{ ++ double iSleepTime, iRenderPts; ++ int iBufferLevel; ++ ++ // get render stats ++ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); ++ ++ if( m_stalled ) ++ iRenderPts = DVD_NOPTS_VALUE; ++ else ++ iRenderPts = iRenderPts - max(0.0, iSleepTime); ++ ++ return iRenderPts; ++} ++ + #define MAXFRAMERATEDIFF 0.01 + #define MAXFRAMESERR 1000 + +@@ -1573,6 +1589,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) + else + iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; + ++ ++ m_FlipTimeStamp = m_pClock->GetAbsoluteClock() + max(0.0, iSleepTime) + iInterval; ++ ++ if( m_stalled ) ++ m_iCurrentPts = DVD_NOPTS_VALUE; ++ else ++ m_iCurrentPts = iRenderPts - max(0.0, iSleepTime); ++ ++ + if (m_droppingStats.m_lastDecoderPts > 0 + && bNewFrame + && m_bAllowDrop +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +index 186e271..59c7f09 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +@@ -100,7 +100,7 @@ class CDVDPlayerVideo : public CThread + + bool InitializedOutputDevice(); + +- double GetCurrentPts() { return m_iCurrentPts; } ++ double GetCurrentPts(); + int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); } + + double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */ +-- +1.9.3 + + +From eaff1ef5b113e475c4fe2faefeef3e210fb7f923 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 16 Feb 2013 18:25:53 +0100 +Subject: [PATCH 032/122] videoplayer: some rework and documentation + +--- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 28 ++++++++++++++++++++-- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 11 +++++++++ + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 4 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +index 7761f7fa..2fbc656 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -156,7 +156,6 @@ class CDVDCodecOptions; + #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data + #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again + #define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped +-#define VC_HURRY 0x00000040 + + class CDVDVideoCodec + { +@@ -292,10 +291,35 @@ class CDVDVideoCodec + */ + static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id); + +- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) ++ /* For calculation of dropping requirements player asks for some information. ++ * ++ * - pts : right after decoder, used to detect gaps (dropped frames in decoder) ++ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle ++ * instead of dropping a full frame ++ * - interlaced : when detecting gaps in pts, player needs to know whether ++ * it's interlaced or not ++ * ++ * If codec does not implement this method, pts of decoded frame at input ++ * video player is used. In case coded does post-proc and de-interlacing there ++ * may be quite some frames queued up between exit decoder and entry player. ++ */ ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced) + { + return false; + } + ++ /** ++ * Codec can be informed by player with the following flags: ++ * ++ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off ++ * postprocessing and de-interlacing ++ * ++ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing. ++ * If video buffers in RenderManager are about to run dry, ++ * this is signaled to codec. Codec can wait for post-proc ++ * to be finished instead of returning empty and getting another ++ * packet. ++ * ++ */ + virtual void SetCodecControl(int flags) {} + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index afe133c..3b384f4 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -845,6 +845,17 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences() + return 0; + } + ++bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced) ++{ ++ pts = m_decoderPts; ++ skippedDeint = m_skippedDeint; ++ if (m_pFrame) ++ interlaced = m_pFrame->interlaced_frame; ++ else ++ interlaced = 0; ++ return true; ++} ++ + void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) + { + m_codecControlFlags = flags; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index ed98955..95c6489 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -68,7 +68,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open + virtual unsigned GetConvergeCount(); + virtual unsigned GetAllowedReferences(); +- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced); + virtual void SetCodecControl(int flags); + + bool IsHardwareAllowed() { return !m_bSoftware; } +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 1d29b6f..ee07f30 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1566,7 +1566,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) + int iBufferLevel; + + // get decoder stats +- if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) ++ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) + iDecoderPts = pts; + if (iDecoderPts == DVD_NOPTS_VALUE) + iDecoderPts = pts; +-- +1.9.3 + + +From cf1b51d0d37b23525ef36043c78433272fea8194 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 1 Jun 2013 11:21:19 +0200 +Subject: [PATCH 033/122] renderer: bump buffers to 5 + +--- + xbmc/cores/VideoRenderers/BaseRenderer.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h +index dc2712a..9edfbd4 100644 +--- a/xbmc/cores/VideoRenderers/BaseRenderer.h ++++ b/xbmc/cores/VideoRenderers/BaseRenderer.h +@@ -29,7 +29,7 @@ + + #define MAX_PLANES 3 + #define MAX_FIELDS 3 +-#define NUM_BUFFERS 3 ++#define NUM_BUFFERS 5 + + class CSetting; + +-- +1.9.3 + + +From 2e789870e5c4153dbf0d0e1afab067e5cb13f3e0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:41:31 +0200 +Subject: [PATCH 034/122] videoplayer: update frametime, it might change due to + fps detection + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index ee07f30..b3175cd 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -708,6 +708,8 @@ void CDVDPlayerVideo::Process() + + int iResult = OutputPicture(&picture, pts); + ++ frametime = (double)DVD_TIME_BASE/m_fFrameRate; ++ + if(m_started == false) + { + m_codecname = m_pVideoCodec->GetName(); +-- +1.9.3 + + +From 1a0fc0a5a4906687269d6fb02414eb772474e098 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:43:06 +0200 +Subject: [PATCH 035/122] videoplayer: give streams with invalid fps a chance + for fps detection + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index b3175cd..9c36bdb 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1497,7 +1497,7 @@ void CDVDPlayerVideo::CalcFrameRate() + double frameduration = m_pullupCorrection.GetFrameDuration(); + + if (frameduration == DVD_NOPTS_VALUE || +- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) ++ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) + { + //reset the stored framerates if no good framerate was detected + m_fStableFrameRate = 0.0; +-- +1.9.3 + + +From 9a193f6e56733fd6d5331fe6164de640d056f423 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:49:05 +0200 +Subject: [PATCH 036/122] dvdplayer: allow rewinding at end of stream, do a + seek after rewind + +--- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index 3f2e0df..097af37 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -1633,7 +1633,7 @@ void CDVDPlayer::HandlePlaySpeed() + + } + else if (m_CurrentVideo.id >= 0 +- && m_CurrentVideo.inited == true ++ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file + && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() + && m_SpeedState.lasttime != GetTime()) + { +@@ -2294,6 +2294,12 @@ void CDVDPlayer::HandleMessages() + pvrinputstream->Pause( speed == 0 ); + } + ++ // do a seek after rewind, clock is not in sync with current pts ++ if (m_playSpeed < 0 && speed >= 0) ++ { ++ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); ++ } ++ + // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE + // audioplayer, stops outputing audio to audiorendere, but still tries to + // sleep an correct amount for each packet +-- +1.9.3 + + +From b77c46bb894868ccab05e40ac84fb6fcf2d88d44 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:22:05 +0200 +Subject: [PATCH 037/122] X11: ditch SDL for video and window events + +--- + xbmc/Application.cpp | 2 +- + xbmc/system.h | 5 + + xbmc/windowing/Makefile.in | 1 + + xbmc/windowing/WinEvents.cpp | 4 + + xbmc/windowing/WinEventsX11.cpp | 784 ++++++++++++++++++++++++++++++++++++ + xbmc/windowing/WinEventsX11.h | 65 +++ + xbmc/windowing/X11/WinSystemX11.cpp | 386 ++++++++++++------ + xbmc/windowing/X11/WinSystemX11.h | 10 +- + 8 files changed, 1129 insertions(+), 128 deletions(-) + create mode 100644 xbmc/windowing/WinEventsX11.cpp + create mode 100644 xbmc/windowing/WinEventsX11.h + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 98eda81..46993d5 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -938,7 +938,7 @@ bool CApplication::CreateGUI() + + uint32_t sdlFlags = 0; + +-#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2) ++#if (defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)) && !defined(HAS_GLX) + sdlFlags |= SDL_INIT_VIDEO; + #endif + +diff --git a/xbmc/system.h b/xbmc/system.h +index 1f4e15f..075e44a 100644 +--- a/xbmc/system.h ++++ b/xbmc/system.h +@@ -171,16 +171,21 @@ + #define HAS_GL + #ifdef HAVE_X11 + #define HAS_GLX ++#define HAS_X11_WIN_EVENTS + #endif + #ifdef HAVE_SDL + #define HAS_SDL + #ifndef HAS_SDL_OPENGL + #define HAS_SDL_OPENGL + #endif ++#ifndef HAVE_X11 + #define HAS_SDL_WIN_EVENTS ++#endif + #else ++#ifndef HAVE_X11 + #define HAS_LINUX_EVENTS + #endif ++#endif + #define HAS_LINUX_NETWORK + #define HAS_LIRC + #ifdef HAVE_LIBPULSE +diff --git a/xbmc/windowing/Makefile.in b/xbmc/windowing/Makefile.in +index 6704967..4b41723 100644 +--- a/xbmc/windowing/Makefile.in ++++ b/xbmc/windowing/Makefile.in +@@ -1,6 +1,7 @@ + SRCS=WinEventsSDL.cpp \ + WinEventsLinux.cpp \ + WinEventsWayland.cpp \ ++ WinEventsX11.cpp \ + WinSystem.cpp \ + WinEvents.cpp + +diff --git a/xbmc/windowing/WinEvents.cpp b/xbmc/windowing/WinEvents.cpp +index 1022ad2..8e64497 100644 +--- a/xbmc/windowing/WinEvents.cpp ++++ b/xbmc/windowing/WinEvents.cpp +@@ -42,6 +42,10 @@ + #include "WinEventsSDL.h" + #define WinEventsType CWinEventsSDL + ++#elif (defined(TARGET_FREEBSD) || defined(TARGET_LINUX)) && defined(HAS_X11_WIN_EVENTS) ++#include "WinEventsX11.h" ++#define WinEventsType CWinEventsX11 ++ + #elif defined(HAVE_WAYLAND) + #include "WinEventsWayland.h" + #define WinEventsType CWinEventsWayland +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +new file mode 100644 +index 0000000..ad58aad +--- /dev/null ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -0,0 +1,784 @@ ++/* ++* Copyright (C) 2005-2012 Team XBMC ++* http://www.xbmc.org ++* ++* This Program 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, or (at your option) ++* any later version. ++* ++* This Program 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 XBMC; see the file COPYING. If not, write to ++* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++* http://www.gnu.org/copyleft/gpl.html ++* ++*/ ++ ++#include "system.h" ++ ++#ifdef HAS_X11_WIN_EVENTS ++ ++#include "WinEvents.h" ++#include "WinEventsX11.h" ++#include "Application.h" ++#include "ApplicationMessenger.h" ++#include ++#include "X11/WinSystemX11GL.h" ++#include "X11/keysymdef.h" ++#include "X11/XF86keysym.h" ++#include "utils/log.h" ++#include "guilib/GUIWindowManager.h" ++#include "input/MouseStat.h" ++ ++CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0; ++ ++static uint32_t SymMappingsX11[][2] = ++{ ++ {XK_BackSpace, XBMCK_BACKSPACE} ++, {XK_Tab, XBMCK_TAB} ++, {XK_Clear, XBMCK_CLEAR} ++, {XK_Return, XBMCK_RETURN} ++, {XK_Pause, XBMCK_PAUSE} ++, {XK_Escape, XBMCK_ESCAPE} ++, {XK_Delete, XBMCK_DELETE} ++// multi-media keys ++, {XF86XK_Back, XBMCK_BROWSER_BACK} ++, {XF86XK_Forward, XBMCK_BROWSER_FORWARD} ++, {XF86XK_Refresh, XBMCK_BROWSER_REFRESH} ++, {XF86XK_Stop, XBMCK_BROWSER_STOP} ++, {XF86XK_Search, XBMCK_BROWSER_SEARCH} ++, {XF86XK_Favorites, XBMCK_BROWSER_FAVORITES} ++, {XF86XK_HomePage, XBMCK_BROWSER_HOME} ++, {XF86XK_AudioMute, XBMCK_VOLUME_MUTE} ++, {XF86XK_AudioLowerVolume, XBMCK_VOLUME_DOWN} ++, {XF86XK_AudioRaiseVolume, XBMCK_VOLUME_UP} ++, {XF86XK_AudioNext, XBMCK_MEDIA_NEXT_TRACK} ++, {XF86XK_AudioPrev, XBMCK_MEDIA_PREV_TRACK} ++, {XF86XK_AudioStop, XBMCK_MEDIA_STOP} ++, {XF86XK_AudioPause, XBMCK_MEDIA_PLAY_PAUSE} ++, {XF86XK_Mail, XBMCK_LAUNCH_MAIL} ++, {XF86XK_Select, XBMCK_LAUNCH_MEDIA_SELECT} ++, {XF86XK_Launch0, XBMCK_LAUNCH_APP1} ++, {XF86XK_Launch1, XBMCK_LAUNCH_APP2} ++, {XF86XK_WWW, XBMCK_LAUNCH_FILE_BROWSER} ++, {XF86XK_AudioMedia, XBMCK_LAUNCH_MEDIA_CENTER } ++ // Numeric keypad ++, {XK_KP_0, XBMCK_KP0} ++, {XK_KP_1, XBMCK_KP1} ++, {XK_KP_2, XBMCK_KP2} ++, {XK_KP_3, XBMCK_KP3} ++, {XK_KP_4, XBMCK_KP4} ++, {XK_KP_5, XBMCK_KP5} ++, {XK_KP_6, XBMCK_KP6} ++, {XK_KP_7, XBMCK_KP7} ++, {XK_KP_8, XBMCK_KP8} ++, {XK_KP_9, XBMCK_KP9} ++, {XK_KP_Separator, XBMCK_KP_PERIOD} ++, {XK_KP_Divide, XBMCK_KP_DIVIDE} ++, {XK_KP_Multiply, XBMCK_KP_MULTIPLY} ++, {XK_KP_Subtract, XBMCK_KP_MINUS} ++, {XK_KP_Add, XBMCK_KP_PLUS} ++, {XK_KP_Enter, XBMCK_KP_ENTER} ++, {XK_KP_Equal, XBMCK_KP_EQUALS} ++ // Arrows + Home/End pad ++, {XK_Up, XBMCK_UP} ++, {XK_Down, XBMCK_DOWN} ++, {XK_Right, XBMCK_RIGHT} ++, {XK_Left, XBMCK_LEFT} ++, {XK_Insert, XBMCK_INSERT} ++, {XK_Home, XBMCK_HOME} ++, {XK_End, XBMCK_END} ++, {XK_Page_Up, XBMCK_PAGEUP} ++, {XK_Page_Down, XBMCK_PAGEDOWN} ++ // Function keys ++, {XK_F1, XBMCK_F1} ++, {XK_F2, XBMCK_F2} ++, {XK_F3, XBMCK_F3} ++, {XK_F4, XBMCK_F4} ++, {XK_F5, XBMCK_F5} ++, {XK_F6, XBMCK_F6} ++, {XK_F7, XBMCK_F7} ++, {XK_F8, XBMCK_F8} ++, {XK_F9, XBMCK_F9} ++, {XK_F10, XBMCK_F10} ++, {XK_F11, XBMCK_F11} ++, {XK_F12, XBMCK_F12} ++, {XK_F13, XBMCK_F13} ++, {XK_F14, XBMCK_F14} ++, {XK_F15, XBMCK_F15} ++ // Key state modifier keys ++, {XK_Num_Lock, XBMCK_NUMLOCK} ++, {XK_Caps_Lock, XBMCK_CAPSLOCK} ++, {XK_Scroll_Lock, XBMCK_SCROLLOCK} ++, {XK_Shift_R, XBMCK_RSHIFT} ++, {XK_Shift_L, XBMCK_LSHIFT} ++, {XK_Control_R, XBMCK_RCTRL} ++, {XK_Control_L, XBMCK_LCTRL} ++, {XK_Alt_R, XBMCK_RALT} ++, {XK_Alt_L, XBMCK_LALT} ++, {XK_Meta_R, XBMCK_RMETA} ++, {XK_Meta_L, XBMCK_LMETA} ++, {XK_Super_L, XBMCK_LSUPER} ++, {XK_Super_R, XBMCK_RSUPER} ++, {XK_Mode_switch, XBMCK_MODE} ++, {XK_Multi_key, XBMCK_COMPOSE} ++ // Miscellaneous function keys ++, {XK_Help, XBMCK_HELP} ++, {XK_Print, XBMCK_PRINT} ++//, {0, XBMCK_SYSREQ} ++, {XK_Break, XBMCK_BREAK} ++, {XK_Menu, XBMCK_MENU} ++, {XF86XK_PowerOff, XBMCK_POWER} ++, {XK_EcuSign, XBMCK_EURO} ++, {XK_Undo, XBMCK_UNDO} ++ /* Media keys */ ++, {XF86XK_Eject, XBMCK_EJECT} ++, {XF86XK_Stop, XBMCK_STOP} ++, {XF86XK_AudioRecord, XBMCK_RECORD} ++, {XF86XK_AudioRewind, XBMCK_REWIND} ++, {XF86XK_Phone, XBMCK_PHONE} ++, {XF86XK_AudioPlay, XBMCK_PLAY} ++, {XF86XK_AudioRandomPlay, XBMCK_SHUFFLE} ++, {XF86XK_AudioForward, XBMCK_FASTFORWARD} ++}; ++ ++bool CWinEventsX11::MessagePump() ++{ ++ return CWinEventsX11Imp::MessagePump(); ++} ++ ++size_t CWinEventsX11::GetQueueSize() ++{ ++ return CWinEventsX11Imp::GetQueueSize(); ++} ++ ++CWinEventsX11Imp::CWinEventsX11Imp() ++{ ++ m_display = 0; ++ m_window = 0; ++ m_keybuf = 0; ++ m_utf16buf = 0; ++} ++ ++CWinEventsX11Imp::~CWinEventsX11Imp() ++{ ++ if (m_keybuf); ++ { ++ free(m_keybuf); ++ m_keybuf = 0; ++ } ++ ++ if (m_utf16buf) ++ { ++ free(m_utf16buf); ++ m_utf16buf = 0; ++ } ++ ++ if (m_xic) ++ { ++ XUnsetICFocus(m_xic); ++ XDestroyIC(m_xic); ++ m_xic = 0; ++ } ++ ++ if (m_xim) ++ { ++ XCloseIM(m_xim); ++ m_xim = 0; ++ } ++ ++ m_symLookupTable.clear(); ++} ++ ++bool CWinEventsX11Imp::Init(Display *dpy, Window win) ++{ ++ if (WinEvents) ++ return true; ++ ++ WinEvents = new CWinEventsX11Imp(); ++ WinEvents->m_display = dpy; ++ WinEvents->m_window = win; ++ WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); ++ WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); ++ WinEvents->m_keymodState = 0; ++ WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); ++ WinEvents->m_structureChanged = false; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); ++ ++ // open input method ++ char *old_locale = NULL, *old_modifiers = NULL; ++ char res_name[8]; ++ const char *p; ++ size_t n; ++ ++ // set resource name to xbmc, not used ++ strcpy(res_name, "xbmc"); ++ ++ // save current locale, this should be "C" ++ p = setlocale(LC_ALL, NULL); ++ if (p) ++ { ++ old_locale = (char*)malloc(strlen(p) +1); ++ strcpy(old_locale, p); ++ } ++ p = XSetLocaleModifiers(NULL); ++ if (p) ++ { ++ old_modifiers = (char*)malloc(strlen(p) +1); ++ strcpy(old_modifiers, p); ++ } ++ ++ // set users preferences and open input method ++ p = setlocale(LC_ALL, ""); ++ XSetLocaleModifiers(""); ++ WinEvents->m_xim = XOpenIM(WinEvents->m_display, NULL, res_name, res_name); ++ ++ // restore old locale ++ if (old_locale) ++ { ++ setlocale(LC_ALL, old_locale); ++ free(old_locale); ++ } ++ if (old_modifiers) ++ { ++ XSetLocaleModifiers(old_modifiers); ++ free(old_modifiers); ++ } ++ ++ WinEvents->m_xic = NULL; ++ if (WinEvents->m_xim) ++ { ++ WinEvents->m_xic = XCreateIC(WinEvents->m_xim, ++ XNClientWindow, WinEvents->m_window, ++ XNFocusWindow, WinEvents->m_window, ++ XNInputStyle, XIMPreeditNothing | XIMStatusNothing, ++ XNResourceName, res_name, ++ XNResourceClass, res_name, ++ NULL); ++ } ++ ++ if (!WinEvents->m_xic) ++ CLog::Log(LOGWARNING,"CWinEventsX11::Init - no input method found"); ++ ++ // build Keysym lookup table ++ for (unsigned int i = 0; i < sizeof(SymMappingsX11)/(2*sizeof(uint32_t)); ++i) ++ { ++ WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; ++ } ++ ++ return true; ++} ++ ++void CWinEventsX11Imp::Quit() ++{ ++ if (!WinEvents) ++ return; ++ ++ delete WinEvents; ++ WinEvents = 0; ++} ++ ++bool CWinEventsX11Imp::HasStructureChanged() ++{ ++ if (!WinEvents) ++ return false; ++ ++ bool ret = WinEvents->m_structureChanged; ++ WinEvents->m_structureChanged = false; ++ return ret; ++} ++ ++bool CWinEventsX11Imp::MessagePump() ++{ ++ if (!WinEvents) ++ return false; ++ ++ bool ret = false; ++ XEvent xevent; ++ unsigned long serial = 0; ++ ++ while (WinEvents && XPending(WinEvents->m_display)) ++ { ++ memset(&xevent, 0, sizeof (XEvent)); ++ XNextEvent(WinEvents->m_display, &xevent); ++ ++ // ignore events generated by auto-repeat ++ if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) ++ { ++ XEvent peekevent; ++ XPeekEvent(WinEvents->m_display, &peekevent); ++ if ((peekevent.type == KeyPress) && ++ (peekevent.xkey.keycode == xevent.xkey.keycode) && ++ ((peekevent.xkey.time - xevent.xkey.time) < 2)) ++ { ++ XNextEvent(WinEvents->m_display, &peekevent); ++ continue; ++ } ++ } ++ ++ if (XFilterEvent(&xevent, None)) ++ continue; ++ ++ switch (xevent.type) ++ { ++ case MapNotify: ++ { ++ g_application.SetRenderGUI(true); ++ break; ++ } ++ ++ case UnmapNotify: ++ { ++ g_application.SetRenderGUI(false); ++ break; ++ } ++ ++ case FocusIn: ++ { ++ if (WinEvents->m_xic) ++ XSetICFocus(WinEvents->m_xic); ++ g_application.m_AppFocused = true; ++ if (serial == xevent.xfocus.serial) ++ break; ++ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); ++ break; ++ } ++ ++ case FocusOut: ++ { ++ if (WinEvents->m_xic) ++ XUnsetICFocus(WinEvents->m_xic); ++ g_application.m_AppFocused = false; ++ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); ++ serial = xevent.xfocus.serial; ++ break; ++ } ++ ++ case Expose: ++ { ++ g_windowManager.MarkDirty(); ++ break; ++ } ++ ++ case ConfigureNotify: ++ { ++ if (xevent.xconfigure.window != WinEvents->m_window) ++ break; ++ ++ WinEvents->m_structureChanged = true; ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_VIDEORESIZE; ++ newEvent.resize.w = xevent.xconfigure.width; ++ newEvent.resize.h = xevent.xconfigure.height; ++ ret |= g_application.OnEvent(newEvent); ++ g_windowManager.MarkDirty(); ++ break; ++ } ++ ++ case ClientMessage: ++ { ++ if (xevent.xclient.data.l[0] == WinEvents->m_wmDeleteMessage) ++ if (!g_application.m_bStop) CApplicationMessenger::Get().Quit(); ++ break; ++ } ++ ++ case KeyPress: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_KEYDOWN; ++ KeySym xkeysym; ++ ++ // fallback if we have no IM ++ if (!WinEvents->m_xic) ++ { ++ static XComposeStatus state; ++ char keybuf[32]; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ if (XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state)) ++ { ++ newEvent.key.keysym.unicode = keybuf[0]; ++ } ++ ret |= ProcessKey(newEvent, 500); ++ break; ++ } ++ ++ Status status; ++ int utf16size; ++ int utf16length; ++ int len; ++ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, ++ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), ++ &xkeysym, &status); ++ if (status == XBufferOverflow) ++ { ++ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); ++ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, ++ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), ++ &xkeysym, &status); ++ } ++ switch (status) ++ { ++ case XLookupNone: ++ break; ++ case XLookupChars: ++ case XLookupBoth: ++ { ++ if (len == 0) ++ break; ++ utf16size = len * sizeof(uint16_t); ++ if (utf16size > sizeof(WinEvents->m_utf16buf)) ++ { ++ WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); ++ if (WinEvents->m_utf16buf == NULL) ++ { ++ break; ++ } ++ } ++ utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); ++ if (utf16length < 0) ++ { ++ break; ++ } ++ for (unsigned int i = 0; i < utf16length - 1; i++) ++ { ++ newEvent.key.keysym.sym = XBMCK_UNKNOWN; ++ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 500); ++ } ++ if (utf16length > 0) ++ { ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ++ ret |= ProcessKey(newEvent, 500); ++ } ++ break; ++ } ++ ++ case XLookupKeySym: ++ { ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 500); ++ break; ++ } ++ ++ }// switch status ++ break; ++ } //KeyPress ++ ++ case KeyRelease: ++ { ++ XBMC_Event newEvent; ++ KeySym xkeysym; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_KEYUP; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 0); ++ break; ++ } ++ ++ // lose mouse coverage ++ case LeaveNotify: ++ { ++ g_Mouse.SetActive(false); ++ break; ++ } ++ ++ case MotionNotify: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEMOTION; ++ newEvent.motion.xrel = (int16_t)xevent.xmotion.x_root; ++ newEvent.motion.yrel = (int16_t)xevent.xmotion.y_root; ++ newEvent.motion.x = (int16_t)xevent.xmotion.x; ++ newEvent.motion.y = (int16_t)xevent.xmotion.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ case ButtonPress: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEBUTTONDOWN; ++ newEvent.button.button = (unsigned char)xevent.xbutton.button; ++ newEvent.button.state = XBMC_PRESSED; ++ newEvent.button.x = (int16_t)xevent.xbutton.x; ++ newEvent.button.y = (int16_t)xevent.xbutton.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ case ButtonRelease: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEBUTTONUP; ++ newEvent.button.button = (unsigned char)xevent.xbutton.button; ++ newEvent.button.state = XBMC_RELEASED; ++ newEvent.button.x = (int16_t)xevent.xbutton.x; ++ newEvent.button.y = (int16_t)xevent.xbutton.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ default: ++ { ++ break; ++ } ++ }// switch event.type ++ }// while ++ ++ ret |= ProcessKeyRepeat(); ++ ++ return ret; ++} ++ ++size_t CWinEventsX11Imp::GetQueueSize() ++{ ++ int ret = 0; ++ ++ if (WinEvents) ++ ret = XPending(WinEvents->m_display); ++ ++ return ret; ++} ++ ++bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) ++{ ++ if (event.type == XBMC_KEYDOWN) ++ { ++ // check key modifiers ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_LSHIFT: ++ WinEvents->m_keymodState |= XBMCKMOD_LSHIFT; ++ break; ++ case XBMCK_RSHIFT: ++ WinEvents->m_keymodState |= XBMCKMOD_RSHIFT; ++ break; ++ case XBMCK_LCTRL: ++ WinEvents->m_keymodState |= XBMCKMOD_LCTRL; ++ break; ++ case XBMCK_RCTRL: ++ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LALT: ++ WinEvents->m_keymodState |= XBMCKMOD_LALT; ++ break; ++ case XBMCK_RALT: ++ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LMETA: ++ WinEvents->m_keymodState |= XBMCKMOD_LMETA; ++ break; ++ case XBMCK_RMETA: ++ WinEvents->m_keymodState |= XBMCKMOD_RMETA; ++ break; ++ case XBMCK_MODE: ++ WinEvents->m_keymodState |= XBMCKMOD_MODE; ++ break; ++ default: ++ break; ++ } ++ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; ++ memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); ++ WinEvents->m_repeatKeyTimeout.Set(repeatDelay); ++ ++ bool ret = ProcessShortcuts(event); ++ if (ret) ++ return ret; ++ } ++ else if (event.type == XBMC_KEYUP) ++ { ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_LSHIFT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LSHIFT; ++ break; ++ case XBMCK_RSHIFT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RSHIFT; ++ break; ++ case XBMCK_LCTRL: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LCTRL; ++ break; ++ case XBMCK_RCTRL: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LALT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LALT; ++ break; ++ case XBMCK_RALT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LMETA: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LMETA; ++ break; ++ case XBMCK_RMETA: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RMETA; ++ break; ++ case XBMCK_MODE: ++ WinEvents->m_keymodState &= ~XBMCKMOD_MODE; ++ break; ++ default: ++ break; ++ } ++ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(event)); ++ } ++ ++ return g_application.OnEvent(event); ++} ++ ++bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) ++{ ++ if (event.key.keysym.mod & XBMCKMOD_ALT) ++ { ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_TAB: // ALT+TAB to minimize/hide ++ g_application.Minimize(); ++ return true; ++ ++ default: ++ return false; ++ } ++ } ++ return false; ++} ++ ++bool CWinEventsX11Imp::ProcessKeyRepeat() ++{ ++ if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) ++ { ++ if (WinEvents->m_repeatKeyTimeout.IsTimePast()) ++ { ++ return ProcessKey(WinEvents->m_lastKey, 10); ++ } ++ } ++ return false; ++} ++ ++int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) ++{ ++ // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. ++ uint16_t *p = utf16; ++ uint16_t const *const maxPtr = utf16 + utf16MaxLength; ++ ++ // end_of_input points to the last byte of input as opposed to the next to the last byte. ++ char const *const endOfInput = utf8 + utf8Length - 1; ++ ++ while (utf8 <= endOfInput) ++ { ++ unsigned char const c = *utf8; ++ if (p >= maxPtr) ++ { ++ //No more output space. ++ return -1; ++ } ++ if (c < 0x80) ++ { ++ //One byte ASCII. ++ *p++ = c; ++ utf8 += 1; ++ } ++ else if (c < 0xC0) ++ { ++ // Follower byte without preceding leader bytes. ++ return -1; ++ } ++ // 11 bits ++ else if (c < 0xE0) ++ { ++ // Two byte sequence. We need one follower byte. ++ if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) ++ { ++ return -1; ++ } ++ *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); ++ utf8 += 2; ++ } ++ // 16 bis ++ else if (c < 0xF0) ++ { ++ // Three byte sequence. We need two follower byte. ++ if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) ++ { ++ return -1; ++ } ++ *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); ++ utf8 += 3; ++ } ++ // 21 bits ++ else if (c < 0xF8) ++ { ++ int plane; ++ // Four byte sequence. We need three follower bytes. ++ if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || ++ ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) ++ { ++ return -1; ++ } ++ uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + ++ ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); ++ utf8 += 4; ++ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); ++ } ++ // 26 bits ++ else if (c < 0xFC) ++ { ++ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); ++ utf8 += 5; ++ } ++ // 31 bit ++ else ++ { ++ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); ++ utf8 += 6; ++ } ++ } ++ return p - utf16; ++} ++ ++XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) ++{ ++ // try direct mapping first ++ std::map::iterator it; ++ it = WinEvents->m_symLookupTable.find(keysym); ++ if (it != WinEvents->m_symLookupTable.end()) ++ { ++ return (XBMCKey)(it->second); ++ } ++ ++ // try ascii mappings ++ if (keysym>>8 == 0x00) ++ return (XBMCKey)(keysym & 0xFF); ++ ++ return (XBMCKey)keysym; ++} ++#endif +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +new file mode 100644 +index 0000000..ce57c23 +--- /dev/null ++++ b/xbmc/windowing/WinEventsX11.h +@@ -0,0 +1,65 @@ ++/* ++* Copyright (C) 2005-2012 Team XBMC ++* http://www.xbmc.org ++* ++* This Program 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, or (at your option) ++* any later version. ++* ++* This Program 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 XBMC; see the file COPYING. If not, write to ++* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++* http://www.gnu.org/copyleft/gpl.html ++* ++*/ ++#pragma once ++ ++#include "WinEvents.h" ++#include ++#include "threads/SystemClock.h" ++#include ++ ++class CWinEventsX11 : public IWinEvents ++{ ++public: ++ virtual bool MessagePump(); ++ virtual size_t GetQueueSize(); ++}; ++ ++class CWinEventsX11Imp ++{ ++public: ++ CWinEventsX11Imp(); ++ virtual ~CWinEventsX11Imp(); ++ static bool Init(Display *dpy, Window win); ++ static void Quit(); ++ static bool HasStructureChanged(); ++ static bool MessagePump(); ++ static size_t GetQueueSize(); ++ ++protected: ++ static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); ++ static XBMCKey LookupXbmcKeySym(KeySym keysym); ++ static bool ProcessKey(XBMC_Event &event, int repeatDelay); ++ static bool ProcessKeyRepeat(); ++ static bool ProcessShortcuts(XBMC_Event& event); ++ static CWinEventsX11Imp *WinEvents; ++ Display *m_display; ++ Window m_window; ++ Atom m_wmDeleteMessage; ++ char *m_keybuf; ++ uint16_t *m_utf16buf; ++ XIM m_xim; ++ XIC m_xic; ++ XBMC_Event m_lastKey; ++ XbmcThreads::EndTime m_repeatKeyTimeout; ++ std::map m_symLookupTable; ++ int m_keymodState; ++ bool m_structureChanged; ++}; +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 54379ea..40b8403 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -22,7 +22,6 @@ + + #ifdef HAS_GLX + +-#include + #include "WinSystemX11.h" + #include "settings/DisplaySettings.h" + #include "settings/Settings.h" +@@ -34,7 +33,6 @@ + #include "XRandR.h" + #include + #include "threads/SingleLock.h" +-#include + #include "cores/VideoRenderers/RenderManager.h" + #include "utils/TimeUtils.h" + #include "utils/StringUtils.h" +@@ -43,19 +41,22 @@ + #include + #endif + ++#include "../WinEventsX11.h" ++#include "input/MouseStat.h" ++ + using namespace std; + + CWinSystemX11::CWinSystemX11() : CWinSystemBase() + { + m_eWindowSystem = WINDOW_SYSTEM_X11; + m_glContext = NULL; +- m_SDLSurface = NULL; + m_dpy = NULL; + m_glWindow = 0; +- m_wmWindow = 0; + m_bWasFullScreenBeforeMinimize = false; + m_minimized = false; ++ m_bIgnoreNextFocusMessage = false; + m_dpyLostTime = 0; ++ m_invisibleCursor = 0; + + XSetErrorHandler(XErrorHandler); + } +@@ -68,18 +69,6 @@ bool CWinSystemX11::InitWindowSystem() + { + if ((m_dpy = XOpenDisplay(NULL))) + { +- +- SDL_EnableUNICODE(1); +- // set repeat to 10ms to ensure repeat time < frame time +- // so that hold times can be reliably detected +- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10); +- +- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +- + return CWinSystemBase::InitWindowSystem(); + } + else +@@ -117,45 +106,37 @@ bool CWinSystemX11::DestroyWindowSystem() + + bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) + { +- RESOLUTION_INFO& desktop = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP); +- +- if (fullScreen && +- (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || +- res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) +- { +- //on the first call to SDL_SetVideoMode, SDL stores the current displaymode +- //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode +- //before the first call to SDL_SetVideoMode, SDL changes the displaymode back +- //to the wrong mode on exit +- +- CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); +- if (!SetFullScreen(true, desktop, false)) +- return false; +- } +- + if(!SetFullScreen(fullScreen, res, false)) + return false; + +- CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon256x256.png"); +- +- if (iconTexture) +- SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); +- SDL_WM_SetCaption("XBMC Media Center", NULL); +- delete iconTexture; +- +- // register XRandR Events +-#if defined(HAS_XRANDR) +- int iReturn; +- XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn); +- XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask); +-#endif +- + m_bWindowCreated = true; + return true; + } + + bool CWinSystemX11::DestroyWindow() + { ++ if (!m_glWindow) ++ return true; ++ ++ if (m_glContext) ++ glXMakeCurrent(m_dpy, None, NULL); ++ ++ if (m_invisibleCursor) ++ { ++ XUndefineCursor(m_dpy, m_glWindow); ++ XFreeCursor(m_dpy, m_invisibleCursor); ++ m_invisibleCursor = 0; ++ } ++ ++ CWinEventsX11Imp::Quit(); ++ ++ XUnmapWindow(m_dpy, m_glWindow); ++ XSync(m_dpy,TRUE); ++ XUngrabKeyboard(m_dpy, CurrentTime); ++ XUngrabPointer(m_dpy, CurrentTime); ++ XDestroyWindow(m_dpy, m_glWindow); ++ m_glWindow = 0; ++ + return true; + } + +@@ -165,67 +146,105 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + && m_nHeight == newHeight) + return true; + ++ if (!SetWindow(newWidth, newHeight, false)) ++ { ++ return false; ++ } ++ ++ RefreshGlxContext(); + m_nWidth = newWidth; + m_nHeight = newHeight; ++ m_bFullScreen = false; + +- int options = SDL_OPENGL; +- if (m_bFullScreen) +- options |= SDL_FULLSCREEN; +- else +- options |= SDL_RESIZABLE; ++ return false; ++} + +- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) ++void CWinSystemX11::RefreshWindow() ++{ ++ g_xrandr.Query(true); ++ XOutput out = g_xrandr.GetCurrentOutput(); ++ XMode mode = g_xrandr.GetCurrentMode(out.name); ++ ++ // only overwrite desktop resolution, if we are not in fullscreen mode ++ if (!g_graphicsContext.IsFullScreenVideo()) + { +- SetGrabMode(); +- RefreshGlxContext(); +- return true; ++ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); ++ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); ++ g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; ++ g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; + } + +- return false; ++ RESOLUTION_INFO res; ++ unsigned int i; ++ bool found(false); ++ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) ++ { ++ if (g_settings.m_ResInfo[i].strId == mode.id) ++ { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); ++ return; ++ } ++ ++ if (g_graphicsContext.IsFullScreenRoot()) ++ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); ++ else ++ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); + } + + bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) + { +- m_nWidth = res.iWidth; +- m_nHeight = res.iHeight; +- m_bFullScreen = fullScreen; + + #if defined(HAS_XRANDR) + XOutput out; + XMode mode; +- out.name = res.strOutput; +- mode.w = res.iWidth; +- mode.h = res.iHeight; +- mode.hz = res.fRefreshRate; +- mode.id = res.strId; ++ ++ if (fullScreen) ++ { ++ out.name = res.strOutput; ++ mode.w = res.iWidth; ++ mode.h = res.iHeight; ++ mode.hz = res.fRefreshRate; ++ mode.id = res.strId; ++ } ++ else ++ { ++ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; ++ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; ++ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; ++ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; ++ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ } + +- if(m_bFullScreen) ++ XOutput currout = g_xrandr.GetCurrentOutput(); ++ XMode currmode = g_xrandr.GetCurrentMode(currout.name); ++ ++ // only call xrandr if mode changes ++ if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || ++ currmode.hz != mode.hz || currmode.id != mode.id) + { ++ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); + OnLostDevice(); + g_xrandr.SetMode(out, mode); + } +- else +- g_xrandr.RestoreState(); + #endif + +- int options = SDL_OPENGL; +- if (m_bFullScreen) +- options |= SDL_FULLSCREEN; +- else +- options |= SDL_RESIZABLE; +- +- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) +- { +- if ((m_SDLSurface->flags & SDL_OPENGL) != SDL_OPENGL) +- CLog::Log(LOGERROR, "CWinSystemX11::SetFullScreen SDL_OPENGL not set, SDL_GetError:%s", SDL_GetError()); ++ if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) ++ return false; + +- SetGrabMode(); +- RefreshGlxContext(); ++ RefreshGlxContext(); + +- return true; +- } ++ m_nWidth = res.iWidth; ++ m_nHeight = res.iHeight; ++ m_bFullScreen = fullScreen; + +- return false; ++ return true; + } + + void CWinSystemX11::UpdateResolutions() +@@ -327,17 +346,10 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) + bool CWinSystemX11::RefreshGlxContext() + { + bool retVal = false; +- SDL_SysWMinfo info; +- SDL_VERSION(&info.version); +- if (SDL_GetWMInfo(&info) <= 0) +- { +- CLog::Log(LOGERROR, "Failed to get window manager info from SDL"); +- return false; +- } + +- if(m_glWindow == info.info.x11.window && m_glContext) ++ if (m_glContext) + { +- CLog::Log(LOGERROR, "GLX: Same window as before, refreshing context"); ++ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); + glXMakeCurrent(m_dpy, None, NULL); + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); + return true; +@@ -349,8 +361,6 @@ bool CWinSystemX11::RefreshGlxContext() + int availableVisuals = 0; + vMask.screen = DefaultScreen(m_dpy); + XWindowAttributes winAttr; +- m_glWindow = info.info.x11.window; +- m_wmWindow = info.info.x11.wmwindow; + + /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() + or XGetVisualInfo() fail. That shouldn't happen unless something is +@@ -421,7 +431,10 @@ bool CWinSystemX11::RefreshGlxContext() + + void CWinSystemX11::ShowOSMouse(bool show) + { +- SDL_ShowCursor(show ? 1 : 0); ++ if (show) ++ XUndefineCursor(m_dpy,m_glWindow); ++ else if (m_invisibleCursor) ++ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); + } + + void CWinSystemX11::ResetOSScreensaver() +@@ -435,8 +448,6 @@ void CWinSystemX11::ResetOSScreensaver() + { + m_screensaverReset.StartZero(); + XResetScreenSaver(m_dpy); +- //need to flush the output buffer, since we don't check for events on m_dpy +- XFlush(m_dpy); + } + } + else +@@ -452,13 +463,27 @@ void CWinSystemX11::NotifyAppActiveChange(bool bActivated) + + m_minimized = !bActivated; + } ++ ++void CWinSystemX11::NotifyAppFocusChange(bool bGaining) ++{ ++ if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && ++ !g_graphicsContext.IsFullScreenRoot()) ++ g_graphicsContext.ToggleFullScreenRoot(); ++ if (!bGaining) ++ m_bIgnoreNextFocusMessage = false; ++} ++ + bool CWinSystemX11::Minimize() + { + m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); + if (m_bWasFullScreenBeforeMinimize) ++ { ++ m_bIgnoreNextFocusMessage = true; + g_graphicsContext.ToggleFullScreenRoot(); ++ } ++ ++ XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); + +- SDL_WM_IconifyWindow(); + m_minimized = true; + return true; + } +@@ -468,13 +493,13 @@ bool CWinSystemX11::Restore() + } + bool CWinSystemX11::Hide() + { +- XUnmapWindow(m_dpy, m_wmWindow); ++ XUnmapWindow(m_dpy, m_glWindow); + XSync(m_dpy, False); + return true; + } + bool CWinSystemX11::Show(bool raise) + { +- XMapWindow(m_dpy, m_wmWindow); ++ XMapWindow(m_dpy, m_glWindow); + XSync(m_dpy, False); + m_minimized = false; + return true; +@@ -506,6 +531,7 @@ void CWinSystemX11::CheckDisplayEvents() + if (bGotEvent || bTimeout) + { + CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); ++ RefreshWindow(); + + CSingleLock lock(m_resourceSection); + +@@ -564,37 +590,151 @@ bool CWinSystemX11::EnableFrameLimiter() + return m_minimized; + } + +-void CWinSystemX11::SetGrabMode(const CSetting *setting /*= NULL*/) ++bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + { +- bool enabled; +- if (setting) +- enabled = ((CSettingBool*)setting)->GetValue(); +- else +- enabled = CSettings::Get().GetBool("input.enablesystemkeys"); +- +- if (m_SDLSurface && m_SDLSurface->flags & SDL_FULLSCREEN) ++ bool changeWindow = false; ++ bool changeSize = false; ++ bool mouseActive = false; ++ float mouseX, mouseY; ++ ++ if (m_glWindow && (m_bFullScreen != fullscreen)) + { +- if (enabled) ++ mouseActive = g_Mouse.IsActive(); ++ if (mouseActive) + { +- //SDL will always call XGrabPointer and XGrabKeyboard when in fullscreen +- //so temporarily zero the SDL_FULLSCREEN flag, then turn off SDL grab mode +- //this will make SDL call XUnGrabPointer and XUnGrabKeyboard +- m_SDLSurface->flags &= ~SDL_FULLSCREEN; +- SDL_WM_GrabInput(SDL_GRAB_OFF); +- m_SDLSurface->flags |= SDL_FULLSCREEN; ++ Window root_return, child_return; ++ int root_x_return, root_y_return; ++ int win_x_return, win_y_return; ++ unsigned int mask_return; ++ bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, ++ &root_x_return, &root_y_return, ++ &win_x_return, &win_y_return, ++ &mask_return); ++ if (isInWin) ++ { ++ mouseX = (float)win_x_return/m_nWidth; ++ mouseY = (float)win_y_return/m_nHeight; ++ g_Mouse.SetActive(false); ++ } ++ else ++ mouseActive = false; + } +- else ++ DestroyWindow(); ++ } ++ ++ // create main window ++ if (!m_glWindow) ++ { ++ GLint att[] = + { +- //turn off key grabbing, which will actually make SDL turn it on when in fullscreen +- SDL_WM_GrabInput(SDL_GRAB_OFF); +- } ++ GLX_RGBA, ++ GLX_RED_SIZE, 8, ++ GLX_GREEN_SIZE, 8, ++ GLX_BLUE_SIZE, 8, ++ GLX_ALPHA_SIZE, 8, ++ GLX_DEPTH_SIZE, 24, ++ GLX_DOUBLEBUFFER, ++ None ++ }; ++ Colormap cmap; ++ XSetWindowAttributes swa; ++ XVisualInfo *vi; ++ ++ vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); ++ cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); ++ ++ int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); ++ swa.override_redirect = fullscreen ? True : False; ++ swa.border_pixel = fullscreen ? 0 : 5; ++ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; ++ swa.colormap = cmap; ++ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; ++ swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ++ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ++ PropertyChangeMask | StructureNotifyMask | KeymapStateMask | ++ EnterWindowMask | LeaveWindowMask | ExposureMask; ++ unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; ++ ++ m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), ++ 0, 0, width, height, 0, vi->depth, ++ InputOutput, vi->visual, ++ mask, &swa); ++ ++ // define invisible cursor ++ Pixmap bitmapNoData; ++ XColor black; ++ static char noData[] = { 0,0,0,0,0,0,0,0 }; ++ black.red = black.green = black.blue = 0; ++ ++ bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); ++ m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, ++ &black, &black, 0, 0); ++ XFreePixmap(m_dpy, bitmapNoData); ++ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); ++ ++ //init X11 events ++ CWinEventsX11Imp::Init(m_dpy, m_glWindow); ++ ++ changeWindow = true; ++ changeSize = true; + } +-} + +-void CWinSystemX11::OnSettingChanged(const CSetting *setting) +-{ +- if (setting->GetId() == "input.enablesystemkeys") +- SetGrabMode(setting); ++ if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) ++ { ++ changeSize = true; ++ } ++ ++ if (changeSize || changeWindow) ++ { ++ XResizeWindow(m_dpy, m_glWindow, width, height); ++ } ++ ++ if (changeWindow) ++ { ++ if (!fullscreen) ++ { ++ XWMHints wm_hints; ++ XClassHint class_hints; ++ XTextProperty windowName, iconName; ++ std::string titleString = "XBMC Media Center"; ++ char *title = (char*)titleString.c_str(); ++ ++ XStringListToTextProperty(&title, 1, &windowName); ++ XStringListToTextProperty(&title, 1, &iconName); ++ wm_hints.initial_state = NormalState; ++ wm_hints.input = True; ++ wm_hints.icon_pixmap = None; ++ wm_hints.flags = StateHint | IconPixmapHint | InputHint; ++ ++ XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, ++ NULL, 0, NULL, &wm_hints, ++ NULL); ++ ++ // register interest in the delete window message ++ Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); ++ XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); ++ } ++ XMapRaised(m_dpy, m_glWindow); ++ XSync(m_dpy,TRUE); ++ ++ if (changeWindow && mouseActive) ++ { ++ XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); ++ } ++ ++ if (fullscreen) ++ { ++ int result = -1; ++ while (result != GrabSuccess) ++ { ++ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); ++ XbmcThreads::ThreadSleep(100); ++ } ++ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ ++ } ++ } ++ return true; + } + + #endif +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index b1464d0..34b912f 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -54,6 +54,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + virtual bool EnableFrameLimiter(); + + virtual void NotifyAppActiveChange(bool bActivated); ++ virtual void NotifyAppFocusChange(bool bGaining); + + virtual bool Minimize(); + virtual bool Restore() ; +@@ -66,20 +67,21 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + Display* GetDisplay() { return m_dpy; } + GLXWindow GetWindow() { return m_glWindow; } + GLXContext GetGlxContext() { return m_glContext; } +- virtual void OnSettingChanged(const CSetting *setting); ++ void RefreshWindow(); + + protected: + bool RefreshGlxContext(); + void CheckDisplayEvents(); + void OnLostDevice(); ++ bool SetWindow(int width, int height, bool fullscreen); + +- SDL_Surface* m_SDLSurface; ++ Window m_glWindow; + GLXContext m_glContext; +- GLXWindow m_glWindow; +- Window m_wmWindow; + Display* m_dpy; ++ Cursor m_invisibleCursor; + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; ++ bool m_bIgnoreNextFocusMessage; + int m_RREventBase; + CCriticalSection m_resourceSection; + std::vector m_resources; +-- +1.9.3 + + +From 9c2362e552ea7136ba2a6f089b98ffc413e54d4f Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:24:22 +0200 +Subject: [PATCH 038/122] X11: Add xbmc icon + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 126 +++++++++++++++++++++++++++++++++++- + xbmc/windowing/X11/WinSystemX11.h | 3 +- + 2 files changed, 127 insertions(+), 2 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 40b8403..858ea5e 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -137,6 +137,9 @@ bool CWinSystemX11::DestroyWindow() + XDestroyWindow(m_dpy, m_glWindow); + m_glWindow = 0; + ++ if (m_icon) ++ XFreePixmap(m_dpy, m_icon); ++ + return true; + } + +@@ -691,8 +694,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + + if (changeWindow) + { ++ m_icon = None; + if (!fullscreen) + { ++ CreateIconPixmap(); + XWMHints wm_hints; + XClassHint class_hints; + XTextProperty windowName, iconName; +@@ -703,7 +708,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + XStringListToTextProperty(&title, 1, &iconName); + wm_hints.initial_state = NormalState; + wm_hints.input = True; +- wm_hints.icon_pixmap = None; ++ wm_hints.icon_pixmap = m_icon; + wm_hints.flags = StateHint | IconPixmapHint | InputHint; + + XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, +@@ -737,4 +742,123 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + return true; + } + ++bool CWinSystemX11::CreateIconPixmap() ++{ ++ int depth; ++ XImage *img = NULL; ++ Visual *vis; ++ XWindowAttributes wndattribs; ++ XVisualInfo visInfo; ++ double rRatio; ++ double gRatio; ++ double bRatio; ++ int outIndex = 0; ++ int i,j; ++ int numBufBytes; ++ unsigned char *buf; ++ uint32_t *newBuf = 0; ++ size_t numNewBufBytes; ++ ++ // Get visual Info ++ XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs); ++ visInfo.visualid = wndattribs.visual->visualid; ++ int nvisuals = 0; ++ XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals); ++ if (nvisuals != 1) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual"); ++ return false; ++ } ++ visInfo = visuals[0]; ++ XFree(visuals); ++ ++ depth = visInfo.depth; ++ vis = visInfo.visual; ++ ++ if (depth < 15) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth"); ++ return false; ++ } ++ ++ rRatio = vis->red_mask / 255.0; ++ gRatio = vis->green_mask / 255.0; ++ bRatio = vis->blue_mask / 255.0; ++ ++ CTexture iconTexture; ++ iconTexture.LoadFromFile("special://xbmc/media/icon.png"); ++ buf = iconTexture.GetPixels(); ++ ++ numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; ++ ++ if (depth>=24) ++ numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); ++ else ++ numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); ++ ++ newBuf = (uint32_t*)malloc(numNewBufBytes); ++ if (!newBuf) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed"); ++ return false; ++ } ++ ++ for (i=0; ired_mask; ++ g &= vis->green_mask; ++ b &= vis->blue_mask; ++ newBuf[outIndex] = r | g | b; ++ ++outIndex; ++ } ++ } ++ img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, ++ iconTexture.GetWidth(), iconTexture.GetHeight(), ++ (depth>=24)?32:16, 0); ++ if (!img) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image"); ++ free(newBuf); ++ return false; ++ } ++ if (!XInitImage(img)) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed"); ++ XDestroyImage(img); ++ return false; ++ } ++ ++ // set byte order ++ union ++ { ++ char c[sizeof(short)]; ++ short s; ++ } order; ++ order.s = 1; ++ if ((1 == order.c[0])) ++ { ++ img->byte_order = LSBFirst; ++ } ++ else ++ { ++ img->byte_order = MSBFirst; ++ } ++ ++ // create icon pixmap from image ++ m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth); ++ GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL); ++ XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height); ++ XFreeGC(m_dpy, gc); ++ XDestroyImage(img); // this also frees newBuf ++ ++ return true; ++} ++ + #endif +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 34b912f..352e90e 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -79,6 +79,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + GLXContext m_glContext; + Display* m_dpy; + Cursor m_invisibleCursor; ++ Pixmap m_icon; + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; + bool m_bIgnoreNextFocusMessage; +@@ -90,7 +91,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + private: + bool IsSuitableVisual(XVisualInfo *vInfo); + static int XErrorHandler(Display* dpy, XErrorEvent* error); +- void SetGrabMode(const CSetting *setting = NULL); ++ bool CreateIconPixmap(); + + CStopWatch m_screensaverReset; + }; +-- +1.9.3 + + +From 4104b4a971c7c742f42d8e04c42cdb0aa70efc3c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 20 May 2012 14:11:26 +0200 +Subject: [PATCH 039/122] X11: add SDL joystick until we have a better solution + +--- + xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index ad58aad..6f57a87 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -35,6 +35,10 @@ + #include "guilib/GUIWindowManager.h" + #include "input/MouseStat.h" + ++#ifdef HAS_SDL_JOYSTICK ++#include "input/SDLJoystick.h" ++#endif ++ + CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0; + + static uint32_t SymMappingsX11[][2] = +@@ -556,6 +560,28 @@ bool CWinEventsX11Imp::MessagePump() + + ret |= ProcessKeyRepeat(); + ++#ifdef HAS_SDL_JOYSTICK ++ SDL_Event event; ++ while (SDL_PollEvent(&event)) ++ { ++ switch(event.type) ++ { ++ case SDL_JOYBUTTONUP: ++ case SDL_JOYBUTTONDOWN: ++ case SDL_JOYAXISMOTION: ++ case SDL_JOYBALLMOTION: ++ case SDL_JOYHATMOTION: ++ g_Joystick.Update(event); ++ ret = true; ++ break; ++ ++ default: ++ break; ++ } ++ memset(&event, 0, sizeof(SDL_Event)); ++ } ++#endif ++ + return ret; + } + +-- +1.9.3 + + +From 5d690104a5b44ce27808f8118df505c7f3986d02 Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 12:35:55 +0200 +Subject: [PATCH 040/122] X11: factor out code handling device reset + notification + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 22 ++++++++++++++-------- + xbmc/windowing/X11/WinSystemX11.h | 1 + + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 858ea5e..304dac8 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -533,14 +533,7 @@ void CWinSystemX11::CheckDisplayEvents() + + if (bGotEvent || bTimeout) + { +- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); +- RefreshWindow(); +- +- CSingleLock lock(m_resourceSection); +- +- // tell any shared resources +- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) +- (*i)->OnResetDevice(); ++ NotifyXRREvent(); + + // reset fail safe timer + m_dpyLostTime = 0; +@@ -548,6 +541,19 @@ void CWinSystemX11::CheckDisplayEvents() + #endif + } + ++void CWinSystemX11::NotifyXRREvent() ++{ ++ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); ++ RefreshWindow(); ++ ++ CSingleLock lock(m_resourceSection); ++ ++ // tell any shared resources ++ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) ++ (*i)->OnResetDevice(); ++ ++} ++ + void CWinSystemX11::OnLostDevice() + { + CLog::Log(LOGDEBUG, "%s - notify display change event", __FUNCTION__); +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 352e90e..3f91b9b 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -68,6 +68,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + GLXWindow GetWindow() { return m_glWindow; } + GLXContext GetGlxContext() { return m_glContext; } + void RefreshWindow(); ++ void NotifyXRREvent(); + + protected: + bool RefreshGlxContext(); +-- +1.9.3 + + +From 5ea82c6ac118e388bfbdc719163b887389d46a14 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:02:00 +0200 +Subject: [PATCH 041/122] X11: move xrandr events to WinEventsX11 + +--- + xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++++ + xbmc/windowing/WinEventsX11.h | 5 +++++ + xbmc/windowing/X11/WinSystemX11.cpp | 6 +++++- + 3 files changed, 52 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 6f57a87..d77cb2a 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -35,6 +35,10 @@ + #include "guilib/GUIWindowManager.h" + #include "input/MouseStat.h" + ++#if defined(HAS_XRANDR) ++#include ++#endif ++ + #ifdef HAS_SDL_JOYSTICK + #include "input/SDLJoystick.h" + #endif +@@ -212,6 +216,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_keymodState = 0; + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; ++ WinEvents->m_xrrEventPending = false; + memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); + + // open input method +@@ -275,6 +280,13 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; + } + ++ // register for xrandr events ++#if defined(HAS_XRANDR) ++ int iReturn; ++ XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); ++ XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); ++#endif ++ + return true; + } + +@@ -297,6 +309,15 @@ bool CWinEventsX11Imp::HasStructureChanged() + return ret; + } + ++void CWinEventsX11Imp::SetXRRFailSafeTimer(int millis) ++{ ++ if (!WinEvents) ++ return; ++ ++ WinEvents->m_xrrFailSafeTimer.Set(millis); ++ WinEvents->m_xrrEventPending = true; ++} ++ + bool CWinEventsX11Imp::MessagePump() + { + if (!WinEvents) +@@ -556,10 +577,31 @@ bool CWinEventsX11Imp::MessagePump() + break; + } + }// switch event.type ++ ++#if defined(HAS_XRANDR) ++ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) ++ { ++ XRRUpdateConfiguration(&xevent); ++ if (xevent.xgeneric.serial != serial) ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ serial = xevent.xgeneric.serial; ++ } ++#endif ++ + }// while + + ret |= ProcessKeyRepeat(); + ++#if defined(HAS_XRANDR) ++ if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) ++ { ++ CLog::Log(LOGERROR,"CWinEventsX11::MessagePump - missed XRR Events"); ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ } ++#endif ++ + #ifdef HAS_SDL_JOYSTICK + SDL_Event event; + while (SDL_PollEvent(&event)) +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index ce57c23..a412f32 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -40,6 +40,8 @@ class CWinEventsX11Imp + static bool Init(Display *dpy, Window win); + static void Quit(); + static bool HasStructureChanged(); ++ static void PendingResize(int width, int height); ++ static void SetXRRFailSafeTimer(int millis); + static bool MessagePump(); + static size_t GetQueueSize(); + +@@ -62,4 +64,7 @@ class CWinEventsX11Imp + std::map m_symLookupTable; + int m_keymodState; + bool m_structureChanged; ++ int m_RREventBase; ++ XbmcThreads::EndTime m_xrrFailSafeTimer; ++ bool m_xrrEventPending; + }; +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 304dac8..16b13aa 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -510,7 +510,7 @@ bool CWinSystemX11::Show(bool raise) + + void CWinSystemX11::CheckDisplayEvents() + { +-#if defined(HAS_XRANDR) ++#if defined(HAS_XRANDR) && defined(HAS_SDL_VIDEO_X11) + bool bGotEvent(false); + bool bTimeout(false); + XEvent Event; +@@ -566,8 +566,12 @@ void CWinSystemX11::OnLostDevice() + (*i)->OnLostDevice(); + } + ++#if defined(HAS_SDL_VIDEO_X11) + // fail safe timer + m_dpyLostTime = CurrentHostCounter(); ++#else ++ CWinEventsX11Imp::SetXRRFailSafeTimer(3000); ++#endif + } + + void CWinSystemX11::Register(IDispResource *resource) +-- +1.9.3 + + +From 23fb8b6739673c102469c965b054604e74fc2814 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 12 Apr 2012 15:43:56 +0200 +Subject: [PATCH 042/122] xrandr: remove method RestoreState + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++-- + xbmc/windowing/X11/XRandR.cpp | 19 ------------------- + xbmc/windowing/X11/XRandR.h | 1 - + 3 files changed, 11 insertions(+), 22 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 16b13aa..f61d425 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -80,9 +80,18 @@ bool CWinSystemX11::InitWindowSystem() + bool CWinSystemX11::DestroyWindowSystem() + { + #if defined(HAS_XRANDR) +- //restore videomode on exit ++ //restore desktop resolution on exit + if (m_bFullScreen) +- g_xrandr.RestoreState(); ++ { ++ XOutput out; ++ XMode mode; ++ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; ++ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; ++ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; ++ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; ++ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ g_xrandr.SetMode(out, mode); ++ } + #endif + + if (m_dpy) +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 0ac17ab..7e06655 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -139,25 +139,6 @@ void CXRandR::SaveState() + Query(true); + } + +-void CXRandR::RestoreState() +-{ +- vector::iterator outiter; +- for (outiter=m_current.begin() ; outiter!=m_current.end() ; outiter++) +- { +- vector modes = (*outiter).modes; +- vector::iterator modeiter; +- for (modeiter=modes.begin() ; modeiter!=modes.end() ; modeiter++) +- { +- XMode mode = *modeiter; +- if (mode.isCurrent) +- { +- SetMode(*outiter, mode); +- return; +- } +- } +- } +-} +- + bool CXRandR::SetMode(XOutput output, XMode mode) + { + if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index 0aec487..00b49dc 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -99,7 +99,6 @@ class CXRandR + bool SetMode(XOutput output, XMode mode); + void LoadCustomModeLinesToAllOutputs(void); + void SaveState(); +- void RestoreState(); + //bool Has1080i(); + //bool Has1080p(); + //bool Has720p(); +-- +1.9.3 + + +From fb625ae69e001be9e671d9eb055d2a2dc459ec0a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 20 May 2012 13:17:10 +0200 +Subject: [PATCH 043/122] xrandr: observe orientation + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 89 ++++++++++++++++++++++++++++++------- + xbmc/windowing/X11/WinSystemX11.h | 2 + + xbmc/windowing/X11/XRandR.cpp | 7 +++ + xbmc/windowing/X11/XRandR.h | 1 + + 4 files changed, 82 insertions(+), 17 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index f61d425..4257aeb 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -85,11 +85,11 @@ bool CWinSystemX11::DestroyWindowSystem() + { + XOutput out; + XMode mode; +- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; +- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; +- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; +- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; +- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput; ++ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth; ++ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight; ++ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate; ++ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; + g_xrandr.SetMode(out, mode); + } + #endif +@@ -173,25 +173,34 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + + void CWinSystemX11::RefreshWindow() + { +- g_xrandr.Query(true); ++ if (!g_xrandr.Query(true)) ++ { ++ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); ++ return; ++ } + XOutput out = g_xrandr.GetCurrentOutput(); + XMode mode = g_xrandr.GetCurrentMode(out.name); + ++ RotateResolutions(); ++ + // only overwrite desktop resolution, if we are not in fullscreen mode + if (!g_graphicsContext.IsFullScreenVideo()) + { + CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); +- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); +- g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; +- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; ++ if (!out.isRotated) ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); ++ else ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); ++ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; ++ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; + } + + RESOLUTION_INFO res; + unsigned int i; + bool found(false); +- for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) ++ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) + { +- if (g_settings.m_ResInfo[i].strId == mode.id) ++ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) + { + found = true; + break; +@@ -227,16 +236,24 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + else + { +- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; +- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; +- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; +- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; +- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput; ++ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth; ++ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight; ++ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate; ++ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; + } + + XOutput currout = g_xrandr.GetCurrentOutput(); + XMode currmode = g_xrandr.GetCurrentMode(currout.name); + ++ // flip h/w when rotated ++ if (m_bIsRotated) ++ { ++ int w = mode.w; ++ mode.w = mode.h; ++ mode.h = w; ++ } ++ + // only call xrandr if mode changes + if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || + currmode.hz != mode.hz || currmode.id != mode.id) +@@ -269,7 +286,11 @@ void CWinSystemX11::UpdateResolutions() + { + XOutput out = g_xrandr.GetCurrentOutput(); + XMode mode = g_xrandr.GetCurrentMode(out.name); +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); ++ m_bIsRotated = out.isRotated; ++ if (!m_bIsRotated) ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); ++ else ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; + } +@@ -308,6 +329,16 @@ void CWinSystemX11::UpdateResolutions() + res.iHeight = mode.h; + res.iScreenWidth = mode.w; + res.iScreenHeight = mode.h; ++ if (!m_bIsRotated) ++ { ++ res.iWidth = mode.w; ++ res.iHeight = mode.h; ++ } ++ else ++ { ++ res.iWidth = mode.h; ++ res.iHeight = mode.w; ++ } + if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) + res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); + else +@@ -335,6 +366,30 @@ void CWinSystemX11::UpdateResolutions() + + } + ++void CWinSystemX11::RotateResolutions() ++{ ++#if defined(HAS_XRANDR) ++ XOutput out = g_xrandr.GetCurrentOutput(); ++ if (out.isRotated == m_bIsRotated) ++ return; ++ ++ for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) ++ { ++ int width = CDisplaySettings::Get().GetResolutionInfo(i).iWidth; ++ CDisplaySettings::Get().GetResolutionInfo(i).iWidth = CDisplaySettings::Get().GetResolutionInfo(i).iHeight; ++ CDisplaySettings::Get().GetResolutionInfo(i).iHeight = width; ++ } ++ // update desktop resolution ++// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; ++// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; ++// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; ++// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); ++ ++ m_bIsRotated = out.isRotated; ++ ++#endif ++} ++ + bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) + { + int value; +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 3f91b9b..4175aab 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -75,12 +75,14 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + void CheckDisplayEvents(); + void OnLostDevice(); + bool SetWindow(int width, int height, bool fullscreen); ++ void RotateResolutions(); + + Window m_glWindow; + GLXContext m_glContext; + Display* m_dpy; + Cursor m_invisibleCursor; + Pixmap m_icon; ++ bool m_bIsRotated; + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; + bool m_bIgnoreNextFocusMessage; +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 7e06655..330e945 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -98,6 +98,13 @@ bool CXRandR::Query(bool force) + xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); + xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); + xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); ++ if (output->Attribute("rotation") != NULL ++ && (strcasecmp(output->Attribute("rotation"), "left") == 0 || strcasecmp(output->Attribute("rotation"), "right") == 0)) ++ { ++ xoutput.isRotated = true; ++ } ++ else ++ xoutput.isRotated = false; + + if (!xoutput.isConnected) + continue; +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index 00b49dc..508604d 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -86,6 +86,7 @@ class XOutput + int wmm; + int hmm; + std::vector modes; ++ bool isRotated; + }; + + class CXRandR +-- +1.9.3 + + +From bd016fafcd657ef7e78b1e6e093e44f0ed1bd104 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:54:15 +0200 +Subject: [PATCH 044/122] xrandr: allow getting info for multiple screen's + +Refactored by: Joakim Plate +--- + xbmc/windowing/X11/XRandR.cpp | 65 +++++++++++++++++++++++++++++++++---------- + xbmc/windowing/X11/XRandR.h | 8 ++++-- + 2 files changed, 57 insertions(+), 16 deletions(-) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 330e945..4685413 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -40,6 +40,7 @@ using namespace std; + CXRandR::CXRandR(bool query) + { + m_bInit = false; ++ m_numScreens = 1; + if (query) + Query(); + } +@@ -56,11 +57,21 @@ bool CXRandR::Query(bool force) + return false; + + m_outputs.clear(); +- m_current.clear(); ++ // query all screens ++ for(unsigned int screennum=0; screennumValue(), "screen") != 0) ++ if (strcasecmp(pRootElement->Value(), "screen") != screennum) + { + // TODO ERROR + return false; +@@ -92,6 +103,7 @@ bool CXRandR::Query(bool force) + xoutput.name = output->Attribute("name"); + StringUtils::Trim(xoutput.name); + xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0); ++ xoutput.screen = screennum; + xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0); + xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); + xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); +@@ -123,7 +135,6 @@ bool CXRandR::Query(bool force) + xoutput.modes.push_back(xmode); + if (xmode.isCurrent) + { +- m_current.push_back(xoutput); + hascurrent = true; + } + } +@@ -247,17 +258,6 @@ bool CXRandR::SetMode(XOutput output, XMode mode) + return true; + } + +-XOutput CXRandR::GetCurrentOutput() +-{ +- Query(); +- for (unsigned int j = 0; j < m_outputs.size(); j++) +- { +- if(m_outputs[j].isConnected) +- return m_outputs[j]; +- } +- XOutput empty; +- return empty; +-} + XMode CXRandR::GetCurrentMode(CStdString outputName) + { + Query(); +@@ -329,6 +329,43 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void) + } + } + ++void CXRandR::SetNumScreens(unsigned int num) ++{ ++ m_numScreens = num; ++ m_bInit = false; ++} ++ ++bool CXRandR::IsOutputConnected(CStdString name) ++{ ++ bool result = false; ++ Query(); ++ ++ for (unsigned int i = 0; i < m_outputs.size(); ++i) ++ { ++ if (m_outputs[i].name == name) ++ { ++ result = true; ++ break; ++ } ++ } ++ return result; ++} ++ ++XOutput* CXRandR::GetOutput(CStdString outputName) ++{ ++ XOutput *result = 0; ++ Query(); ++ for (unsigned int i = 0; i < m_outputs.size(); ++i) ++ { ++ if (m_outputs[i].name == outputName) ++ { ++ result = &m_outputs[i]; ++ break; ++ } ++ } ++ return result; ++} ++ + CXRandR g_xrandr; + + #endif // HAS_XRANDR +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index 508604d..d37838a 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -79,6 +79,7 @@ class XOutput + } + CStdString name; + bool isConnected; ++ int screen; + int w; + int h; + int x; +@@ -94,12 +95,15 @@ class CXRandR + public: + CXRandR(bool query=false); + bool Query(bool force=false); ++ bool Query(bool force, int screennum); + std::vector GetModes(void); +- XOutput GetCurrentOutput(); + XMode GetCurrentMode(CStdString outputName); ++ XOutput *GetOutput(CStdString outputName); + bool SetMode(XOutput output, XMode mode); + void LoadCustomModeLinesToAllOutputs(void); + void SaveState(); ++ void SetNumScreens(unsigned int num); ++ bool IsOutputConnected(CStdString name); + //bool Has1080i(); + //bool Has1080p(); + //bool Has720p(); +@@ -107,10 +111,10 @@ class CXRandR + + private: + bool m_bInit; +- std::vector m_current; + std::vector m_outputs; + CStdString m_currentOutput; + CStdString m_currentMode; ++ unsigned int m_numScreens; + }; + + extern CXRandR g_xrandr; +-- +1.9.3 + + +From 911462fccd04f08f45898fe4583c53eb060346a3 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:44:00 +0200 +Subject: [PATCH 045/122] X11: fix multi-head setups + +--- + language/English/strings.po | 4 +- + system/settings/settings.xml | 11 ++ + xbmc/rendering/gl/RenderSystemGL.h | 1 + + xbmc/settings/DisplaySettings.cpp | 44 ++++++- + xbmc/settings/DisplaySettings.h | 2 + + xbmc/settings/Settings.cpp | 6 + + xbmc/windowing/WinEventsX11.cpp | 7 + + xbmc/windowing/X11/WinSystemX11.cpp | 255 +++++++++++++++++++++--------------- + xbmc/windowing/X11/WinSystemX11.h | 10 +- + 9 files changed, 227 insertions(+), 113 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 616a321..685847c 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -1021,7 +1021,9 @@ msgctxt "#245" + msgid "Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1) (VShift: %2.2f)" + msgstr "" + +-#empty string with id 246 ++msgctxt "#246" ++msgid "Monitor" ++msgstr "" + + msgctxt "#247" + msgid "Scripts" +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index f92bd59..fba4561 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2251,6 +2251,15 @@ +
+ + ++ ++ HAS_GLX ++ 0 ++ Default ++ ++ monitors ++ ++ ++ + + 0 + 0 +@@ -2272,6 +2281,7 @@ + -1 + + ++ + + + +@@ -2289,6 +2299,7 @@ + -1 + + ++ + + + +diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h +index 4bd540b..f1e2c50 100644 +--- a/xbmc/rendering/gl/RenderSystemGL.h ++++ b/xbmc/rendering/gl/RenderSystemGL.h +@@ -44,6 +44,7 @@ class CRenderSystemGL : public CRenderSystemBase + virtual bool IsExtSupported(const char* extension); + + virtual void SetVSync(bool vsync); ++ virtual void ResetVSync() { m_bVsyncInit = false; } + + virtual void SetViewPort(CRect& viewPort); + virtual void GetViewPort(CRect& viewPort); +diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp +index daa1b18..db2f667 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -219,7 +219,8 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + + const std::string &settingId = setting->GetId(); + if (settingId == "videoscreen.resolution" || +- settingId == "videoscreen.screen") ++ settingId == "videoscreen.screen" || ++ settingId == "videoscreen.monitor") + { + RESOLUTION newRes = RES_DESKTOP; + if (settingId == "videoscreen.resolution") +@@ -235,6 +236,11 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + // get desktop resolution for screen + newRes = GetResolutionForScreen(); + } ++ else if (settingId == "videoscreen.monitor") ++ { ++ g_Windowing.UpdateResolutions(); ++ newRes = GetResolutionForScreen(); ++ } + + string screenmode = GetStringFromResolution(newRes); + CSettings::Get().SetString("videoscreen.screenmode", screenmode); +@@ -245,7 +251,11 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue()); + + SetCurrentResolution(newRes, false); +- g_graphicsContext.SetVideoResolution(newRes); ++ bool outputChanged = false; ++#if defined(HAS_GLX) ++ outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor")); ++#endif ++ g_graphicsContext.SetVideoResolution(newRes, outputChanged); + + // check if the old or the new resolution was/is windowed + // in which case we don't show any prompt to the user +@@ -641,6 +651,10 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std: + if (g_advancedSettings.m_canWindowed) + list.push_back(make_pair(g_localizeStrings.Get(242), DM_WINDOWED)); + ++#if defined(HAS_GLX) ++ list.push_back(make_pair(g_localizeStrings.Get(244), 0)); ++#else ++ + for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++) + { + int screen = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen; +@@ -655,6 +669,7 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std: + RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res); + current = resInfo.iScreen; + } ++#endif + } + + void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t) +@@ -683,3 +698,28 @@ void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(const + SettingOptionsStereoscopicModesFiller(setting, list, current); + list.push_back(make_pair(g_localizeStrings.Get(36525), RENDER_STEREO_MODE_AUTO)); // option for autodetect + } ++ ++void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t) ++{ ++#if defined(HAS_GLX) ++ std::vector monitors; ++ g_Windowing.GetConnectedOutputs(&monitors); ++ for (unsigned int i=0; i RES_CUSTOM) ++ { ++ std::vector::iterator firstCustom = m_resolutions.begin()+RES_CUSTOM; ++ m_resolutions.erase(firstCustom, m_resolutions.end()); ++ } ++} +diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h +index 8ee1be2..bead24b 100644 +--- a/xbmc/settings/DisplaySettings.h ++++ b/xbmc/settings/DisplaySettings.h +@@ -78,6 +78,7 @@ class CDisplaySettings : public ISettingCallback, public ISubSettings, + + void ApplyCalibrations(); + void UpdateCalibrations(); ++ void ClearCustomResolutions(); + + float GetZoomAmount() const { return m_zoomAmount; } + void SetZoomAmount(float zoomAmount) { m_zoomAmount = zoomAmount; } +@@ -95,6 +96,7 @@ class CDisplaySettings : public ISettingCallback, public ISubSettings, + static void SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); + static void SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); + static void SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); ++ static void SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t); + + protected: + CDisplaySettings(); +diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp +index d8d50ea..013adf9 100644 +--- a/xbmc/settings/Settings.cpp ++++ b/xbmc/settings/Settings.cpp +@@ -406,6 +406,7 @@ void CSettings::Uninitialize() + m_settingsManager->UnregisterSettingOptionsFiller("screens"); + m_settingsManager->UnregisterSettingOptionsFiller("stereoscopicmodes"); + m_settingsManager->UnregisterSettingOptionsFiller("preferedstereoscopicviewmodes"); ++ m_settingsManager->UnregisterSettingOptionsFiller("monitors"); + m_settingsManager->UnregisterSettingOptionsFiller("shutdownstates"); + m_settingsManager->UnregisterSettingOptionsFiller("startupwindows"); + m_settingsManager->UnregisterSettingOptionsFiller("streamlanguages"); +@@ -835,6 +836,7 @@ void CSettings::InitializeOptionFillers() + m_settingsManager->RegisterSettingOptionsFiller("screens", CDisplaySettings::SettingOptionsScreensFiller); + m_settingsManager->RegisterSettingOptionsFiller("stereoscopicmodes", CDisplaySettings::SettingOptionsStereoscopicModesFiller); + m_settingsManager->RegisterSettingOptionsFiller("preferedstereoscopicviewmodes", CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller); ++ m_settingsManager->RegisterSettingOptionsFiller("monitors", CDisplaySettings::SettingOptionsMonitorsFiller); + m_settingsManager->RegisterSettingOptionsFiller("shutdownstates", CPowerManager::SettingOptionsShutdownStatesFiller); + m_settingsManager->RegisterSettingOptionsFiller("startupwindows", ADDON::CSkinInfo::SettingOptionsStartupWindowsFiller); + m_settingsManager->RegisterSettingOptionsFiller("streamlanguages", CLangInfo::SettingOptionsStreamLanguagesFiller); +@@ -868,6 +870,9 @@ void CSettings::InitializeConditions() + #ifdef HAS_GL + m_settingsManager->AddCondition("has_gl"); + #endif ++#ifdef HAS_GLX ++ m_settingsManager->AddCondition("has_glx"); ++#endif + #ifdef HAS_GLES + m_settingsManager->AddCondition("has_gles"); + #endif +@@ -1021,6 +1026,7 @@ void CSettings::InitializeISettingCallbacks() + settingSet.insert("videoscreen.resolution"); + settingSet.insert("videoscreen.screenmode"); + settingSet.insert("videoscreen.vsync"); ++ settingSet.insert("videoscreen.monitor"); + m_settingsManager->RegisterCallback(&CDisplaySettings::Get(), settingSet); + + settingSet.clear(); +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index d77cb2a..d98f12f 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -526,9 +526,16 @@ bool CWinEventsX11Imp::MessagePump() + break; + } + ++ case EnterNotify: ++ { ++ g_Windowing.NotifyMouseCoverage(true); ++ break; ++ } ++ + // lose mouse coverage + case LeaveNotify: + { ++ g_Windowing.NotifyMouseCoverage(false); + g_Mouse.SetActive(false); + break; + } +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 4257aeb..5e86772 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -36,6 +36,8 @@ + #include "cores/VideoRenderers/RenderManager.h" + #include "utils/TimeUtils.h" + #include "utils/StringUtils.h" ++#include "settings/Settings.h" ++#include "windowing/WindowingFactory.h" + + #if defined(HAS_XRANDR) + #include +@@ -57,6 +59,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase() + m_bIgnoreNextFocusMessage = false; + m_dpyLostTime = 0; + m_invisibleCursor = 0; ++ m_bIsInternalXrr = false; + + XSetErrorHandler(XErrorHandler); + } +@@ -69,7 +72,8 @@ bool CWinSystemX11::InitWindowSystem() + { + if ((m_dpy = XOpenDisplay(NULL))) + { +- return CWinSystemBase::InitWindowSystem(); ++ bool ret = CWinSystemBase::InitWindowSystem(); ++ return ret; + } + else + CLog::Log(LOGERROR, "GLX Error: No Display found"); +@@ -106,6 +110,8 @@ bool CWinSystemX11::DestroyWindowSystem() + + //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy + //so instead we just let m_dpy die on exit ++ // i have seen core dumps on ATI if the display is not closed here ++ XCloseDisplay(m_dpy); + } + + // m_SDLSurface is free()'d by SDL_Quit(). +@@ -128,7 +134,10 @@ bool CWinSystemX11::DestroyWindow() + return true; + + if (m_glContext) ++ { ++ glFinish(); + glXMakeCurrent(m_dpy, None, NULL); ++ } + + if (m_invisibleCursor) + { +@@ -158,7 +167,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + && m_nHeight == newHeight) + return true; + +- if (!SetWindow(newWidth, newHeight, false)) ++ if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor"))) + { + return false; + } +@@ -167,58 +176,11 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + m_nWidth = newWidth; + m_nHeight = newHeight; + m_bFullScreen = false; ++ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); + + return false; + } + +-void CWinSystemX11::RefreshWindow() +-{ +- if (!g_xrandr.Query(true)) +- { +- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); +- return; +- } +- XOutput out = g_xrandr.GetCurrentOutput(); +- XMode mode = g_xrandr.GetCurrentMode(out.name); +- +- RotateResolutions(); +- +- // only overwrite desktop resolution, if we are not in fullscreen mode +- if (!g_graphicsContext.IsFullScreenVideo()) +- { +- CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); +- if (!out.isRotated) +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); +- else +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); +- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; +- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; +- } +- +- RESOLUTION_INFO res; +- unsigned int i; +- bool found(false); +- for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) +- { +- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) +- { +- found = true; +- break; +- } +- } +- +- if (!found) +- { +- CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); +- return; +- } +- +- if (g_graphicsContext.IsFullScreenRoot()) +- g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); +- else +- g_graphicsContext.SetVideoResolution(RES_WINDOW, true); +-} +- + bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) + { + +@@ -243,8 +205,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; + } + +- XOutput currout = g_xrandr.GetCurrentOutput(); +- XMode currmode = g_xrandr.GetCurrentMode(currout.name); ++ XMode currmode = g_xrandr.GetCurrentMode(out.name); + + // flip h/w when rotated + if (m_bIsRotated) +@@ -255,16 +216,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + + // only call xrandr if mode changes +- if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || ++ if (currmode.w != mode.w || currmode.h != mode.h || + currmode.hz != mode.hz || currmode.id != mode.id) + { + CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); + OnLostDevice(); ++ m_bIsInternalXrr = true; + g_xrandr.SetMode(out, mode); + } + #endif + +- if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) ++ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) + return false; + + RefreshGlxContext(); +@@ -272,6 +234,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + m_nWidth = res.iWidth; + m_nHeight = res.iHeight; + m_bFullScreen = fullScreen; ++ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); + + return true; + } +@@ -280,19 +243,30 @@ void CWinSystemX11::UpdateResolutions() + { + CWinSystemBase::UpdateResolutions(); + +- + #if defined(HAS_XRANDR) +- if(g_xrandr.Query()) +- { +- XOutput out = g_xrandr.GetCurrentOutput(); +- XMode mode = g_xrandr.GetCurrentMode(out.name); +- m_bIsRotated = out.isRotated; ++ CStdString currentMonitor; ++ int numScreens = XScreenCount(m_dpy); ++ g_xrandr.SetNumScreens(numScreens); ++ if(g_xrandr.Query(true)) ++ { ++ currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); ++ // check if the monitor is connected ++ XOutput *out = g_xrandr.GetOutput(currentMonitor); ++ if (!out) ++ { ++ // choose first output ++ currentMonitor = g_xrandr.GetModes()[0].name; ++ out = g_xrandr.GetOutput(currentMonitor); ++ CSettings::Get().SetString("videoscreen.monitor", currentMonitor); ++ } ++ XMode mode = g_xrandr.GetCurrentMode(currentMonitor); ++ m_bIsRotated = out->isRotated; + if (!m_bIsRotated) +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz); + else +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz); + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; +- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; ++ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; + } + else + #endif +@@ -303,23 +277,22 @@ void CWinSystemX11::UpdateResolutions() + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); + } + +- + #if defined(HAS_XRANDR) + ++ // erase previous stored modes ++ CDisplaySettings::Get().ClearCustomResolutions(); ++ + CLog::Log(LOGINFO, "Available videomodes (xrandr):"); +- vector::iterator outiter; +- vector outs; +- outs = g_xrandr.GetModes(); +- CLog::Log(LOGINFO, "Number of connected outputs: %"PRIdS"", outs.size()); ++ ++ XOutput *out = g_xrandr.GetOutput(currentMonitor); + string modename = ""; + +- for (outiter = outs.begin() ; outiter != outs.end() ; outiter++) ++ if (out != NULL) + { +- XOutput out = *outiter; + vector::iterator modeiter; +- CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out.name.c_str(), out.modes.size()); ++ CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out->name.c_str(), out->modes.size()); + +- for (modeiter = out.modes.begin() ; modeiter!=out.modes.end() ; modeiter++) ++ for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++) + { + XMode mode = *modeiter; + CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", +@@ -339,8 +312,8 @@ void CWinSystemX11::UpdateResolutions() + res.iWidth = mode.h; + res.iHeight = mode.w; + } +- if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) +- res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); ++ if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0) ++ res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h)); + else + res.fPixelRatio = 1.0f; + +@@ -366,28 +339,19 @@ void CWinSystemX11::UpdateResolutions() + + } + +-void CWinSystemX11::RotateResolutions() ++void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) + { +-#if defined(HAS_XRANDR) +- XOutput out = g_xrandr.GetCurrentOutput(); +- if (out.isRotated == m_bIsRotated) +- return; +- +- for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) ++ vector outs; ++ outs = g_xrandr.GetModes(); ++ for(unsigned int i=0; ipush_back(outs[i].name); + } +- // update desktop resolution +-// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; +-// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; +-// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; +-// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); +- +- m_bIsRotated = out.isRotated; ++} + +-#endif ++bool CWinSystemX11::IsCurrentOutput(CStdString output) ++{ ++ return m_currentOutput.Equals(output); + } + + bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) +@@ -417,8 +381,11 @@ bool CWinSystemX11::RefreshGlxContext() + if (m_glContext) + { + CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); ++ glFinish(); + glXMakeCurrent(m_dpy, None, NULL); + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); ++ XSync(m_dpy, FALSE); ++ g_Windowing.ResetVSync(); + return true; + } + +@@ -484,6 +451,8 @@ bool CWinSystemX11::RefreshGlxContext() + { + // make this context current + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); ++ g_Windowing.ResetVSync(); ++ XSync(m_dpy, False); + retVal = true; + } + else +@@ -525,24 +494,53 @@ void CWinSystemX11::ResetOSScreensaver() + + void CWinSystemX11::NotifyAppActiveChange(bool bActivated) + { +- if (bActivated && m_bWasFullScreenBeforeMinimize && !g_graphicsContext.IsFullScreenRoot()) ++ if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) ++ { + g_graphicsContext.ToggleFullScreenRoot(); + ++ m_bWasFullScreenBeforeMinimize = false; ++ } + m_minimized = !bActivated; + } + + void CWinSystemX11::NotifyAppFocusChange(bool bGaining) + { + if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && +- !g_graphicsContext.IsFullScreenRoot()) ++ !m_bFullScreen) ++ { ++ m_bWasFullScreenBeforeMinimize = false; + g_graphicsContext.ToggleFullScreenRoot(); ++ m_minimized = false; ++ } + if (!bGaining) + m_bIgnoreNextFocusMessage = false; + } + ++void CWinSystemX11::NotifyMouseCoverage(bool covered) ++{ ++ if (!m_bFullScreen) ++ return; ++ ++ if (covered) ++ { ++ int result = -1; ++ while (result != GrabSuccess && result != AlreadyGrabbed) ++ { ++ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); ++ XbmcThreads::ThreadSleep(100); ++ } ++ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ } ++ else ++ { ++ XUngrabKeyboard(m_dpy, CurrentTime); ++ XUngrabPointer(m_dpy, CurrentTime); ++ } ++} ++ + bool CWinSystemX11::Minimize() + { +- m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); ++ m_bWasFullScreenBeforeMinimize = m_bFullScreen; + if (m_bWasFullScreenBeforeMinimize) + { + m_bIgnoreNextFocusMessage = true; +@@ -608,13 +606,46 @@ void CWinSystemX11::CheckDisplayEvents() + void CWinSystemX11::NotifyXRREvent() + { + CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); +- RefreshWindow(); ++ m_windowDirty = true; + +- CSingleLock lock(m_resourceSection); ++ // if external event update resolutions ++ if (!m_bIsInternalXrr) ++ { ++ UpdateResolutions(); ++ } ++ else if (!g_xrandr.Query(true)) ++ { ++ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); ++ return; ++ } ++ m_bIsInternalXrr = false; + +- // tell any shared resources +- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) +- (*i)->OnResetDevice(); ++ CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); ++ XOutput *out = g_xrandr.GetOutput(currentOutput); ++ XMode mode = g_xrandr.GetCurrentMode(currentOutput); ++ ++ RESOLUTION_INFO res; ++ unsigned int i; ++ bool found(false); ++ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) ++ { ++ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) ++ { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); ++ i = RES_DESKTOP; ++ } ++ ++ if (g_graphicsContext.IsFullScreenRoot()) ++ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); ++ else ++ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); + + } + +@@ -667,14 +698,14 @@ bool CWinSystemX11::EnableFrameLimiter() + return m_minimized; + } + +-bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) ++bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) + { + bool changeWindow = false; + bool changeSize = false; + bool mouseActive = false; + float mouseX, mouseY; + +- if (m_glWindow && (m_bFullScreen != fullscreen)) ++ if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) + { + mouseActive = g_Mouse.IsActive(); + if (mouseActive) +@@ -696,6 +727,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + else + mouseActive = false; + } ++ OnLostDevice(); + DestroyWindow(); + } + +@@ -717,7 +749,11 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + XSetWindowAttributes swa; + XVisualInfo *vi; + +- vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); ++ XOutput *out = g_xrandr.GetOutput(output); ++ if (!out) ++ out = g_xrandr.GetOutput(m_currentOutput); ++ m_nScreen = out->screen; ++ vi = glXChooseVisual(m_dpy, m_nScreen, att); + cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); + + int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); +@@ -733,7 +769,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; + + m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), +- 0, 0, width, height, 0, vi->depth, ++ out->x, out->y, width, height, 0, vi->depth, + InputOutput, vi->visual, + mask, &swa); + +@@ -804,14 +840,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) + if (fullscreen) + { + int result = -1; +- while (result != GrabSuccess) ++ while (result != GrabSuccess && result != AlreadyGrabbed) + { +- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); ++ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + XbmcThreads::ThreadSleep(100); + } + XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); +- + } ++ CSingleLock lock(m_resourceSection); ++ // tell any shared resources ++ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) ++ (*i)->OnResetDevice(); ++ ++ m_windowDirty = false; + } + return true; + } +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 4175aab..94584ab 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -67,15 +67,16 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + Display* GetDisplay() { return m_dpy; } + GLXWindow GetWindow() { return m_glWindow; } + GLXContext GetGlxContext() { return m_glContext; } +- void RefreshWindow(); + void NotifyXRREvent(); ++ void GetConnectedOutputs(std::vector *outputs); ++ bool IsCurrentOutput(CStdString output); ++ void NotifyMouseCoverage(bool covered); + + protected: + bool RefreshGlxContext(); + void CheckDisplayEvents(); + void OnLostDevice(); +- bool SetWindow(int width, int height, bool fullscreen); +- void RotateResolutions(); ++ bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); + + Window m_glWindow; + GLXContext m_glContext; +@@ -90,6 +91,9 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + CCriticalSection m_resourceSection; + std::vector m_resources; + uint64_t m_dpyLostTime; ++ CStdString m_currentOutput; ++ bool m_windowDirty; ++ bool m_bIsInternalXrr; + + private: + bool IsSuitableVisual(XVisualInfo *vInfo); +-- +1.9.3 + + +From fc4fd5ea47a333bbbfc618703ce03b6e65884b5b Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:36:32 +0200 +Subject: [PATCH 046/122] X11: remove all DefaultScreen and RootWindow macros + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- + xbmc/windowing/X11/WinSystemX11.h | 1 + + xbmc/windowing/X11/WinSystemX11GL.cpp | 2 +- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 5e86772..c4fa17c 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -271,7 +271,7 @@ void CWinSystemX11::UpdateResolutions() + else + #endif + { +- int x11screen = DefaultScreen(m_dpy); ++ int x11screen = m_nScreen; + int w = DisplayWidth(m_dpy, x11screen); + int h = DisplayHeight(m_dpy, x11screen); + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); +@@ -393,7 +393,7 @@ bool CWinSystemX11::RefreshGlxContext() + XVisualInfo *visuals; + XVisualInfo *vInfo = NULL; + int availableVisuals = 0; +- vMask.screen = DefaultScreen(m_dpy); ++ vMask.screen = m_nScreen; + XWindowAttributes winAttr; + + /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() +@@ -547,7 +547,7 @@ bool CWinSystemX11::Minimize() + g_graphicsContext.ToggleFullScreenRoot(); + } + +- XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); ++ XIconifyWindow(m_dpy, m_glWindow, m_nScreen); + + m_minimized = true; + return true; +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 94584ab..2bcaf52 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -49,6 +49,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays); + virtual void UpdateResolutions(); + virtual int GetNumScreens() { return 1; } ++ virtual int GetCurrentScreen() { return m_nScreen; } + virtual void ShowOSMouse(bool show); + virtual void ResetOSScreensaver(); + virtual bool EnableFrameLimiter(); +diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp +index 6383754..21e7dc5 100644 +--- a/xbmc/windowing/X11/WinSystemX11GL.cpp ++++ b/xbmc/windowing/X11/WinSystemX11GL.cpp +@@ -167,7 +167,7 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R + return false; + + m_glxext = " "; +- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy)); ++ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_nScreen); + m_glxext += " "; + + CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str()); +-- +1.9.3 + + +From 33a5fdc3c307b1cde71321edbae168872b0b3541 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:45:22 +0200 +Subject: [PATCH 047/122] X11: remove all DefaultScreen and RootWindow macros + (VideoRefClock) + +Note this is on a separate display connection. +--- + xbmc/video/VideoReferenceClock.cpp | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index 0b3950a..ca43b5a 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -271,7 +271,7 @@ bool CVideoReferenceClock::SetupGLX() + } + + bool ExtensionFound = false; +- istringstream Extensions(glXQueryExtensionsString(m_Dpy, DefaultScreen(m_Dpy))); ++ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); + string ExtensionStr; + + while (!ExtensionFound) +@@ -297,7 +297,7 @@ bool CVideoReferenceClock::SetupGLX() + m_bIsATI = true; + } + +- m_vInfo = glXChooseVisual(m_Dpy, DefaultScreen(m_Dpy), singleBufferAttributes); ++ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); + if (!m_vInfo) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); +@@ -308,15 +308,16 @@ bool CVideoReferenceClock::SetupGLX() + { + Swa.border_pixel = 0; + Swa.event_mask = StructureNotifyMask; +- Swa.colormap = XCreateColormap(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), m_vInfo->visual, AllocNone ); ++ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); + SwaMask = CWBorderPixel | CWColormap | CWEventMask; + +- m_Window = XCreateWindow(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), 0, 0, 256, 256, 0, ++ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, + m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); + } + else + { +- m_pixmap = XCreatePixmap(m_Dpy, DefaultRootWindow(m_Dpy), 256, 256, m_vInfo->depth); ++ Window window = g_Windowing.GetWindow(); ++ m_pixmap = XCreatePixmap(m_Dpy, window, 256, 256, m_vInfo->depth); + if (!m_pixmap) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: unable to create pixmap"); +@@ -383,7 +384,7 @@ bool CVideoReferenceClock::SetupGLX() + + //set up receiving of RandR events, we'll get one when the refreshrate changes + XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); +- XRRSelectInput(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), RRScreenChangeNotifyMask); ++ XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); + + UpdateRefreshrate(true); //forced refreshrate update + m_MissedVblanks = 0; +@@ -518,7 +519,7 @@ int CVideoReferenceClock::GetRandRRate() + int RefreshRate; + XRRScreenConfiguration *CurrInfo; + +- CurrInfo = XRRGetScreenInfo(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen)); ++ CurrInfo = XRRGetScreenInfo(m_Dpy, g_Windowing.GetWindow()); + RefreshRate = XRRConfigCurrentRate(CurrInfo); + XRRFreeScreenConfigInfo(CurrInfo); + +-- +1.9.3 + + +From 86595a6d47b3b19cb036d553d5bffd4ea2110365 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 20 Jun 2012 17:37:11 +0200 +Subject: [PATCH 048/122] X11: recreate gl context after output has changed + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++---------- + xbmc/windowing/X11/WinSystemX11.h | 1 + + xbmc/windowing/X11/WinSystemX11GL.cpp | 9 +++++++++ + 3 files changed, 24 insertions(+), 10 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index c4fa17c..f2fd18d 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -172,7 +172,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + return false; + } + +- RefreshGlxContext(); + m_nWidth = newWidth; + m_nHeight = newHeight; + m_bFullScreen = false; +@@ -223,14 +222,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + OnLostDevice(); + m_bIsInternalXrr = true; + g_xrandr.SetMode(out, mode); ++ return true; + } + #endif + + if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) + return false; + +- RefreshGlxContext(); +- + m_nWidth = res.iWidth; + m_nHeight = res.iHeight; + m_bFullScreen = fullScreen; +@@ -381,11 +379,8 @@ bool CWinSystemX11::RefreshGlxContext() + if (m_glContext) + { + CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); +- glFinish(); + glXMakeCurrent(m_dpy, None, NULL); + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); +- XSync(m_dpy, FALSE); +- g_Windowing.ResetVSync(); + return true; + } + +@@ -445,14 +440,14 @@ bool CWinSystemX11::RefreshGlxContext() + { + glXMakeCurrent(m_dpy, None, NULL); + glXDestroyContext(m_dpy, m_glContext); ++ XSync(m_dpy, FALSE); ++ m_newGlContext = true; + } + + if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True))) + { + // make this context current + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); +- g_Windowing.ResetVSync(); +- XSync(m_dpy, False); + retVal = true; + } + else +@@ -729,6 +724,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + } + OnLostDevice(); + DestroyWindow(); ++ m_windowDirty = true; + } + + // create main window +@@ -847,13 +843,21 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + } + XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); + } ++ ++ CDirtyRegionList dr; ++ RefreshGlxContext(); ++ XSync(m_dpy, FALSE); ++ g_graphicsContext.Clear(0); ++ g_graphicsContext.Flip(dr); ++ g_Windowing.ResetVSync(); ++ m_windowDirty = false; ++ + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) + (*i)->OnResetDevice(); +- +- m_windowDirty = false; + } ++ + return true; + } + +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 2bcaf52..9666cc3 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -95,6 +95,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + CStdString m_currentOutput; + bool m_windowDirty; + bool m_bIsInternalXrr; ++ bool m_newGlContext; + + private: + bool IsSuitableVisual(XVisualInfo *vInfo); +diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp +index 21e7dc5..8e68d5d 100644 +--- a/xbmc/windowing/X11/WinSystemX11GL.cpp ++++ b/xbmc/windowing/X11/WinSystemX11GL.cpp +@@ -24,6 +24,7 @@ + #include "WinSystemX11GL.h" + #include "utils/log.h" + #include "utils/StringUtils.h" ++#include "Application.h" + + CWinSystemX11GL::CWinSystemX11GL() + { +@@ -197,17 +198,25 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R + + bool CWinSystemX11GL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) + { ++ m_newGlContext = false; + CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop); + CRenderSystemGL::ResetRenderSystem(newWidth, newHeight, false, 0); + ++ if (m_newGlContext) ++ g_application.ReloadSkin(); ++ + return true; + } + + bool CWinSystemX11GL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) + { ++ m_newGlContext = false; + CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays); + CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate); + ++ if (m_newGlContext) ++ g_application.ReloadSkin(); ++ + return true; + } + +-- +1.9.3 + + +From 8dec206d57608d5bc03eeb1db7a2bb55fdf98cd7 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:06:25 +0200 +Subject: [PATCH 049/122] X11: hook video reference clock in windowing + +--- + xbmc/video/VideoReferenceClock.cpp | 71 +++++++++++++++++++++++++++----------- + xbmc/video/VideoReferenceClock.h | 13 ++++++- + 2 files changed, 63 insertions(+), 21 deletions(-) + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index ca43b5a..0ddf102 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -136,12 +136,23 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") + m_Context = NULL; + m_pixmap = None; + m_glPixmap = None; +- m_RREventBase = 0; + m_UseNvSettings = true; + m_bIsATI = false; + #endif + } + ++CVideoReferenceClock::~CVideoReferenceClock() ++{ ++#if defined(HAS_GLX) ++ // some ATI voodoo, if we don't close the display, we crash on exit ++ if (m_Dpy) ++ { ++ XCloseDisplay(m_Dpy); ++ m_Dpy = NULL; ++ } ++#endif ++} ++ + void CVideoReferenceClock::Process() + { + bool SetupSuccess = false; +@@ -152,6 +163,10 @@ void CVideoReferenceClock::Process() + m_D3dCallback.Reset(); + g_Windowing.Register(&m_D3dCallback); + #endif ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ g_Windowing.Register(this); ++ m_xrrEvent = false; ++#endif + + while(!m_bStop) + { +@@ -212,6 +227,16 @@ void CVideoReferenceClock::Process() + //clean up the vblank clock + #if defined(HAS_GLX) && defined(HAS_XRANDR) + CleanupGLX(); ++ if (m_xrrEvent) ++ { ++ m_releaseEvent.Set(); ++ while (!m_bStop) ++ { ++ if (m_resetEvent.WaitMSec(100)) ++ break; ++ } ++ m_xrrEvent = false; ++ } + #elif defined(TARGET_WINDOWS) && defined(HAS_DX) + CleanupD3D(); + #elif defined(TARGET_DARWIN) +@@ -223,6 +248,9 @@ void CVideoReferenceClock::Process() + #if defined(TARGET_WINDOWS) && defined(HAS_DX) + g_Windowing.Unregister(&m_D3dCallback); + #endif ++#if defined(HAS_GLX) ++ g_Windowing.Unregister(this); ++#endif + } + + bool CVideoReferenceClock::WaitStarted(int MSecs) +@@ -232,6 +260,24 @@ bool CVideoReferenceClock::WaitStarted(int MSecs) + } + + #if defined(HAS_GLX) && defined(HAS_XRANDR) ++ ++void CVideoReferenceClock::OnLostDevice() ++{ ++ if (!m_xrrEvent) ++ { ++ m_releaseEvent.Reset(); ++ m_resetEvent.Reset(); ++ m_xrrEvent = true; ++ m_releaseEvent.Wait(); ++ } ++} ++ ++void CVideoReferenceClock::OnResetDevice() ++{ ++ m_xrrEvent = false; ++ m_resetEvent.Set(); ++} ++ + bool CVideoReferenceClock::SetupGLX() + { + int singleBufferAttributes[] = { +@@ -382,10 +428,6 @@ bool CVideoReferenceClock::SetupGLX() + return false; + } + +- //set up receiving of RandR events, we'll get one when the refreshrate changes +- XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); +- XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); +- + UpdateRefreshrate(true); //forced refreshrate update + m_MissedVblanks = 0; + +@@ -586,6 +628,9 @@ void CVideoReferenceClock::RunGLX() + + while(!m_bStop) + { ++ if (m_xrrEvent) ++ return; ++ + //wait for the next vblank + if (!m_bIsATI) + { +@@ -649,7 +694,6 @@ void CVideoReferenceClock::RunGLX() + UpdateClock((int)(VblankCount - PrevVblankCount), true); + SingleLock.Leave(); + SendVblankSignal(); +- UpdateRefreshrate(); + IsReset = false; + } + else if (!m_bStop) +@@ -1186,23 +1230,10 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) + + #if defined(HAS_GLX) && defined(HAS_XRANDR) + +- //check for RandR events +- bool GotEvent = Forced || m_RefreshChanged == 2; +- XEvent Event; +- while (XCheckTypedEvent(m_Dpy, m_RREventBase + RRScreenChangeNotify, &Event)) +- { +- if (Event.type == m_RREventBase + RRScreenChangeNotify) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Received RandR event %i", Event.type); +- GotEvent = true; +- } +- XRRUpdateConfiguration(&Event); +- } +- + if (!Forced) + m_RefreshChanged = 0; + +- if (!GotEvent) //refreshrate did not change ++ if (!Forced) //refreshrate did not change + return false; + + //the refreshrate can be wrong on nvidia drivers, so read it from nvidia-settings when it's available +diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h +index dd65a1b..afd71fc 100644 +--- a/xbmc/video/VideoReferenceClock.h ++++ b/xbmc/video/VideoReferenceClock.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++ #include "guilib/DispResource.h" + #elif defined(TARGET_WINDOWS) && defined(HAS_DX) + #include + #include "guilib/D3DResource.h" +@@ -56,9 +57,13 @@ class CD3DCallback : public ID3DResource + #endif + + class CVideoReferenceClock : public CThread ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ ,public IDispResource ++#endif + { + public: + CVideoReferenceClock(); ++ virtual ~CVideoReferenceClock(); + + int64_t GetTime(bool interpolated = true); + int64_t GetFrequency(); +@@ -75,6 +80,11 @@ class CVideoReferenceClock : public CThread + void VblankHandler(int64_t nowtime, double fps); + #endif + ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ virtual void OnLostDevice(); ++ virtual void OnResetDevice(); ++#endif ++ + private: + void Process(); + bool UpdateRefreshrate(bool Forced = false); +@@ -121,7 +131,8 @@ class CVideoReferenceClock : public CThread + GLXContext m_Context; + Pixmap m_pixmap; + GLXPixmap m_glPixmap; +- int m_RREventBase; ++ bool m_xrrEvent; ++ CEvent m_releaseEvent, m_resetEvent; + + bool m_UseNvSettings; + bool m_bIsATI; +-- +1.9.3 + + +From da979d3a6a09f83c0fcfd8e5ca1e72159a2ca8d4 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 21 Jun 2012 17:26:51 +0200 +Subject: [PATCH 050/122] X11: fix video calibrations + +--- + xbmc/windowing/WinSystem.h | 1 + + xbmc/windowing/X11/WinSystemX11.cpp | 36 +++++++++++++++++++++++++++++++++++- + xbmc/windowing/X11/WinSystemX11.h | 1 + + 3 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h +index 00a2d24..c0db210 100644 +--- a/xbmc/windowing/WinSystem.h ++++ b/xbmc/windowing/WinSystem.h +@@ -103,6 +103,7 @@ class CWinSystemBase + std::vector ScreenResolutions(int screen, float refreshrate); + std::vector RefreshRates(int screen, int width, int height, uint32_t dwFlags); + REFRESHRATE DefaultRefreshRate(int screen, std::vector rates); ++ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo) { return true; }; + + // text input interface + virtual void EnableTextInput(bool bEnable) {} +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index f2fd18d..c4152c8 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -320,7 +320,7 @@ void CWinSystemX11::UpdateResolutions() + res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); + res.strOutput = out.name; + res.strId = mode.id; +- res.iSubtitles = (int)(0.95*mode.h); ++ res.iSubtitles = (int)(0.965*mode.h); + res.fRefreshRate = mode.hz; + res.bFullScreen = true; + +@@ -333,8 +333,42 @@ void CWinSystemX11::UpdateResolutions() + CDisplaySettings::Get().AddResolutionInfo(res); + } + } ++ CDisplaySettings::Get().ApplyCalibrations(); + #endif ++} ++ ++bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) ++{ ++ XOutput *out = g_xrandr.GetOutput(m_currentOutput); ++ ++ // keep calibrations done on a not connected output ++ if (!out->name.Equals(resInfo.strOutput)) ++ return true; ++ ++ // keep calibrations not updated with resolution data ++ if (resInfo.iWidth == 0) ++ return true; ++ ++ float fPixRatio; ++ if (resInfo.iHeight>0 && resInfo.iWidth>0 && out->hmm>0 && out->wmm>0) ++ fPixRatio = ((float)out->wmm/(float)resInfo.iWidth) / (((float)out->hmm/(float)resInfo.iHeight)); ++ else ++ fPixRatio = 1.0f; + ++ if (resInfo.Overscan.left != 0) ++ return true; ++ if (resInfo.Overscan.top != 0) ++ return true; ++ if (resInfo.Overscan.right != resInfo.iWidth) ++ return true; ++ if (resInfo.Overscan.bottom != resInfo.iHeight) ++ return true; ++ if (resInfo.fPixelRatio != fPixRatio) ++ return true; ++ if (resInfo.iSubtitles != (int)(0.965*resInfo.iHeight)) ++ return true; ++ ++ return false; + } + + void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 9666cc3..5b52d6c 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -63,6 +63,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + virtual bool Show(bool raise = true); + virtual void Register(IDispResource *resource); + virtual void Unregister(IDispResource *resource); ++ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo); + + // Local to WinSystemX11 only + Display* GetDisplay() { return m_dpy; } +-- +1.9.3 + + +From a3926a451b1d62e42d6a762aacf721195e109dd1 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:00:26 +0200 +Subject: [PATCH 051/122] X11: deactivate screen saver on startup + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++ + xbmc/windowing/X11/WinSystemX11.h | 1 + + 2 files changed, 30 insertions(+) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index c4152c8..b76b229 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -521,6 +521,33 @@ void CWinSystemX11::ResetOSScreensaver() + } + } + ++void CWinSystemX11::EnableSystemScreenSaver(bool bEnable) ++{ ++ if (!m_dpy) ++ return; ++ ++ if (bEnable) ++ XForceScreenSaver(m_dpy, ScreenSaverActive); ++ else ++ { ++ Window root_return, child_return; ++ int root_x_return, root_y_return; ++ int win_x_return, win_y_return; ++ unsigned int mask_return; ++ bool isInWin = XQueryPointer(m_dpy, RootWindow(m_dpy, m_nScreen), &root_return, &child_return, ++ &root_x_return, &root_y_return, ++ &win_x_return, &win_y_return, ++ &mask_return); ++ ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return+300, root_y_return+300); ++ XSync(m_dpy, FALSE); ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, 0, 0); ++ XSync(m_dpy, FALSE); ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return, root_y_return); ++ XSync(m_dpy, FALSE); ++ } ++} ++ + void CWinSystemX11::NotifyAppActiveChange(bool bActivated) + { + if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) +@@ -764,6 +791,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + // create main window + if (!m_glWindow) + { ++ EnableSystemScreenSaver(false); ++ + GLint att[] = + { + GLX_RGBA, +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 5b52d6c..b2bd5a0 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -53,6 +53,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + virtual void ShowOSMouse(bool show); + virtual void ResetOSScreensaver(); + virtual bool EnableFrameLimiter(); ++ virtual void EnableSystemScreenSaver(bool bEnable); + + virtual void NotifyAppActiveChange(bool bActivated); + virtual void NotifyAppFocusChange(bool bGaining); +-- +1.9.3 + + +From dbafd214fc5f17d115cc35ca5244d29d1881badb Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:10:09 +0200 +Subject: [PATCH 052/122] X11: change method of going full-screen + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index b76b229..869baa8 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -38,6 +38,7 @@ + #include "utils/StringUtils.h" + #include "settings/Settings.h" + #include "windowing/WindowingFactory.h" ++#include + + #if defined(HAS_XRANDR) + #include +@@ -816,7 +817,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); + + int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); +- swa.override_redirect = fullscreen ? True : False; ++ swa.override_redirect = False; + swa.border_pixel = fullscreen ? 0 : 5; + swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; + swa.colormap = cmap; +@@ -832,6 +833,12 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + InputOutput, vi->visual, + mask, &swa); + ++ if (fullscreen) ++ { ++ Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); ++ XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); ++ } ++ + // define invisible cursor + Pixmap bitmapNoData; + XColor black; +-- +1.9.3 + + +From afa966cc1a5b0f4591c1f84f970f97c11e9db7fc Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Jun 2012 19:12:39 +0200 +Subject: [PATCH 053/122] X11: reset key repeat and key modifier on focus lost + and gain + +--- + xbmc/windowing/WinEventsX11.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index d98f12f..743aca9 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -368,6 +368,8 @@ bool CWinEventsX11Imp::MessagePump() + if (WinEvents->m_xic) + XSetICFocus(WinEvents->m_xic); + g_application.m_AppFocused = true; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); ++ WinEvents->m_keymodState = 0; + if (serial == xevent.xfocus.serial) + break; + g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); +@@ -379,6 +381,7 @@ bool CWinEventsX11Imp::MessagePump() + if (WinEvents->m_xic) + XUnsetICFocus(WinEvents->m_xic); + g_application.m_AppFocused = false; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); + g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); + serial = xevent.xfocus.serial; + break; +-- +1.9.3 + + +From 4cba8f372d1980b922230f4a22d4666be2d89412 Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 14:18:46 +0200 +Subject: [PATCH 054/122] X11: replace custom utf8 to unicode with charset + convertor (squash to x11 events) + +--- + xbmc/windowing/WinEventsX11.cpp | 119 ++++------------------------------------ + xbmc/windowing/WinEventsX11.h | 2 - + 2 files changed, 11 insertions(+), 110 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 743aca9..6b98e67 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -32,6 +32,7 @@ + #include "X11/keysymdef.h" + #include "X11/XF86keysym.h" + #include "utils/log.h" ++#include "utils/CharsetConverter.h" + #include "guilib/GUIWindowManager.h" + #include "input/MouseStat.h" + +@@ -170,7 +171,6 @@ CWinEventsX11Imp::CWinEventsX11Imp() + m_display = 0; + m_window = 0; + m_keybuf = 0; +- m_utf16buf = 0; + } + + CWinEventsX11Imp::~CWinEventsX11Imp() +@@ -181,12 +181,6 @@ CWinEventsX11Imp::~CWinEventsX11Imp() + m_keybuf = 0; + } + +- if (m_utf16buf) +- { +- free(m_utf16buf); +- m_utf16buf = 0; +- } +- + if (m_xic) + { + XUnsetICFocus(m_xic); +@@ -212,7 +206,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_display = dpy; + WinEvents->m_window = win; + WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); +- WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); + WinEvents->m_keymodState = 0; + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; +@@ -442,8 +435,6 @@ bool CWinEventsX11Imp::MessagePump() + } + + Status status; +- int utf16size; +- int utf16length; + int len; + len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, + WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), +@@ -462,36 +453,29 @@ bool CWinEventsX11Imp::MessagePump() + case XLookupChars: + case XLookupBoth: + { +- if (len == 0) +- break; +- utf16size = len * sizeof(uint16_t); +- if (utf16size > sizeof(WinEvents->m_utf16buf)) +- { +- WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); +- if (WinEvents->m_utf16buf == NULL) +- { +- break; +- } +- } +- utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); +- if (utf16length < 0) ++ CStdString data(WinEvents->m_keybuf, len); ++ CStdStringW keys; ++ g_charsetConverter.utf8ToW(data, keys, false); ++ ++ if (keys.length() == 0) + { + break; + } +- for (unsigned int i = 0; i < utf16length - 1; i++) ++ ++ for (unsigned int i = 0; i < keys.length() - 1; i++) + { + newEvent.key.keysym.sym = XBMCK_UNKNOWN; +- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; ++ newEvent.key.keysym.unicode = keys[i]; + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; + ret |= ProcessKey(newEvent, 500); + } +- if (utf16length > 0) ++ if (keys.length() > 0) + { + newEvent.key.keysym.scancode = xevent.xkey.keycode; + xkeysym = XLookupKeysym(&xevent.xkey, 0); + newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); +- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; ++ newEvent.key.keysym.unicode = keys[keys.length() - 1]; + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; + +@@ -762,87 +746,6 @@ bool CWinEventsX11Imp::ProcessKeyRepeat() + return false; + } + +-int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) +-{ +- // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. +- uint16_t *p = utf16; +- uint16_t const *const maxPtr = utf16 + utf16MaxLength; +- +- // end_of_input points to the last byte of input as opposed to the next to the last byte. +- char const *const endOfInput = utf8 + utf8Length - 1; +- +- while (utf8 <= endOfInput) +- { +- unsigned char const c = *utf8; +- if (p >= maxPtr) +- { +- //No more output space. +- return -1; +- } +- if (c < 0x80) +- { +- //One byte ASCII. +- *p++ = c; +- utf8 += 1; +- } +- else if (c < 0xC0) +- { +- // Follower byte without preceding leader bytes. +- return -1; +- } +- // 11 bits +- else if (c < 0xE0) +- { +- // Two byte sequence. We need one follower byte. +- if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) +- { +- return -1; +- } +- *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); +- utf8 += 2; +- } +- // 16 bis +- else if (c < 0xF0) +- { +- // Three byte sequence. We need two follower byte. +- if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) +- { +- return -1; +- } +- *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); +- utf8 += 3; +- } +- // 21 bits +- else if (c < 0xF8) +- { +- int plane; +- // Four byte sequence. We need three follower bytes. +- if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || +- ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) +- { +- return -1; +- } +- uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + +- ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); +- utf8 += 4; +- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); +- } +- // 26 bits +- else if (c < 0xFC) +- { +- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); +- utf8 += 5; +- } +- // 31 bit +- else +- { +- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); +- utf8 += 6; +- } +- } +- return p - utf16; +-} +- + XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) + { + // try direct mapping first +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index a412f32..9a8a912 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -46,7 +46,6 @@ class CWinEventsX11Imp + static size_t GetQueueSize(); + + protected: +- static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); + static XBMCKey LookupXbmcKeySym(KeySym keysym); + static bool ProcessKey(XBMC_Event &event, int repeatDelay); + static bool ProcessKeyRepeat(); +@@ -56,7 +55,6 @@ class CWinEventsX11Imp + Window m_window; + Atom m_wmDeleteMessage; + char *m_keybuf; +- uint16_t *m_utf16buf; + XIM m_xim; + XIC m_xic; + XBMC_Event m_lastKey; +-- +1.9.3 + + +From 6fdeb3e88ebd7ab6c3505c7c69e2a840b7932ab6 Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 14:23:54 +0200 +Subject: [PATCH 055/122] X11: fixed invalid usage of sizeof() (squash into x11 + changes) + +--- + xbmc/windowing/WinEventsX11.cpp | 11 +++++++---- + xbmc/windowing/WinEventsX11.h | 1 + + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 6b98e67..a62521f 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -171,6 +171,7 @@ CWinEventsX11Imp::CWinEventsX11Imp() + m_display = 0; + m_window = 0; + m_keybuf = 0; ++ m_keybuf_len = 0; + } + + CWinEventsX11Imp::~CWinEventsX11Imp() +@@ -205,7 +206,8 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents = new CWinEventsX11Imp(); + WinEvents->m_display = dpy; + WinEvents->m_window = win; +- WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); ++ WinEvents->m_keybuf_len = 32*sizeof(char); ++ WinEvents->m_keybuf = (char*)malloc(WinEvents->m_keybuf_len); + WinEvents->m_keymodState = 0; + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; +@@ -437,13 +439,14 @@ bool CWinEventsX11Imp::MessagePump() + Status status; + int len; + len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, +- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), ++ WinEvents->m_keybuf, WinEvents->m_keybuf_len, + &xkeysym, &status); + if (status == XBufferOverflow) + { +- WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); ++ WinEvents->m_keybuf_len = len; ++ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, WinEvents->m_keybuf_len); + len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, +- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), ++ WinEvents->m_keybuf, WinEvents->m_keybuf_len, + &xkeysym, &status); + } + switch (status) +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index 9a8a912..c69169c 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -55,6 +55,7 @@ class CWinEventsX11Imp + Window m_window; + Atom m_wmDeleteMessage; + char *m_keybuf; ++ size_t m_keybuf_len; + XIM m_xim; + XIC m_xic; + XBMC_Event m_lastKey; +-- +1.9.3 + + +From abf94b2c2812cc290ebfe0e8748a4420fe2b22d8 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 9 Jun 2012 18:23:53 +0200 +Subject: [PATCH 056/122] add missing keys to xbmc keytable + +--- + xbmc/input/XBMC_keytable.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp +index 4d07eb3..53b9dce 100644 +--- a/xbmc/input/XBMC_keytable.cpp ++++ b/xbmc/input/XBMC_keytable.cpp +@@ -182,6 +182,8 @@ static const XBMCKEYTABLE XBMCKeyTable[] = + , { XBMCK_LAUNCH_APP2, 0, 0, XBMCVK_LAUNCH_APP2, "launch_app2_pc_icon" } + , { XBMCK_LAUNCH_FILE_BROWSER, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER, "launch_file_browser" } + , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } ++, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } ++, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } + + // Function keys + , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} +-- +1.9.3 + + +From 594b2f7da7f2a3dbc7a57773f6f4aa9c0b1e17fe Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 16 Mar 2012 15:57:51 +0100 +Subject: [PATCH 057/122] videorefclock: temp deactivate of nv settings + +--- + xbmc/video/VideoReferenceClock.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index 0ddf102..3ae7107 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -136,7 +136,7 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") + m_Context = NULL; + m_pixmap = None; + m_glPixmap = None; +- m_UseNvSettings = true; ++ m_UseNvSettings = false; + m_bIsATI = false; + #endif + } +-- +1.9.3 + + +From 4b026d2e917eaf20267305cc11ecc69658848e70 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 20 Aug 2012 09:09:09 +0200 +Subject: [PATCH 058/122] videorefclock: ask graphics context for refresh rate + +--- + xbmc/video/VideoReferenceClock.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp +index 3ae7107..27bebde 100644 +--- a/xbmc/video/VideoReferenceClock.cpp ++++ b/xbmc/video/VideoReferenceClock.cpp +@@ -31,6 +31,7 @@ + #include + #include + #include "windowing/WindowingFactory.h" ++ #include "guilib/GraphicContext.h" + #define NVSETTINGSCMD "nvidia-settings -nt -q RefreshRate3" + #elif defined(TARGET_DARWIN_OSX) + #include +@@ -1254,7 +1255,7 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) + } + + CSingleLock SingleLock(m_CritSection); +- m_RefreshRate = GetRandRRate(); ++ m_RefreshRate = MathUtils::round_int(g_graphicsContext.GetFPS()); + + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", (int)m_RefreshRate); + +-- +1.9.3 + + +From 426b0b1bc534bc1941b74c103b7ff2859e6d6d50 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 9 Jul 2012 14:00:18 +0200 +Subject: [PATCH 059/122] X11: fix icon texture after + cc5ed3c2474084ebc0373a3046410e6f766e03f4 + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 43 ++++++++++++++++++++++--------------- + 1 file changed, 26 insertions(+), 17 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 869baa8..bfe3797 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -874,22 +874,24 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + if (!fullscreen) + { + CreateIconPixmap(); +- XWMHints wm_hints; +- XClassHint class_hints; ++ XWMHints *wm_hints; + XTextProperty windowName, iconName; + std::string titleString = "XBMC Media Center"; + char *title = (char*)titleString.c_str(); + + XStringListToTextProperty(&title, 1, &windowName); + XStringListToTextProperty(&title, 1, &iconName); +- wm_hints.initial_state = NormalState; +- wm_hints.input = True; +- wm_hints.icon_pixmap = m_icon; +- wm_hints.flags = StateHint | IconPixmapHint | InputHint; + ++ wm_hints = XAllocWMHints(); ++ wm_hints->initial_state = NormalState; ++ wm_hints->icon_pixmap = m_icon; ++ wm_hints->flags = StateHint | IconPixmapHint; ++ ++ XSync(m_dpy,False); + XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, +- NULL, 0, NULL, &wm_hints, ++ NULL, 0, NULL, wm_hints, + NULL); ++ XFree(wm_hints); + + // register interest in the delete window message + Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); +@@ -974,16 +976,21 @@ bool CWinSystemX11::CreateIconPixmap() + gRatio = vis->green_mask / 255.0; + bRatio = vis->blue_mask / 255.0; + +- CTexture iconTexture; +- iconTexture.LoadFromFile("special://xbmc/media/icon.png"); +- buf = iconTexture.GetPixels(); ++ CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon.png"); ++ ++ if (!iconTexture) ++ return false; + +- numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; ++ buf = iconTexture->GetPixels(); ++ ++ numBufBytes = iconTexture->GetWidth() * iconTexture->GetHeight() * 4; ++ int wid = iconTexture->GetWidth(); ++ int hi = iconTexture->GetHeight(); + + if (depth>=24) +- numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); ++ numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight())); + else +- numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); ++ numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight())); + + newBuf = (uint32_t*)malloc(numNewBufBytes); + if (!newBuf) +@@ -992,11 +999,11 @@ bool CWinSystemX11::CreateIconPixmap() + return false; + } + +- for (i=0; iGetHeight();++i) + { +- for (j=0; jGetWidth();++j) + { +- unsigned int pos = i*iconTexture.GetPitch()+j*4; ++ unsigned int pos = i*iconTexture->GetPitch()+j*4; + unsigned int r, g, b; + r = (buf[pos+2] * rRatio); + g = (buf[pos+1] * gRatio); +@@ -1009,7 +1016,7 @@ bool CWinSystemX11::CreateIconPixmap() + } + } + img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, +- iconTexture.GetWidth(), iconTexture.GetHeight(), ++ iconTexture->GetWidth(), iconTexture->GetHeight(), + (depth>=24)?32:16, 0); + if (!img) + { +@@ -1047,6 +1054,8 @@ bool CWinSystemX11::CreateIconPixmap() + XFreeGC(m_dpy, gc); + XDestroyImage(img); // this also frees newBuf + ++ delete iconTexture; ++ + return true; + } + +-- +1.9.3 + + +From b89023e829fede3d83e256466a83e0febdc8afe3 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 10 Jul 2012 11:14:12 +0200 +Subject: [PATCH 060/122] X11: check for window manager + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++++- + xbmc/windowing/X11/WinSystemX11.h | 1 + + 2 files changed, 73 insertions(+), 2 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index bfe3797..af82061 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -816,8 +816,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + vi = glXChooseVisual(m_dpy, m_nScreen, att); + cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); + ++ bool hasWM = HasWindowManager(); ++ + int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); +- swa.override_redirect = False; ++ swa.override_redirect = hasWM ? False : True; + swa.border_pixel = fullscreen ? 0 : 5; + swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; + swa.colormap = cmap; +@@ -833,7 +835,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + InputOutput, vi->visual, + mask, &swa); + +- if (fullscreen) ++ if (fullscreen && hasWM) + { + Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); + XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); +@@ -1059,4 +1061,72 @@ bool CWinSystemX11::CreateIconPixmap() + return true; + } + ++bool CWinSystemX11::HasWindowManager() ++{ ++ Window wm_check; ++ unsigned char *data; ++ int status, real_format; ++ Atom real_type, prop; ++ unsigned long items_read, items_left, i; ++ char req = 0; ++ ++ prop = XInternAtom(m_dpy, "_NET_SUPPORTING_WM_CHECK", True); ++ if (prop == None) ++ return false; ++ status = XGetWindowProperty(m_dpy, DefaultRootWindow(m_dpy), prop, ++ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ if(status != Success || ! items_read) ++ { ++ if(status == Success) ++ XFree(data); ++ return false; ++ } ++ ++ wm_check = ((Window*)data)[0]; ++ XFree(data); ++ ++ status = XGetWindowProperty(m_dpy, wm_check, prop, ++ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ ++ if(status != Success || !items_read) ++ { ++ if(status == Success) ++ XFree(data); ++ return false; ++ } ++ ++ if(wm_check != ((Window*)data)[0]) ++ { ++ XFree(data); ++ return false; ++ } ++ ++ XFree(data); ++ ++ prop = XInternAtom(m_dpy, "_NET_WM_NAME", True); ++ if (prop == None) ++ { ++ CLog::Log(LOGDEBUG,"Window Manager Name: "); ++ return true; ++ } ++ ++ status = XGetWindowProperty(m_dpy, wm_check, prop, ++ 0L, (~0L), False, AnyPropertyType, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ ++ if(status == Success && items_read) ++ { ++ CLog::Log(LOGDEBUG,"Window Manager Name: %s", data); ++ } ++ else ++ CLog::Log(LOGDEBUG,"Window Manager Name: "); ++ ++ if(status == Success) ++ XFree(data); ++ ++ return true; ++} ++ + #endif +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index b2bd5a0..3e62cd8 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -103,6 +103,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + bool IsSuitableVisual(XVisualInfo *vInfo); + static int XErrorHandler(Display* dpy, XErrorEvent* error); + bool CreateIconPixmap(); ++ bool HasWindowManager(); + + CStopWatch m_screensaverReset; + }; +-- +1.9.3 + + +From eeeaef0535bbf85fbd61884fd9f70351d12d20fb Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 12 Jul 2012 11:11:47 +0200 +Subject: [PATCH 061/122] X11: dont set window on xrandr if no mode available + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index af82061..4f33c68 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -665,16 +665,17 @@ void CWinSystemX11::NotifyXRREvent() + CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); + m_windowDirty = true; + ++ if (!g_xrandr.Query(true)) ++ { ++ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); ++ return; ++ } ++ + // if external event update resolutions + if (!m_bIsInternalXrr) + { + UpdateResolutions(); + } +- else if (!g_xrandr.Query(true)) +- { +- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); +- return; +- } + m_bIsInternalXrr = false; + + CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); +-- +1.9.3 + + +From f545cc66674f273106e1aa8826f252e5131fd495 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 26 Jul 2012 09:34:28 +0200 +Subject: [PATCH 062/122] X11: fix crash after a resolution change on startup + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 4f33c68..bc4e963 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -223,7 +223,8 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + OnLostDevice(); + m_bIsInternalXrr = true; + g_xrandr.SetMode(out, mode); +- return true; ++ if (m_glWindow) ++ return true; + } + #endif + +-- +1.9.3 + + +From fdf2423a1a3c906719b16617a7b8b3caf55c5c0e Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 15 Sep 2012 18:27:29 +0200 +Subject: [PATCH 063/122] X11: lock graphics context in NotifyXRREvent + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index bc4e963..57a8d20 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -666,6 +666,8 @@ void CWinSystemX11::NotifyXRREvent() + CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); + m_windowDirty = true; + ++ CSingleLock lock(g_graphicsContext); ++ + if (!g_xrandr.Query(true)) + { + CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); +-- +1.9.3 + + +From 1be06d40be0af2fb83fc5870d64c678d783d447d Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 20 Aug 2012 16:06:39 +0200 +Subject: [PATCH 064/122] dvdplayer: observe pts counter overflow + +--- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 197 ++++++++++++++++++++- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 4 + + 2 files changed, 200 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 7f7df15..3a4b3f7 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -18,7 +18,6 @@ + * + */ + +-#include "system.h" + #ifndef __STDC_CONSTANT_MACROS + #define __STDC_CONSTANT_MACROS + #endif +@@ -26,6 +25,7 @@ + #define __STDC_LIMIT_MACROS + #endif + #ifdef TARGET_POSIX ++#include "system.h" + #include "stdint.h" + #endif + #include "DVDDemuxFFmpeg.h" +@@ -417,6 +417,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + CreateStreams(); + ++ m_bPtsWrapChecked = false; ++ m_bPtsWrap = false; ++ + return true; + } + +@@ -558,6 +561,12 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) + if (pts == (int64_t)AV_NOPTS_VALUE) + return DVD_NOPTS_VALUE; + ++ if (m_bPtsWrap) ++ { ++ if (pts < m_iStartTime && pts < m_iEndTime) ++ pts += m_iMaxTime; ++ } ++ + // do calculations in floats as they can easily overflow otherwise + // we don't care for having a completly exact timestamp anyway + double timestamp = (double)pts * num / den; +@@ -697,6 +706,24 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + m_pkt.pkt.pts = AV_NOPTS_VALUE; + } + ++ if (!m_bPtsWrapChecked && m_pFormatContext->iformat->flags & AVFMT_TS_DISCONT) ++ { ++ int defaultStream = av_find_default_stream_index(m_pFormatContext); ++ int64_t duration = m_pFormatContext->streams[defaultStream]->duration * 1.5; ++ m_iMaxTime = 1LL<streams[defaultStream]->pts_wrap_bits; ++ m_iStartTime = m_pFormatContext->streams[defaultStream]->start_time; ++ if (m_iStartTime != DVD_NOPTS_VALUE) ++ { ++ m_iEndTime = (m_iStartTime + duration) & ~m_iMaxTime; ++ if (m_iEndTime < m_iStartTime) ++ { ++ CLog::Log(LOGNOTICE,"CDVDDemuxFFmpeg::Read - file contains pts overflow"); ++ m_bPtsWrap = true; ++ } ++ } ++ m_bPtsWrapChecked = true; ++ } ++ + // copy contents into our own packet + pPacket->iSize = m_pkt.pkt.size; + +@@ -830,7 +857,16 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) + ret = av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); + + if(ret >= 0) ++ { + UpdateCurrentPTS(); ++ ++ // seek may fail silently on streams which allow discontinuity ++ // if current timestamp is way off asume a pts overflow and try bisect seek ++ if (m_bPtsWrap && fabs(time - m_iCurrentPts/1000) > 10000) ++ { ++ ret = SeekTimeDiscont(seek_pts, backwords) ? 1 : -1; ++ } ++ } + } + + if(m_iCurrentPts == DVD_NOPTS_VALUE) +@@ -849,6 +885,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) + return (ret >= 0); + } + ++bool CDVDDemuxFFmpeg::SeekTimeDiscont(int64_t pts, bool backwards) ++{ ++ // this code is taken from ffmpeg function ff_gen_search ++ // it is modified to assume a pts overflow if timestamp < start_time ++ if (!m_pFormatContext->iformat->read_timestamp) ++ return false; ++ ++ int defaultStream = av_find_default_stream_index(m_pFormatContext); ++ ++ if (defaultStream < 0) ++ { ++ return false; ++ } ++ ++ // timestamp for default must be expressed in AV_TIME_BASE units ++ pts = av_rescale_rnd(pts, m_pFormatContext->streams[defaultStream]->time_base.den, ++ AV_TIME_BASE * (int64_t)m_pFormatContext->streams[defaultStream]->time_base.num, ++ AV_ROUND_NEAR_INF); ++ ++ int64_t pos, pos_min, pos_max, pos_limit, ts, ts_min, ts_max; ++ int64_t start_pos, filesize; ++ int no_change; ++ ++ pos_min = m_pFormatContext->data_offset; ++ ts_min = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, ++ &pos_min, INT64_MAX); ++ if (ts_min == AV_NOPTS_VALUE) ++ return false; ++ ++ if(ts_min >= pts) ++ { ++ pos = pos_min; ++ return true; ++ } ++ ++ int step= 1024; ++ filesize = m_pInput->GetLength(); ++ pos_max = filesize - 1; ++ do ++ { ++ pos_max -= step; ++ ts_max = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, ++ &pos_max, pos_max + step); ++ step += step; ++ }while (ts_max == AV_NOPTS_VALUE && pos_max >= step); ++ ++ if (ts_max == AV_NOPTS_VALUE) ++ return false; ++ ++ if (ts_max < m_iStartTime && ts_max < m_iEndTime) ++ ts_max += m_iMaxTime; ++ ++ for(;;) ++ { ++ int64_t tmp_pos = pos_max + 1; ++ int64_t tmp_ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, ++ &tmp_pos, INT64_MAX); ++ if(tmp_ts == AV_NOPTS_VALUE) ++ break; ++ ++ if (tmp_ts < m_iStartTime && tmp_ts < m_iEndTime) ++ tmp_ts += m_iMaxTime; ++ ++ ts_max = tmp_ts; ++ pos_max = tmp_pos; ++ if (tmp_pos >= filesize) ++ break; ++ } ++ pos_limit = pos_max; ++ ++ if(ts_max <= pts) ++ { ++ bool ret = SeekByte(pos_max); ++ if (ret) ++ { ++ m_iCurrentPts = ConvertTimestamp(ts_max, m_pFormatContext->streams[defaultStream]->time_base.den, ++ m_pFormatContext->streams[defaultStream]->time_base.num); ++ } ++ return ret; ++ } ++ ++ if(ts_min > ts_max) ++ { ++ return false; ++ } ++ else if (ts_min == ts_max) ++ { ++ pos_limit = pos_min; ++ } ++ ++ no_change=0; ++ while (pos_min < pos_limit) ++ { ++ if (no_change == 0) ++ { ++ int64_t approximate_keyframe_distance= pos_max - pos_limit; ++ // interpolate position (better than dichotomy) ++ pos = av_rescale_rnd(pts - ts_min, pos_max - pos_min, ++ ts_max - ts_min, AV_ROUND_NEAR_INF) ++ + pos_min - approximate_keyframe_distance; ++ } ++ else if (no_change == 1) ++ { ++ // bisection, if interpolation failed to change min or max pos last time ++ pos = (pos_min + pos_limit) >> 1; ++ } ++ else ++ { ++ /* linear search if bisection failed, can only happen if there ++ are very few or no keyframes between min/max */ ++ pos = pos_min; ++ } ++ if (pos <= pos_min) ++ pos= pos_min + 1; ++ else if (pos > pos_limit) ++ pos= pos_limit; ++ start_pos = pos; ++ ++ ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, ++ &pos, INT64_MAX); ++ if (pos == pos_max) ++ no_change++; ++ else ++ no_change=0; ++ ++ if (ts == AV_NOPTS_VALUE) ++ { ++ return false; ++ } ++ ++ if (ts < m_iStartTime && ts < m_iEndTime) ++ ts += m_iMaxTime; ++ ++ if (pts <= ts) ++ { ++ pos_limit = start_pos - 1; ++ pos_max = pos; ++ ts_max = ts; ++ } ++ if (pts >= ts) ++ { ++ pos_min = pos; ++ ts_min = ts; ++ } ++ } ++ ++ pos = (backwards) ? pos_min : pos_max; ++ ts = (backwards) ? ts_min : ts_max; ++ ++ bool ret = SeekByte(pos); ++ if (ret) ++ { ++ m_iCurrentPts = ConvertTimestamp(ts, m_pFormatContext->streams[defaultStream]->time_base.den, ++ m_pFormatContext->streams[defaultStream]->time_base.num); ++ } ++ ++ return ret; ++} ++ + bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) + { + CSingleLock lock(m_critSection); +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index 44e101c..3b0f615 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -99,6 +99,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux + DemuxPacket* Read(); + + bool SeekTime(int time, bool backwords = false, double* startpts = NULL); ++ bool SeekTimeDiscont(int64_t pts, bool backwards); + bool SeekByte(int64_t pos); + int GetStreamLength(); + CDemuxStream* GetStream(int iStreamId); +@@ -153,5 +154,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux + AVPacket pkt; // packet ffmpeg returned + int result; // result from av_read_packet + }m_pkt; ++ ++ bool m_bPtsWrap, m_bPtsWrapChecked; ++ int64_t m_iStartTime, m_iMaxTime, m_iEndTime; + }; + +-- +1.9.3 + + +From 54e47fecc73ba79c08363cfacee3f40735a67f75 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 2 Oct 2012 13:02:10 +0200 +Subject: [PATCH 065/122] dvdplayer: avoid short screen flicker caused by + unnecessary reconfigure of renderer + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 9c36bdb..322a581 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1054,13 +1054,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + + #ifdef HAS_VIDEO_PLAYBACK + double config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate; ++ double render_framerate = g_graphicsContext.GetFPS(); ++ if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") == ADJUST_REFRESHRATE_OFF) ++ render_framerate = config_framerate; + /* check so that our format or aspect has changed. if it has, reconfigure renderer */ + if (!g_renderManager.IsConfigured() + || ( m_output.width != pPicture->iWidth ) + || ( m_output.height != pPicture->iHeight ) + || ( m_output.dwidth != pPicture->iDisplayWidth ) + || ( m_output.dheight != pPicture->iDisplayHeight ) +- || ( m_output.framerate != config_framerate ) ++ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 && render_framerate != config_framerate) + || ( m_output.color_format != (unsigned int)pPicture->format ) + || ( m_output.extended_format != pPicture->extended_format ) + || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified +-- +1.9.3 + + +From 2108c530b2bfc71dd01af6c059090458ee7a12bb Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 11 Oct 2012 12:05:50 +0200 +Subject: [PATCH 066/122] vdpau: advanced settings for auto deinterlacing + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++---- + xbmc/settings/AdvancedSettings.cpp | 4 ++++ + xbmc/settings/AdvancedSettings.h | 2 ++ + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index e58681b..3f87a7d 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1970,10 +1970,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) + if (method == VS_INTERLACEMETHOD_AUTO) + { + int deint = -1; +-// if (m_config.outHeight >= 720) +-// deint = g_advancedSettings.m_videoVDPAUdeintHD; +-// else +-// deint = g_advancedSettings.m_videoVDPAUdeintSD; ++ if (m_config.outHeight >= 720) ++ deint = g_advancedSettings.m_videoVDPAUdeintHD; ++ else ++ deint = g_advancedSettings.m_videoVDPAUdeintSD; + + if (deint != -1) + { +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index eff43dd..7532914 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -163,6 +163,8 @@ void CAdvancedSettings::Initialize() + m_videoAutoScaleMaxFps = 30.0f; + m_videoDisableBackgroundDeinterlace = false; + m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect ++ m_videoVDPAUdeintHD = -1; ++ m_videoVDPAUdeintSD = -1; + m_videoVDPAUtelecine = false; + m_videoVDPAUdeintSkipChromaHD = false; + m_DXVACheckCompatibility = false; +@@ -600,6 +602,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) + XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading); + XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); + XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); ++ XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD); ++ XMLUtils::GetInt(pElement,"vdpauSDdeint",m_videoVDPAUdeintSD); + XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine); + XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); + +diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h +index 3995f35..c43351d 100644 +--- a/xbmc/settings/AdvancedSettings.h ++++ b/xbmc/settings/AdvancedSettings.h +@@ -160,6 +160,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler + int m_videoPercentSeekBackwardBig; + CStdString m_videoPPFFmpegDeint; + CStdString m_videoPPFFmpegPostProc; ++ int m_videoVDPAUdeintHD; ++ int m_videoVDPAUdeintSD; + bool m_videoVDPAUtelecine; + bool m_videoVDPAUdeintSkipChromaHD; + bool m_musicUseTimeSeeking; +-- +1.9.3 + + +From 061ef4cc5b8d7f52f4567a7e6d4b1b7fe4233185 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 2 Nov 2012 13:20:03 +0100 +Subject: [PATCH 067/122] player: fix rewind + +--- + xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 30 +++++++++++++++++++----------- + xbmc/cores/dvdplayer/DVDPlayer.h | 7 ++++--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 +++- + xbmc/cores/dvdplayer/DVDPlayerVideo.h | 1 + + 5 files changed, 31 insertions(+), 16 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDMessage.h b/xbmc/cores/dvdplayer/DVDMessage.h +index 2ea8b8f..e8274f9 100644 +--- a/xbmc/cores/dvdplayer/DVDMessage.h ++++ b/xbmc/cores/dvdplayer/DVDMessage.h +@@ -220,7 +220,7 @@ class CDVDMsgPlayerSetState : public CDVDMsg + class CDVDMsgPlayerSeek : public CDVDMsg + { + public: +- CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false) ++ CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false, bool sync = true) + : CDVDMsg(PLAYER_SEEK) + , m_time(time) + , m_backward(backward) +@@ -228,6 +228,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg + , m_accurate(accurate) + , m_restore(restore) + , m_trickplay(trickplay) ++ , m_sync(sync) + {} + int GetTime() { return m_time; } + bool GetBackward() { return m_backward; } +@@ -235,6 +236,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg + bool GetAccurate() { return m_accurate; } + bool GetRestore() { return m_restore; } + bool GetTrickPlay() { return m_trickplay; } ++ bool GetSync() { return m_sync; } + private: + int m_time; + bool m_backward; +@@ -242,6 +244,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg + bool m_accurate; + bool m_restore; // whether to restore any EDL cut time + bool m_trickplay; ++ bool m_sync; + }; + + class CDVDMsgPlayerSeekChapter : public CDVDMsg +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index 097af37..c41b0b7 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -1634,11 +1634,13 @@ void CDVDPlayer::HandlePlaySpeed() + } + else if (m_CurrentVideo.id >= 0 + && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file +- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() ++ && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200)) ++ && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE) + && m_SpeedState.lasttime != GetTime()) + { + m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts(); + m_SpeedState.lasttime = GetTime(); ++ m_SpeedState.lastabstime = CDVDClock::GetAbsoluteClock(); + // check how much off clock video is when ff/rw:ing + // a problem here is that seeking isn't very accurate + // and since the clock will be resynced after seek +@@ -1657,7 +1659,7 @@ void CDVDPlayer::HandlePlaySpeed() + { + CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up"); + int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL); +- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true)); ++ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true, false)); + } + } + } +@@ -2143,7 +2145,7 @@ void CDVDPlayer::HandleMessages() + else + m_StateInput.dts = start; + +- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate()); ++ FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync()); + } + else + CLog::Log(LOGWARNING, "error while seeking"); +@@ -2279,9 +2281,10 @@ void CDVDPlayer::HandleMessages() + double offset; + offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; + offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; ++ offset = DVD_TIME_TO_MSEC(offset); + if(offset > 1000) offset = 1000; + if(offset < -1000) offset = -1000; +- m_State.time += DVD_TIME_TO_MSEC(offset); ++ m_State.time += offset; + m_State.timestamp = CDVDClock::GetAbsoluteClock(); + } + +@@ -2297,7 +2300,8 @@ void CDVDPlayer::HandleMessages() + // do a seek after rewind, clock is not in sync with current pts + if (m_playSpeed < 0 && speed >= 0) + { +- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); ++ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset); ++ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true)); + } + + // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE +@@ -3294,7 +3298,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) + return true; + } + +-void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) ++void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync) + { + double startpts; + if(accurate) +@@ -3306,19 +3310,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) + if(startpts != DVD_NOPTS_VALUE) + startpts -= m_offset_pts; + +- m_CurrentAudio.inited = false; ++ if (sync) ++ { ++ m_CurrentAudio.inited = false; ++ m_CurrentVideo.inited = false; ++ m_CurrentSubtitle.inited = false; ++ m_CurrentTeletext.inited = false; ++ } ++ + m_CurrentAudio.dts = DVD_NOPTS_VALUE; + m_CurrentAudio.startpts = startpts; + +- m_CurrentVideo.inited = false; + m_CurrentVideo.dts = DVD_NOPTS_VALUE; + m_CurrentVideo.startpts = startpts; + +- m_CurrentSubtitle.inited = false; + m_CurrentSubtitle.dts = DVD_NOPTS_VALUE; + m_CurrentSubtitle.startpts = startpts; + +- m_CurrentTeletext.inited = false; + m_CurrentTeletext.dts = DVD_NOPTS_VALUE; + m_CurrentTeletext.startpts = startpts; + +@@ -3362,7 +3370,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) + m_CurrentTeletext.started = false; + } + +- if(pts != DVD_NOPTS_VALUE) ++ if(pts != DVD_NOPTS_VALUE && sync) + m_clock.Discontinuity(pts); + UpdatePlayState(0); + +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h +index e2a836b..6ecaf3f 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.h ++++ b/xbmc/cores/dvdplayer/DVDPlayer.h +@@ -308,7 +308,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer + bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset); + + +- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true); ++ void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true); + + void HandleMessages(); + void HandlePlaySpeed(); +@@ -357,8 +357,9 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer + int m_playSpeed; + struct SSpeedState + { +- double lastpts; // holds last display pts during ff/rw operations +- double lasttime; ++ double lastpts; // holds last display pts during ff/rw operations ++ int64_t lasttime; ++ double lastabstime; + } m_SpeedState; + + int m_errorCount; +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 322a581..9c5469b 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1470,7 +1470,7 @@ double CDVDPlayerVideo::GetCurrentPts() + + if( m_stalled ) + iRenderPts = DVD_NOPTS_VALUE; +- else ++ else if ( m_speed == DVD_PLAYSPEED_NORMAL) + iRenderPts = iRenderPts - max(0.0, iSleepTime); + + return iRenderPts; +@@ -1570,6 +1570,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) + int iSkippedDeint = 0; + int iBufferLevel; + ++ m_droppingStats.m_lastPts = pts; ++ + // get decoder stats + if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) + iDecoderPts = pts; +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +index 59c7f09..65dea76 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h +@@ -50,6 +50,7 @@ class CDroppingStats + double m_totalGain; + double m_lastDecoderPts; + double m_lastRenderPts; ++ double m_lastPts; + unsigned int m_lateFrames; + unsigned int m_dropRequests; + }; +-- +1.9.3 + + +From 7b22cdc4f481439486e7a7803e1b8326970a0105 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 23 Nov 2012 17:41:12 +0100 +Subject: [PATCH 068/122] xrandr: fix query for multiple screens + +--- + xbmc/windowing/X11/XRandR.cpp | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 4685413..e610150 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -58,12 +58,14 @@ bool CXRandR::Query(bool force) + + m_outputs.clear(); + // query all screens ++ // we are happy if at least one screen returns results ++ bool success = false; + for(unsigned int screennum=0; screennum +Date: Sun, 2 Dec 2012 15:46:55 +0100 +Subject: [PATCH 069/122] X11: add debug log to print out refresh after xrr + event + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 57a8d20..a237dc0 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -685,6 +685,12 @@ void CWinSystemX11::NotifyXRREvent() + XOutput *out = g_xrandr.GetOutput(currentOutput); + XMode mode = g_xrandr.GetCurrentMode(currentOutput); + ++ if (out) ++ CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ ++ , out->name.c_str(), mode.id.c_str(), mode.hz); ++ else ++ CLog::Log(LOGWARNING, "%s - output name not set", __FUNCTION__); ++ + RESOLUTION_INFO res; + unsigned int i; + bool found(false); +-- +1.9.3 + + +From b20fadfdb740c77151b8081b25eca202f77a26be Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 11 Dec 2012 11:08:13 +0100 +Subject: [PATCH 070/122] X11: dont call XCloseDisplay on shutdown, it crashes + when powered doen by cec on ATI + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index a237dc0..ab660b1 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -112,7 +112,8 @@ bool CWinSystemX11::DestroyWindowSystem() + //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy + //so instead we just let m_dpy die on exit + // i have seen core dumps on ATI if the display is not closed here +- XCloseDisplay(m_dpy); ++ // crashes when shutting down via cec ++// XCloseDisplay(m_dpy); + } + + // m_SDLSurface is free()'d by SDL_Quit(). +-- +1.9.3 + + +From 60ae99538a05f982122c8db8be3e571aa126bf31 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gr=C3=A9gory=20Coutant?= +Date: Wed, 12 Dec 2012 19:49:47 +0100 +Subject: [PATCH 071/122] x11: support for multiple x screens + +--- + xbmc/windowing/X11/XRandR.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index e610150..5c53574 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -93,7 +93,7 @@ bool CXRandR::Query(bool force, int screennum) + pclose(file); + + TiXmlElement *pRootElement = xmlDoc.RootElement(); +- if (strcasecmp(pRootElement->Value(), "screen") != screennum) ++ if (atoi(pRootElement->Attribute("id")) != screennum) + { + // TODO ERROR + return false; +-- +1.9.3 + + +From 0da348dc4de87e881f60c08e8ebae902e9b5483b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 24 Dec 2012 16:02:42 +0100 +Subject: [PATCH 072/122] pvr: increase changes counter of stream on stream + change, cosmetics after dd307930d39d92f145a01a16600cd00e01ec39be + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +index 6c8e6db..95cc18f 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +@@ -328,9 +328,7 @@ void CDVDDemuxPVRClient::RequestStreams() + if (stm) + { + st = dynamic_cast(stm); +- if (!st +- || (st->codec != (AVCodecID)props.stream[i].iCodecId) +- || (st->iChannels != props.stream[i].iChannels)) ++ if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) + DisposeStream(i); + } + if (!m_streams[i]) +@@ -347,6 +345,7 @@ void CDVDDemuxPVRClient::RequestStreams() + st->iBitsPerSample = props.stream[i].iBitsPerSample; + m_streams[i] = st; + st->m_parser_split = true; ++ st->changes++; + } + else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_VIDEO) + { +-- +1.9.3 + + +From 16c2bfc0b96aa0c37e7dd025408e11b137746d83 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 17 Jan 2013 16:03:22 +0100 +Subject: [PATCH 073/122] X11: add keymapping for XF86XK_Sleep + +--- + xbmc/windowing/WinEventsX11.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index a62521f..263cb5a 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -143,6 +143,7 @@ static uint32_t SymMappingsX11[][2] = + , {XK_Break, XBMCK_BREAK} + , {XK_Menu, XBMCK_MENU} + , {XF86XK_PowerOff, XBMCK_POWER} ++, {XF86XK_Sleep, XBMCK_SLEEP} + , {XK_EcuSign, XBMCK_EURO} + , {XK_Undo, XBMCK_UNDO} + /* Media keys */ +-- +1.9.3 + + +From 5e72775b6d06288141aff9965c883ca1b488b00c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 21 Jan 2013 09:00:19 +0100 +Subject: [PATCH 074/122] X11: remove toggle full screen after resume + +--- + xbmc/powermanagement/PowerManager.cpp | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp +index 590a887..35b5a21 100644 +--- a/xbmc/powermanagement/PowerManager.cpp ++++ b/xbmc/powermanagement/PowerManager.cpp +@@ -268,11 +268,6 @@ void CPowerManager::OnWake() + #if defined(TARGET_WINDOWS) + ShowWindow(g_hWnd,SW_RESTORE); + SetForegroundWindow(g_hWnd); +-#elif !defined(TARGET_DARWIN_OSX) +- // Hack to reclaim focus, thus rehiding system mouse pointer. +- // Surely there's a better way? +- g_graphicsContext.ToggleFullScreenRoot(); +- g_graphicsContext.ToggleFullScreenRoot(); + #endif + } + g_application.ResetScreenSaver(); +-- +1.9.3 + + +From 51309d9fe2e1266b8dfbd745416ce3374a6faac1 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 23 Jan 2013 17:03:02 +0100 +Subject: [PATCH 075/122] xrandr: set screen on mode change command + +--- + xbmc/windowing/X11/XRandR.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 5c53574..4355ef7 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -246,7 +246,7 @@ bool CXRandR::SetMode(XOutput output, XMode mode) + m_currentMode = modeFound.id; + char cmd[255]; + if (getenv("XBMC_BIN_HOME")) +- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str()); ++ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); + else + return false; + CLog::Log(LOGINFO, "XRANDR: %s", cmd); +-- +1.9.3 + + +From 239fd16099ad491cd04d5251a1baa98f3e31b64f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 23 Jan 2013 17:03:39 +0100 +Subject: [PATCH 076/122] X11: recreate glx context when output changes + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- + xbmc/windowing/X11/WinSystemX11.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index ab660b1..4329a22 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -409,11 +409,11 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) + return true; + } + +-bool CWinSystemX11::RefreshGlxContext() ++bool CWinSystemX11::RefreshGlxContext(bool force) + { + bool retVal = false; + +- if (m_glContext) ++ if (m_glContext && !force) + { + CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); + glXMakeCurrent(m_dpy, None, NULL); +@@ -930,7 +930,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + } + + CDirtyRegionList dr; +- RefreshGlxContext(); ++ RefreshGlxContext(!m_currentOutput.Equals(output)); + XSync(m_dpy, FALSE); + g_graphicsContext.Clear(0); + g_graphicsContext.Flip(dr); +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 3e62cd8..2a1fb41 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -76,7 +76,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + void NotifyMouseCoverage(bool covered); + + protected: +- bool RefreshGlxContext(); ++ bool RefreshGlxContext(bool force); + void CheckDisplayEvents(); + void OnLostDevice(); + bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); +-- +1.9.3 + + +From e0d2e0951d95f35efa9cfd2e245aef8d5c84b02a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 14 Dec 2012 14:19:15 +0100 +Subject: [PATCH 077/122] pvr: do not show selection dialog for a single menu + hook + +--- + xbmc/pvr/addons/PVRClients.cpp | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp +index 8a59e93..75616cd 100644 +--- a/xbmc/pvr/addons/PVRClients.cpp ++++ b/xbmc/pvr/addons/PVRClients.cpp +@@ -733,6 +733,7 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF + { + hooks = client->GetMenuHooks(); + std::vector hookIDs; ++ int selection = 0; + + CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + pDialog->Reset(); +@@ -743,9 +744,11 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF + pDialog->Add(client->GetString(hooks->at(i).iLocalizedStringId)); + hookIDs.push_back(i); + } +- pDialog->DoModal(); +- +- int selection = pDialog->GetSelectedLabel(); ++ if (hookIDs.size() > 1) ++ { ++ pDialog->DoModal(); ++ selection = pDialog->GetSelectedLabel(); ++ } + if (selection >= 0) + client->CallMenuHook(hooks->at(hookIDs.at(selection)), item); + } +-- +1.9.3 + + +From 10bbc9f768eff809aab1207441922cc5c5dbb662 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 3 Feb 2013 08:17:16 +0100 +Subject: [PATCH 078/122] X11: use default screen parameters if no output + connected + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 55 ++++++++++++++++++++++--------------- + 1 file changed, 33 insertions(+), 22 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 4329a22..2adf8a0 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -207,25 +207,27 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + + XMode currmode = g_xrandr.GetCurrentMode(out.name); +- +- // flip h/w when rotated +- if (m_bIsRotated) ++ if (!currmode.name.empty()) + { +- int w = mode.w; +- mode.w = mode.h; +- mode.h = w; +- } ++ // flip h/w when rotated ++ if (m_bIsRotated) ++ { ++ int w = mode.w; ++ mode.w = mode.h; ++ mode.h = w; ++ } + +- // only call xrandr if mode changes +- if (currmode.w != mode.w || currmode.h != mode.h || +- currmode.hz != mode.hz || currmode.id != mode.id) +- { +- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); +- OnLostDevice(); +- m_bIsInternalXrr = true; +- g_xrandr.SetMode(out, mode); +- if (m_glWindow) +- return true; ++ // only call xrandr if mode changes ++ if (currmode.w != mode.w || currmode.h != mode.h || ++ currmode.hz != mode.hz || currmode.id != mode.id) ++ { ++ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); ++ OnLostDevice(); ++ m_bIsInternalXrr = true; ++ g_xrandr.SetMode(out, mode); ++ if (m_glWindow) ++ return true; ++ } + } + #endif + +@@ -272,9 +274,10 @@ void CWinSystemX11::UpdateResolutions() + else + #endif + { +- int x11screen = m_nScreen; +- int w = DisplayWidth(m_dpy, x11screen); +- int h = DisplayHeight(m_dpy, x11screen); ++ CSettings::Get().SetString("videoscreen.monitor", "Default"); ++ m_nScreen = DefaultScreen(m_dpy); ++ int w = DisplayWidth(m_dpy, m_nScreen); ++ int h = DisplayHeight(m_dpy, m_nScreen); + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); + } + +@@ -819,11 +822,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + Colormap cmap; + XSetWindowAttributes swa; + XVisualInfo *vi; ++ int x0 = 0; ++ int y0 = 0; + + XOutput *out = g_xrandr.GetOutput(output); + if (!out) + out = g_xrandr.GetOutput(m_currentOutput); +- m_nScreen = out->screen; ++ if (out) ++ { ++ m_nScreen = out->screen; ++ x0 = out->x; ++ y0 = out->y; ++ } ++ + vi = glXChooseVisual(m_dpy, m_nScreen, att); + cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); + +@@ -842,7 +853,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; + + m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), +- out->x, out->y, width, height, 0, vi->depth, ++ x0, y0, width, height, 0, vi->depth, + InputOutput, vi->visual, + mask, &swa); + +-- +1.9.3 + + +From 80dbddbbe3ed0bc9c768c2f74a134d07ff755218 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 23 Mar 2013 15:13:32 +0100 +Subject: [PATCH 079/122] X11: create parent window + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 69 +++++++++++++++++++++++-------------- + xbmc/windowing/X11/WinSystemX11.h | 2 +- + 2 files changed, 44 insertions(+), 27 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 2adf8a0..07f3f3d 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -55,6 +55,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase() + m_glContext = NULL; + m_dpy = NULL; + m_glWindow = 0; ++ m_mainWindow = 0; + m_bWasFullScreenBeforeMinimize = false; + m_minimized = false; + m_bIgnoreNextFocusMessage = false; +@@ -132,7 +133,7 @@ bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RES + + bool CWinSystemX11::DestroyWindow() + { +- if (!m_glWindow) ++ if (!m_mainWindow) + return true; + + if (m_glContext) +@@ -143,19 +144,21 @@ bool CWinSystemX11::DestroyWindow() + + if (m_invisibleCursor) + { +- XUndefineCursor(m_dpy, m_glWindow); ++ XUndefineCursor(m_dpy, m_mainWindow); + XFreeCursor(m_dpy, m_invisibleCursor); + m_invisibleCursor = 0; + } + + CWinEventsX11Imp::Quit(); + +- XUnmapWindow(m_dpy, m_glWindow); ++ XUnmapWindow(m_dpy, m_mainWindow); + XSync(m_dpy,TRUE); + XUngrabKeyboard(m_dpy, CurrentTime); + XUngrabPointer(m_dpy, CurrentTime); + XDestroyWindow(m_dpy, m_glWindow); ++ XDestroyWindow(m_dpy, m_mainWindow); + m_glWindow = 0; ++ m_mainWindow = 0; + + if (m_icon) + XFreePixmap(m_dpy, m_icon); +@@ -225,7 +228,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + OnLostDevice(); + m_bIsInternalXrr = true; + g_xrandr.SetMode(out, mode); +- if (m_glWindow) ++ if (m_mainWindow) + return true; + } + } +@@ -503,9 +506,9 @@ bool CWinSystemX11::RefreshGlxContext(bool force) + void CWinSystemX11::ShowOSMouse(bool show) + { + if (show) +- XUndefineCursor(m_dpy,m_glWindow); ++ XUndefineCursor(m_dpy,m_mainWindow); + else if (m_invisibleCursor) +- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); ++ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); + } + + void CWinSystemX11::ResetOSScreensaver() +@@ -588,10 +591,10 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered) + int result = -1; + while (result != GrabSuccess && result != AlreadyGrabbed) + { +- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); ++ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + XbmcThreads::ThreadSleep(100); + } +- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); + } + else + { +@@ -609,7 +612,7 @@ bool CWinSystemX11::Minimize() + g_graphicsContext.ToggleFullScreenRoot(); + } + +- XIconifyWindow(m_dpy, m_glWindow, m_nScreen); ++ XIconifyWindow(m_dpy, m_mainWindow, m_nScreen); + + m_minimized = true; + return true; +@@ -620,13 +623,13 @@ bool CWinSystemX11::Restore() + } + bool CWinSystemX11::Hide() + { +- XUnmapWindow(m_dpy, m_glWindow); ++ XUnmapWindow(m_dpy, m_mainWindow); + XSync(m_dpy, False); + return true; + } + bool CWinSystemX11::Show(bool raise) + { +- XMapWindow(m_dpy, m_glWindow); ++ XMapWindow(m_dpy, m_mainWindow); + XSync(m_dpy, False); + m_minimized = false; + return true; +@@ -776,7 +779,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + bool mouseActive = false; + float mouseX, mouseY; + +- if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) ++ if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) + { + mouseActive = g_Mouse.IsActive(); + if (mouseActive) +@@ -785,7 +788,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; +- bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, ++ bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return, + &root_x_return, &root_y_return, + &win_x_return, &win_y_return, + &mask_return); +@@ -804,7 +807,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + } + + // create main window +- if (!m_glWindow) ++ if (!m_mainWindow) + { + EnableSystemScreenSaver(false); + +@@ -845,22 +848,31 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + swa.border_pixel = fullscreen ? 0 : 5; + swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; + swa.colormap = cmap; +- swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; + swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + PropertyChangeMask | StructureNotifyMask | KeymapStateMask | + EnterWindowMask | LeaveWindowMask | ExposureMask; + unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; + +- m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), ++ m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), + x0, y0, width, height, 0, vi->depth, + InputOutput, vi->visual, + mask, &swa); + ++ swa.override_redirect = False; ++ swa.border_pixel = 0; ++ swa.event_mask = 0; ++ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap; ++ ++ m_glWindow = XCreateWindow(m_dpy, m_mainWindow, ++ 0, 0, width, height, 0, vi->depth, ++ InputOutput, vi->visual, ++ mask, &swa); ++ + if (fullscreen && hasWM) + { + Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); +- XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); ++ XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); + } + + // define invisible cursor +@@ -869,14 +881,14 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + static char noData[] = { 0,0,0,0,0,0,0,0 }; + black.red = black.green = black.blue = 0; + +- bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); ++ bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8); + m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, + &black, &black, 0, 0); + XFreePixmap(m_dpy, bitmapNoData); +- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); ++ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); + + //init X11 events +- CWinEventsX11Imp::Init(m_dpy, m_glWindow); ++ CWinEventsX11Imp::Init(m_dpy, m_mainWindow); + + changeWindow = true; + changeSize = true; +@@ -889,13 +901,17 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + + if (changeSize || changeWindow) + { ++ XResizeWindow(m_dpy, m_mainWindow, width, height); ++ } ++ ++ if ((width != m_nWidth) || (height != m_nHeight) || changeWindow) ++ { + XResizeWindow(m_dpy, m_glWindow, width, height); + } + + if (changeWindow) + { + m_icon = None; +- if (!fullscreen) + { + CreateIconPixmap(); + XWMHints *wm_hints; +@@ -912,21 +928,22 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + wm_hints->flags = StateHint | IconPixmapHint; + + XSync(m_dpy,False); +- XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, ++ XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, + NULL, 0, NULL, wm_hints, + NULL); + XFree(wm_hints); + + // register interest in the delete window message + Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); +- XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); ++ XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1); + } + XMapRaised(m_dpy, m_glWindow); ++ XMapRaised(m_dpy, m_mainWindow); + XSync(m_dpy,TRUE); + + if (changeWindow && mouseActive) + { +- XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); ++ XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); + } + + if (fullscreen) +@@ -934,10 +951,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + int result = -1; + while (result != GrabSuccess && result != AlreadyGrabbed) + { +- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); ++ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + XbmcThreads::ThreadSleep(100); + } +- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); + } + + CDirtyRegionList dr; +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 2a1fb41..e8993f1 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -81,7 +81,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + void OnLostDevice(); + bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); + +- Window m_glWindow; ++ Window m_glWindow, m_mainWindow; + GLXContext m_glContext; + Display* m_dpy; + Cursor m_invisibleCursor; +-- +1.9.3 + + +From 4ae9119a3d7b0fc5a3442b9247600015010b026e Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 24 Mar 2013 12:30:12 +0100 +Subject: [PATCH 080/122] X11: use system key repeat rate instead of hardcoded + one, taken from 58fd64b194e38b73b5f3132744bab35e994e7441 + +--- + xbmc/windowing/WinEventsX11.cpp | 58 +++++++++++++---------------------------- + xbmc/windowing/WinEventsX11.h | 5 +--- + 2 files changed, 19 insertions(+), 44 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 263cb5a..09f56ff 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; + WinEvents->m_xrrEventPending = false; +- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); + + // open input method + char *old_locale = NULL, *old_modifiers = NULL; +@@ -328,20 +327,6 @@ bool CWinEventsX11Imp::MessagePump() + memset(&xevent, 0, sizeof (XEvent)); + XNextEvent(WinEvents->m_display, &xevent); + +- // ignore events generated by auto-repeat +- if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) +- { +- XEvent peekevent; +- XPeekEvent(WinEvents->m_display, &peekevent); +- if ((peekevent.type == KeyPress) && +- (peekevent.xkey.keycode == xevent.xkey.keycode) && +- ((peekevent.xkey.time - xevent.xkey.time) < 2)) +- { +- XNextEvent(WinEvents->m_display, &peekevent); +- continue; +- } +- } +- + if (XFilterEvent(&xevent, None)) + continue; + +@@ -364,7 +349,6 @@ bool CWinEventsX11Imp::MessagePump() + if (WinEvents->m_xic) + XSetICFocus(WinEvents->m_xic); + g_application.m_AppFocused = true; +- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); + WinEvents->m_keymodState = 0; + if (serial == xevent.xfocus.serial) + break; +@@ -377,7 +361,6 @@ bool CWinEventsX11Imp::MessagePump() + if (WinEvents->m_xic) + XUnsetICFocus(WinEvents->m_xic); + g_application.m_AppFocused = false; +- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); + g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); + serial = xevent.xfocus.serial; + break; +@@ -433,7 +416,7 @@ bool CWinEventsX11Imp::MessagePump() + { + newEvent.key.keysym.unicode = keybuf[0]; + } +- ret |= ProcessKey(newEvent, 500); ++ ret |= ProcessKey(newEvent); + break; + } + +@@ -472,7 +455,7 @@ bool CWinEventsX11Imp::MessagePump() + newEvent.key.keysym.unicode = keys[i]; + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; +- ret |= ProcessKey(newEvent, 500); ++ ret |= ProcessKey(newEvent); + } + if (keys.length() > 0) + { +@@ -483,7 +466,7 @@ bool CWinEventsX11Imp::MessagePump() + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; + +- ret |= ProcessKey(newEvent, 500); ++ ret |= ProcessKey(newEvent); + } + break; + } +@@ -494,7 +477,7 @@ bool CWinEventsX11Imp::MessagePump() + newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; +- ret |= ProcessKey(newEvent, 500); ++ ret |= ProcessKey(newEvent); + break; + } + +@@ -504,6 +487,18 @@ bool CWinEventsX11Imp::MessagePump() + + case KeyRelease: + { ++ // if we have a queued press directly after, this is a repeat ++ if( XEventsQueued( WinEvents->m_display, QueuedAfterReading ) ) ++ { ++ XEvent next_event; ++ XPeekEvent( WinEvents->m_display, &next_event ); ++ if(next_event.type == KeyPress ++ && next_event.xkey.window == xevent.xkey.window ++ && next_event.xkey.keycode == xevent.xkey.keycode ++ && (next_event.xkey.time - xevent.xkey.time < 2) ) ++ continue; ++ } ++ + XBMC_Event newEvent; + KeySym xkeysym; + memset(&newEvent, 0, sizeof(newEvent)); +@@ -513,7 +508,7 @@ bool CWinEventsX11Imp::MessagePump() + newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); + newEvent.key.state = xevent.xkey.state; + newEvent.key.type = xevent.xkey.type; +- ret |= ProcessKey(newEvent, 0); ++ ret |= ProcessKey(newEvent); + break; + } + +@@ -589,8 +584,6 @@ bool CWinEventsX11Imp::MessagePump() + + }// while + +- ret |= ProcessKeyRepeat(); +- + #if defined(HAS_XRANDR) + if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) + { +@@ -635,7 +628,7 @@ size_t CWinEventsX11Imp::GetQueueSize() + return ret; + } + +-bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) ++bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) + { + if (event.type == XBMC_KEYDOWN) + { +@@ -673,8 +666,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) + break; + } + event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; +- memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); +- WinEvents->m_repeatKeyTimeout.Set(repeatDelay); + + bool ret = ProcessShortcuts(event); + if (ret) +@@ -715,7 +706,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) + break; + } + event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; +- memset(&(WinEvents->m_lastKey), 0, sizeof(event)); + } + + return g_application.OnEvent(event); +@@ -738,18 +728,6 @@ bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) + return false; + } + +-bool CWinEventsX11Imp::ProcessKeyRepeat() +-{ +- if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) +- { +- if (WinEvents->m_repeatKeyTimeout.IsTimePast()) +- { +- return ProcessKey(WinEvents->m_lastKey, 10); +- } +- } +- return false; +-} +- + XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) + { + // try direct mapping first +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index c69169c..6429291 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -47,8 +47,7 @@ class CWinEventsX11Imp + + protected: + static XBMCKey LookupXbmcKeySym(KeySym keysym); +- static bool ProcessKey(XBMC_Event &event, int repeatDelay); +- static bool ProcessKeyRepeat(); ++ static bool ProcessKey(XBMC_Event &event); + static bool ProcessShortcuts(XBMC_Event& event); + static CWinEventsX11Imp *WinEvents; + Display *m_display; +@@ -58,8 +57,6 @@ class CWinEventsX11Imp + size_t m_keybuf_len; + XIM m_xim; + XIC m_xic; +- XBMC_Event m_lastKey; +- XbmcThreads::EndTime m_repeatKeyTimeout; + std::map m_symLookupTable; + int m_keymodState; + bool m_structureChanged; +-- +1.9.3 + + +From 075e9900d9df1194d183aae294b23012cd226d45 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 24 Mar 2013 16:04:48 +0100 +Subject: [PATCH 081/122] linux: use CLOCK_MONOTONIC_RAW as this is not subject + to NTP + +--- + xbmc/threads/SystemClock.cpp | 2 +- + xbmc/utils/TimeUtils.cpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/threads/SystemClock.cpp b/xbmc/threads/SystemClock.cpp +index 657a154..35e3abf 100644 +--- a/xbmc/threads/SystemClock.cpp ++++ b/xbmc/threads/SystemClock.cpp +@@ -43,7 +43,7 @@ namespace XbmcThreads + now_time = (uint64_t)timeGetTime(); + #else + struct timespec ts = {}; +- clock_gettime(CLOCK_MONOTONIC, &ts); ++ clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + now_time = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); + #endif + if (!start_time_set) +diff --git a/xbmc/utils/TimeUtils.cpp b/xbmc/utils/TimeUtils.cpp +index c06b8c5..4390d2e 100644 +--- a/xbmc/utils/TimeUtils.cpp ++++ b/xbmc/utils/TimeUtils.cpp +@@ -43,7 +43,7 @@ int64_t CurrentHostCounter(void) + return( (int64_t)PerformanceCount.QuadPart ); + #else + struct timespec now; +- clock_gettime(CLOCK_MONOTONIC, &now); ++ clock_gettime(CLOCK_MONOTONIC_RAW, &now); + return( ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec ); + #endif + } +-- +1.9.3 + + +From 6a6497886e760948d5410e59627552413edeb996 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Mar 2013 15:18:53 +0100 +Subject: [PATCH 082/122] OMXPlayer: some caching fixes for pvr + +--- + xbmc/cores/omxplayer/OMXPlayer.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp +index 502df4a..c8579a2 100644 +--- a/xbmc/cores/omxplayer/OMXPlayer.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayer.cpp +@@ -2548,7 +2548,8 @@ void COMXPlayer::HandleMessages() + m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true)); + + m_playSpeed = speed; +- m_caching = CACHESTATE_DONE; ++ if (m_caching != CACHESTATE_PVR && m_playSpeed != DVD_PLAYSPEED_NORMAL) ++ m_caching = CACHESTATE_DONE; + m_clock.SetSpeed(speed); + m_av_clock.OMXSetSpeed(speed); + m_av_clock.OMXPause(); +-- +1.9.3 + + +From f89d8be74446e5963e163a50ed0e1038d927092b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Mar 2013 20:50:59 +0100 +Subject: [PATCH 083/122] fix incorrect display of fps when dr kicks in + +--- + xbmc/Application.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 46993d5..2f5cb7c 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -2341,10 +2341,11 @@ void CApplication::Render() + if (frameTime < singleFrameTime) + Sleep(singleFrameTime - frameTime); + } +- m_lastFrameTime = XbmcThreads::SystemClockMillis(); + + if (flip) + g_graphicsContext.Flip(dirtyRegions); ++ ++ m_lastFrameTime = XbmcThreads::SystemClockMillis(); + CTimeUtils::UpdateFrameTime(flip); + + g_renderManager.UpdateResolution(); +-- +1.9.3 + + +From 498b63dad0d49a13a76019bbdfaec506fafc727b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 13 Apr 2013 08:32:06 +0200 +Subject: [PATCH 084/122] X11: fix mouse coverage + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++++--- + xbmc/windowing/X11/WinSystemX11.h | 1 + + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 07f3f3d..2acb36d 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -583,10 +583,10 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining) + + void CWinSystemX11::NotifyMouseCoverage(bool covered) + { +- if (!m_bFullScreen) ++ if (!m_bFullScreen || !m_mainWindow) + return; + +- if (covered) ++ if (covered && !m_bIsGrabbed) + { + int result = -1; + while (result != GrabSuccess && result != AlreadyGrabbed) +@@ -595,11 +595,13 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered) + XbmcThreads::ThreadSleep(100); + } + XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ m_bIsGrabbed = true; + } +- else ++ else if (!covered && m_bIsGrabbed) + { + XUngrabKeyboard(m_dpy, CurrentTime); + XUngrabPointer(m_dpy, CurrentTime); ++ m_bIsGrabbed = false; + } + } + +@@ -955,7 +957,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + XbmcThreads::ThreadSleep(100); + } + XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ m_bIsGrabbed = true; + } ++ else ++ m_bIsGrabbed = false; + + CDirtyRegionList dr; + RefreshGlxContext(!m_currentOutput.Equals(output)); +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index e8993f1..5cccfb7 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -90,6 +90,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; + bool m_bIgnoreNextFocusMessage; ++ bool m_bIsGrabbed; + int m_RREventBase; + CCriticalSection m_resourceSection; + std::vector m_resources; +-- +1.9.3 + + +From 580640ce7f74c01ae7aff6c68bafef05d2a4e52b Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 8 May 2013 13:14:58 +0200 +Subject: [PATCH 085/122] X11: fix incorrectly used screen num in desktop + resolution + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 2acb36d..101ba98 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -268,9 +268,9 @@ void CWinSystemX11::UpdateResolutions() + XMode mode = g_xrandr.GetCurrentMode(currentMonitor); + m_bIsRotated = out->isRotated; + if (!m_bIsRotated) +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz); ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); + else +- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz); ++ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; + } +@@ -305,6 +305,7 @@ void CWinSystemX11::UpdateResolutions() + CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", + mode.id.c_str(), mode.name.c_str(), mode.hz, mode.w, mode.h); + RESOLUTION_INFO res; ++ res.iScreen = 0; // not used by X11 + res.iWidth = mode.w; + res.iHeight = mode.h; + res.iScreenWidth = mode.w; +-- +1.9.3 + + +From a14a6760bff76fc016482adb4142d646d2366aeb Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 9 May 2013 12:07:09 +0200 +Subject: [PATCH 086/122] X11: do not overwrite user selected monitor with + fallback + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 31 ++++++++++++++----------------- + xbmc/windowing/X11/WinSystemX11.h | 1 + + 2 files changed, 15 insertions(+), 17 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 101ba98..c614c9b 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -172,7 +172,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + && m_nHeight == newHeight) + return true; + +- if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor"))) ++ if (!SetWindow(newWidth, newHeight, false, m_userOutput)) + { + return false; + } +@@ -180,7 +180,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + m_nWidth = newWidth; + m_nHeight = newHeight; + m_bFullScreen = false; +- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); ++ m_currentOutput = m_userOutput; + + return false; + } +@@ -234,13 +234,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + #endif + +- if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) ++ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, m_userOutput)) + return false; + + m_nWidth = res.iWidth; + m_nHeight = res.iHeight; + m_bFullScreen = fullScreen; +- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); ++ m_currentOutput = m_userOutput; + + return true; + } +@@ -250,34 +250,32 @@ void CWinSystemX11::UpdateResolutions() + CWinSystemBase::UpdateResolutions(); + + #if defined(HAS_XRANDR) +- CStdString currentMonitor; + int numScreens = XScreenCount(m_dpy); + g_xrandr.SetNumScreens(numScreens); + if(g_xrandr.Query(true)) + { +- currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); ++ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); + // check if the monitor is connected +- XOutput *out = g_xrandr.GetOutput(currentMonitor); ++ XOutput *out = g_xrandr.GetOutput(m_userOutput); + if (!out) + { + // choose first output +- currentMonitor = g_xrandr.GetModes()[0].name; +- out = g_xrandr.GetOutput(currentMonitor); +- CSettings::Get().SetString("videoscreen.monitor", currentMonitor); ++ m_userOutput = g_xrandr.GetModes()[0].name; ++ out = g_xrandr.GetOutput(m_userOutput); + } +- XMode mode = g_xrandr.GetCurrentMode(currentMonitor); ++ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); + m_bIsRotated = out->isRotated; + if (!m_bIsRotated) + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); + else + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); + CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; +- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; ++ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = m_userOutput; + } + else + #endif + { +- CSettings::Get().SetString("videoscreen.monitor", "Default"); ++ m_userOutput = "No Output"; + m_nScreen = DefaultScreen(m_dpy); + int w = DisplayWidth(m_dpy, m_nScreen); + int h = DisplayHeight(m_dpy, m_nScreen); +@@ -291,7 +289,7 @@ void CWinSystemX11::UpdateResolutions() + + CLog::Log(LOGINFO, "Available videomodes (xrandr):"); + +- XOutput *out = g_xrandr.GetOutput(currentMonitor); ++ XOutput *out = g_xrandr.GetOutput(m_userOutput); + string modename = ""; + + if (out != NULL) +@@ -691,9 +689,8 @@ void CWinSystemX11::NotifyXRREvent() + } + m_bIsInternalXrr = false; + +- CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); +- XOutput *out = g_xrandr.GetOutput(currentOutput); +- XMode mode = g_xrandr.GetCurrentMode(currentOutput); ++ XOutput *out = g_xrandr.GetOutput(m_userOutput); ++ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); + + if (out) + CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 5cccfb7..1b658e2 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -96,6 +96,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + std::vector m_resources; + uint64_t m_dpyLostTime; + CStdString m_currentOutput; ++ CStdString m_userOutput; + bool m_windowDirty; + bool m_bIsInternalXrr; + bool m_newGlContext; +-- +1.9.3 + + +From 937e15c2c5ce7330b416f8939d63dc3cbfded53e Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 12 May 2013 10:50:30 +0200 +Subject: [PATCH 087/122] xrandr: add turn on/off to wrapper + +--- + xbmc/windowing/X11/XRandR.cpp | 78 +++++++++++++++++++++++++++++++++++++++---- + xbmc/windowing/X11/XRandR.h | 6 ++-- + 2 files changed, 75 insertions(+), 9 deletions(-) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 4355ef7..223472c 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -29,6 +29,7 @@ + #include "utils/XBMCTinyXML.h" + #include "utils/StringUtils.h" + #include "../xbmc/utils/log.h" ++#include "threads/SystemClock.h" + + #if defined(TARGET_FREEBSD) + #include +@@ -45,7 +46,7 @@ CXRandR::CXRandR(bool query) + Query(); + } + +-bool CXRandR::Query(bool force) ++bool CXRandR::Query(bool force, bool ignoreoff) + { + if (!force) + if (m_bInit) +@@ -62,13 +63,13 @@ bool CXRandR::Query(bool force) + bool success = false; + for(unsigned int screennum=0; screennumAttribute("current"), "true") == 0); + xoutput.modes.push_back(xmode); + if (xmode.isCurrent) +- { + hascurrent = true; +- } + } +- if (hascurrent) ++ if (hascurrent || !ignoreoff) + m_outputs.push_back(xoutput); + else + CLog::Log(LOGWARNING, "CXRandR::Query - output %s has no current mode, assuming disconnected", xoutput.name.c_str()); +@@ -148,6 +147,71 @@ bool CXRandR::Query(bool force, int screennum) + return m_outputs.size() > 0; + } + ++bool CXRandR::TurnOffOutput(CStdString name) ++{ ++ CStdString cmd; ++ cmd = getenv("XBMC_BIN_HOME"); ++ cmd += "/xbmc-xrandr"; ++ cmd.AppendFormat(" --output %s --off", name.c_str()); ++ ++ int status = system(cmd.c_str()); ++ if (status == -1) ++ return false; ++ ++ if (WEXITSTATUS(status) != 0) ++ return false; ++ ++ return true; ++} ++ ++bool CXRandR::TurnOnOutput(CStdString name) ++{ ++ XOutput *output = GetOutput(name); ++ if (!output) ++ return false; ++ ++ XMode mode = GetCurrentMode(output->name); ++ if (mode.isCurrent) ++ return true; ++ ++ // get preferred mode ++ for (unsigned int j = 0; j < m_outputs.size(); j++) ++ { ++ if (m_outputs[j].name == output->name) ++ { ++ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++) ++ { ++ if (m_outputs[j].modes[i].isPreferred) ++ { ++ mode = m_outputs[j].modes[i]; ++ break; ++ } ++ } ++ } ++ } ++ ++ if (!mode.isPreferred) ++ return false; ++ ++ if (!SetMode(*output, mode)) ++ return false; ++ ++ XbmcThreads::EndTime timeout(5000); ++ while (!timeout.IsTimePast()) ++ { ++ if (!Query(true)) ++ return false; ++ ++ output = GetOutput(name); ++ if (output && output->h > 0) ++ return true; ++ ++ Sleep(200); ++ } ++ ++ return false; ++} ++ + std::vector CXRandR::GetModes(void) + { + Query(); +@@ -161,7 +225,7 @@ void CXRandR::SaveState() + + bool CXRandR::SetMode(XOutput output, XMode mode) + { +- if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) ++ if ((output.name == "" && mode.id == "")) + return true; + + Query(); +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index d37838a..059062f 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -94,8 +94,8 @@ class CXRandR + { + public: + CXRandR(bool query=false); +- bool Query(bool force=false); +- bool Query(bool force, int screennum); ++ bool Query(bool force=false, bool ignoreoff=true); ++ bool Query(bool force, int screennum, bool ignoreoff=true); + std::vector GetModes(void); + XMode GetCurrentMode(CStdString outputName); + XOutput *GetOutput(CStdString outputName); +@@ -104,6 +104,8 @@ class CXRandR + void SaveState(); + void SetNumScreens(unsigned int num); + bool IsOutputConnected(CStdString name); ++ bool TurnOffOutput(CStdString name); ++ bool TurnOnOutput(CStdString name); + //bool Has1080i(); + //bool Has1080p(); + //bool Has720p(); +-- +1.9.3 + + +From 9861afa69f32ac694cdf6227d09f7ce5a4ee2b5e Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 19 May 2013 12:55:35 +0200 +Subject: [PATCH 088/122] xrandr: add GetPreferredMode to wrapper + +--- + xbmc/windowing/X11/XRandR.cpp | 23 +++++++++++++++++++++++ + xbmc/windowing/X11/XRandR.h | 1 + + 2 files changed, 24 insertions(+) + +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 223472c..62003f5 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -347,6 +347,29 @@ XMode CXRandR::GetCurrentMode(CStdString outputName) + return result; + } + ++XMode CXRandR::GetPreferredMode(CStdString outputName) ++{ ++ Query(); ++ XMode result; ++ ++ for (unsigned int j = 0; j < m_outputs.size(); j++) ++ { ++ if (m_outputs[j].name == outputName || outputName == "") ++ { ++ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++) ++ { ++ if (m_outputs[j].modes[i].isPreferred) ++ { ++ result = m_outputs[j].modes[i]; ++ break; ++ } ++ } ++ } ++ } ++ ++ return result; ++} ++ + void CXRandR::LoadCustomModeLinesToAllOutputs(void) + { + Query(); +diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h +index 059062f..ab7cc63 100644 +--- a/xbmc/windowing/X11/XRandR.h ++++ b/xbmc/windowing/X11/XRandR.h +@@ -98,6 +98,7 @@ class CXRandR + bool Query(bool force, int screennum, bool ignoreoff=true); + std::vector GetModes(void); + XMode GetCurrentMode(CStdString outputName); ++ XMode GetPreferredMode(CStdString outputName); + XOutput *GetOutput(CStdString outputName); + bool SetMode(XOutput output, XMode mode); + void LoadCustomModeLinesToAllOutputs(void); +-- +1.9.3 + + +From 714238cc825e4f8addaa4337ecd7603139051595 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 11 May 2013 17:12:12 +0200 +Subject: [PATCH 089/122] X11: multi-head improvement - poll for desired output + if we do not get an xrr event + +--- + language/English/strings.po | 9 +++- + system/settings/settings.xml | 8 +++- + xbmc/settings/DisplaySettings.cpp | 4 ++ + xbmc/windowing/WinEventsX11.cpp | 6 +++ + xbmc/windowing/WinEventsX11.h | 1 + + xbmc/windowing/X11/WinSystemX11.cpp | 83 +++++++++++++++++++++++++++++++++---- + xbmc/windowing/X11/WinSystemX11.h | 2 +- + xbmc/windowing/X11/XRandR.cpp | 6 ++- + 8 files changed, 106 insertions(+), 13 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 685847c..9cc2090 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -6558,7 +6558,7 @@ msgctxt "#14071" + msgid "Allow file renaming and deletion" + msgstr "" + +-#empty strings from id 14072 to 14073 ++#empty strings from id 14073 to 14073 + + msgctxt "#14074" + msgid "Set timezone" +@@ -6696,7 +6696,12 @@ msgctxt "#14101" + msgid "Acceleration" + msgstr "" + +-#empty strings from id 14102 to 15011 ++#: xbmc/settings/settings.xml ++msgctxt "#14102" ++msgid "Switch off other Monitor" ++msgstr "" ++ ++#empty strings from id 14103 to 15011 + + #: xbmc/video/VideoDatabase.cpp + msgctxt "#15012" +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index fba4561..798be52 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2252,7 +2252,7 @@ + + + +- HAS_GLX ++ HAS_GLX + 0 + Default + +@@ -2260,6 +2260,11 @@ + + + ++ ++ HAS_GLX ++ 0 ++ false ++ + + 0 + 0 +@@ -2312,6 +2317,7 @@ + + + ++ !HAS_GLX + 1 + false + +diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp +index db2f667..efb6cb1 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -274,6 +274,10 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + m_resolutionChangeAborted = false; + } + } ++ else if (settingId == "videoscreen.monitorsingle") ++ { ++ g_Windowing.UpdateResolutions(); ++ } + + return true; + } +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 09f56ff..908c8b6 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -213,6 +213,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; + WinEvents->m_xrrEventPending = false; ++ WinEvents->m_xrrPollTimer.Set(3000); + + // open input method + char *old_locale = NULL, *old_modifiers = NULL; +@@ -591,6 +592,11 @@ bool CWinEventsX11Imp::MessagePump() + g_Windowing.NotifyXRREvent(); + WinEvents->m_xrrEventPending = false; + } ++ else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast()) ++ { ++ g_Windowing.NotifyXRREvent(true); ++ WinEvents->m_xrrPollTimer.Set(3000); ++ } + #endif + + #ifdef HAS_SDL_JOYSTICK +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index 6429291..91a604f 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -62,5 +62,6 @@ class CWinEventsX11Imp + bool m_structureChanged; + int m_RREventBase; + XbmcThreads::EndTime m_xrrFailSafeTimer; ++ XbmcThreads::EndTime m_xrrPollTimer; + bool m_xrrEventPending; + }; +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index c614c9b..b3fe5102 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -252,18 +252,62 @@ void CWinSystemX11::UpdateResolutions() + #if defined(HAS_XRANDR) + int numScreens = XScreenCount(m_dpy); + g_xrandr.SetNumScreens(numScreens); +- if(g_xrandr.Query(true)) ++ ++ bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle"); ++ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); ++ if (m_userOutput.Equals("Default")) ++ switchOnOff = false; ++ ++ if(g_xrandr.Query(true, !switchOnOff)) + { +- m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); + // check if the monitor is connected +- XOutput *out = g_xrandr.GetOutput(m_userOutput); ++ // might take a while when connected to a receiver ++ XbmcThreads::EndTime timeout(3000); ++ XOutput *out = NULL; ++ while (!m_userOutput.Equals("Default") && !timeout.IsTimePast()) ++ { ++ out = g_xrandr.GetOutput(m_userOutput); ++ if (out) ++ { ++ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); ++ if (mode.isCurrent || switchOnOff) ++ break; ++ else ++ { ++ out = NULL; ++ break; ++ } ++ } ++ ++ Sleep(500); ++ if (!g_xrandr.Query(true, !switchOnOff)) ++ break; ++ } + if (!out) + { +- // choose first output + m_userOutput = g_xrandr.GetModes()[0].name; + out = g_xrandr.GetOutput(m_userOutput); + } ++ ++ // switch on output ++ if(switchOnOff) ++ g_xrandr.TurnOnOutput(m_userOutput); ++ ++ // switch off other outputs if desired ++ if (switchOnOff) ++ { ++ std::vector outputs = g_xrandr.GetModes(); ++ for (int i=0; iisRotated; + if (!m_bIsRotated) + UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); +@@ -382,7 +426,9 @@ bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) + void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) + { + vector outs; ++ g_xrandr.Query(true); + outs = g_xrandr.GetModes(); ++ outputs->push_back("Default"); + for(unsigned int i=0; ipush_back(outs[i].name); +@@ -669,14 +715,34 @@ void CWinSystemX11::CheckDisplayEvents() + #endif + } + +-void CWinSystemX11::NotifyXRREvent() ++void CWinSystemX11::NotifyXRREvent(bool poll) + { +- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); ++ // we may not get an event if desired monitor becomes available ++ // hence we need to poll ++ if (poll) ++ { ++ CStdString output = CSettings::Get().GetString("videoscreen.monitor"); ++ if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default")) ++ return; ++ ++ int numScreens = XScreenCount(m_dpy); ++ g_xrandr.SetNumScreens(numScreens); ++ g_xrandr.Query(true); ++ if (!g_xrandr.IsOutputConnected(output)) ++ return; ++ ++ // if output is turned off by user, respect it ++ XMode mode = g_xrandr.GetCurrentMode(output); ++ if (!mode.isCurrent) ++ return; ++ } ++ ++ CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll); + m_windowDirty = true; + + CSingleLock lock(g_graphicsContext); + +- if (!g_xrandr.Query(true)) ++ if (!g_xrandr.Query(!poll)) + { + CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); + return; +@@ -703,7 +769,8 @@ void CWinSystemX11::NotifyXRREvent() + bool found(false); + for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) + { +- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) ++ res = CDisplaySettings::Get().GetResolutionInfo(i); ++ if (CDisplaySettings::Get().GetResolutionInfo(i).strId.Equals(mode.id)) + { + found = true; + break; +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 1b658e2..7ec5be4 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -70,7 +70,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + Display* GetDisplay() { return m_dpy; } + GLXWindow GetWindow() { return m_glWindow; } + GLXContext GetGlxContext() { return m_glContext; } +- void NotifyXRREvent(); ++ void NotifyXRREvent(bool poll = false); + void GetConnectedOutputs(std::vector *outputs); + bool IsCurrentOutput(CStdString output); + void NotifyMouseCoverage(bool covered); +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 62003f5..8525ede 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -149,10 +149,14 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) + + bool CXRandR::TurnOffOutput(CStdString name) + { ++ XOutput *output = GetOutput(name); ++ if (!output) ++ return false; ++ + CStdString cmd; + cmd = getenv("XBMC_BIN_HOME"); + cmd += "/xbmc-xrandr"; +- cmd.AppendFormat(" --output %s --off", name.c_str()); ++ cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str()); + + int status = system(cmd.c_str()); + if (status == -1) +-- +1.9.3 + + +From b42bdcbafb6b2e1c36ee4693ee5aebb730a29bb8 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 15 May 2013 09:14:34 +0200 +Subject: [PATCH 090/122] X11: ignore mouse move event form other windows + +--- + xbmc/windowing/WinEventsX11.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 908c8b6..938ad26 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -328,7 +328,7 @@ bool CWinEventsX11Imp::MessagePump() + memset(&xevent, 0, sizeof (XEvent)); + XNextEvent(WinEvents->m_display, &xevent); + +- if (XFilterEvent(&xevent, None)) ++ if (XFilterEvent(&xevent, WinEvents->m_window)) + continue; + + switch (xevent.type) +@@ -529,6 +529,8 @@ bool CWinEventsX11Imp::MessagePump() + + case MotionNotify: + { ++ if (xevent.xmotion.window != WinEvents->m_window) ++ break; + XBMC_Event newEvent; + memset(&newEvent, 0, sizeof(newEvent)); + newEvent.type = XBMC_MOUSEMOTION; +-- +1.9.3 + + +From 047a175bf8900da078611cf030c51b16f3ad7edc Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 11 Jun 2013 16:20:29 +0200 +Subject: [PATCH 091/122] renderer: allow some lateness within vblank interval + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++-- + xbmc/cores/VideoRenderers/RenderManager.h | 1 + + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index f4b381e..5e9f666 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -380,6 +380,8 @@ void CXBMCRenderManager::FrameFinish() + if(g_graphicsContext.IsFullScreenVideo()) + WaitPresentTime(m.timestamp); + ++ m_clock_framefinish = GetPresentTime(); ++ + { CSingleLock lock(m_presentlock); + + if(m_presentstep == PRESENT_FRAME) +@@ -1032,6 +1034,12 @@ void CXBMCRenderManager::PrepareNextRender() + + double clocktime = GetPresentTime(); + double frametime = 1.0 / GetMaximumFPS(); ++ double correction = 0.0; ++ int fps = g_VideoReferenceClock.GetRefreshRate(); ++ if((fps > 0) && g_graphicsContext.IsFullScreenVideo() && (clocktime != m_clock_framefinish)) ++ { ++ correction = frametime; ++ } + + /* see if any future queued frames are already due */ + std::deque::reverse_iterator curr, prev; +@@ -1040,8 +1048,8 @@ void CXBMCRenderManager::PrepareNextRender() + ++prev; + while (prev != m_queued.rend()) + { +- if(clocktime > m_Queue[*prev].timestamp /* previous frame is late */ +- && clocktime > m_Queue[*curr].timestamp - frametime) /* selected frame is close to it's display time */ ++ if(clocktime > m_Queue[*prev].timestamp + correction /* previous frame is late */ ++ && clocktime > m_Queue[*curr].timestamp - frametime + correction) /* selected frame is close to it's display time */ + break; + ++curr; + ++prev; +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index 949c652b..d84ff6c 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -252,6 +252,7 @@ class CXBMCRenderManager + XbmcThreads::ConditionVariable m_presentevent; + CCriticalSection m_presentlock; + CEvent m_flushEvent; ++ double m_clock_framefinish; + + + OVERLAY::CRenderer m_overlays; +-- +1.9.3 + + +From 2b302b36fed7bb6cb223c83bd02f251d009e7c8a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 16 Jun 2013 13:22:58 +0200 +Subject: [PATCH 092/122] X11: another fix for mouse coverage + +--- + xbmc/windowing/WinEventsX11.cpp | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 938ad26..e4ca56d 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -515,14 +515,16 @@ bool CWinEventsX11Imp::MessagePump() + + case EnterNotify: + { +- g_Windowing.NotifyMouseCoverage(true); ++ if (xevent.xcrossing.mode == NotifyNormal) ++ g_Windowing.NotifyMouseCoverage(true); + break; + } + + // lose mouse coverage + case LeaveNotify: + { +- g_Windowing.NotifyMouseCoverage(false); ++ if (xevent.xcrossing.mode == NotifyNormal) ++ g_Windowing.NotifyMouseCoverage(false); + g_Mouse.SetActive(false); + break; + } +-- +1.9.3 + + +From cf74860a080ea48b37db52348dc6a4a473a584e2 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 5 Jul 2013 12:14:00 +0200 +Subject: [PATCH 093/122] X11: set windows class name + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index b3fe5102..df5fe9b 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -982,8 +982,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + { + CreateIconPixmap(); + XWMHints *wm_hints; ++ XClassHint *class_hints; + XTextProperty windowName, iconName; + std::string titleString = "XBMC Media Center"; ++ std::string classString = "xbmc.bin"; + char *title = (char*)titleString.c_str(); + + XStringListToTextProperty(&title, 1, &windowName); +@@ -994,10 +996,15 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + wm_hints->icon_pixmap = m_icon; + wm_hints->flags = StateHint | IconPixmapHint; + ++ class_hints = XAllocClassHint(); ++ class_hints->res_class = (char*)classString.c_str(); ++ class_hints->res_name = (char*)classString.c_str(); ++ + XSync(m_dpy,False); + XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, + NULL, 0, NULL, wm_hints, +- NULL); ++ class_hints); ++ XFree(class_hints); + XFree(wm_hints); + + // register interest in the delete window message +-- +1.9.3 + + +From 6d150a887da1423fb7a0e45f4cbdfce79afbb754 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 25 Jul 2013 17:18:13 +0200 +Subject: [PATCH 094/122] ActiveAE: slightly reduce buffer size + +--- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +index 4bd2c32..4350ac8 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -30,8 +30,8 @@ using namespace ActiveAE; + #include "settings/AdvancedSettings.h" + #include "windowing/WindowingFactory.h" + +-#define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds +-#define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds ++#define MAX_CACHE_LEVEL 0.4 // total cache time of stream in seconds ++#define MAX_WATER_LEVEL 0.2 // buffered time after stream stages in seconds + #define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds + + void CEngineStats::Reset(unsigned int sampleRate) +-- +1.9.3 + + +From da256d1559299f50d7b16dedb7578c88144948d2 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 4 Aug 2013 10:11:16 +0200 +Subject: [PATCH 095/122] Revert "vdpau: comment some features that will be + added later" + +This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf. +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 3f87a7d..f7418e8 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1097,8 +1097,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + m_bufferStats.IncDecoded(); + m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); + +- //TODO +- // m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); ++ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); + } + + int retval = 0; +@@ -2294,8 +2293,7 @@ void CMixer::InitCycle() + int flags; + uint64_t latency; + m_config.stats->GetParams(latency, flags); +- // TODO +- if (0) //flags & DVP_FLAG_NO_POSTPROC) ++ if (flags & DVP_FLAG_NO_POSTPROC) + SetPostProcFeatures(false); + else + SetPostProcFeatures(true); +@@ -2307,8 +2305,7 @@ void CMixer::InitCycle() + bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; + m_SeenInterlaceFlag |= interlaced; + +- // TODO +- if (//!(flags & DVP_FLAG_NO_POSTPROC) && ++ if (!(flags & DVP_FLAG_NO_POSTPROC) && + (mode == VS_DEINTERLACEMODE_FORCE || + (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) + { +@@ -2330,8 +2327,7 @@ void CMixer::InitCycle() + m_config.stats->SetCanSkipDeint(true); + } + +- // TODO +- if (0) //m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) ++ if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) + { + m_mixersteps = 1; + } +-- +1.9.3 + + +From 2121f49a6ac009856db0204dc94041297fe47138 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 9 Aug 2013 18:01:40 +0200 +Subject: [PATCH 096/122] X11: fix keysyms + +--- + xbmc/windowing/WinEventsX11.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index e4ca56d..b20130c 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -461,7 +461,7 @@ bool CWinEventsX11Imp::MessagePump() + if (keys.length() > 0) + { + newEvent.key.keysym.scancode = xevent.xkey.keycode; +- xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL); + newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); + newEvent.key.keysym.unicode = keys[keys.length() - 1]; + newEvent.key.state = xevent.xkey.state; +-- +1.9.3 + + +From 4f6915e4d5601887f613380da9cad562bcaff04f Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 9 Aug 2013 18:42:36 +0200 +Subject: [PATCH 097/122] X11: fix keysym for non-IM + +--- + xbmc/windowing/WinEventsX11.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index b20130c..a38890c 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -408,7 +408,7 @@ bool CWinEventsX11Imp::MessagePump() + { + static XComposeStatus state; + char keybuf[32]; +- xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL); + newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); + newEvent.key.keysym.scancode = xevent.xkey.keycode; + newEvent.key.state = xevent.xkey.state; +-- +1.9.3 + + +From e4f76b3484301843354e352760e4fa90c87e66bf Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 10 Aug 2013 11:18:16 +0200 +Subject: [PATCH 098/122] add some missing multi media keys + +--- + system/keymaps/keyboard.xml | 3 +++ + xbmc/input/XBMC_keytable.cpp | 4 ++++ + xbmc/input/XBMC_vkeys.h | 1 + + 3 files changed, 8 insertions(+) + +diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml +index 45682a2..01f7904 100644 +--- a/system/keymaps/keyboard.xml ++++ b/system/keymaps/keyboard.xml +@@ -119,6 +119,9 @@ + SkipPrevious + Stop + Pause ++ FastForward ++ Rewind ++ + + XBMC.ActivateWindow(MyMusic) + ActivateWindow(MyPrograms) +diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp +index 53b9dce..834cccb 100644 +--- a/xbmc/input/XBMC_keytable.cpp ++++ b/xbmc/input/XBMC_keytable.cpp +@@ -184,6 +184,10 @@ static const XBMCKEYTABLE XBMCKeyTable[] = + , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } + , { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } + , { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } ++, { XBMCK_REWIND, 0, 0, XBMCVK_MEDIA_REWIND, "rewind" } ++, { XBMCK_FASTFORWARD, 0, 0, XBMCVK_MEDIA_FASTFORWARD, "fastforward" } ++, { XBMCK_RECORD, 0, 0, XBMCVK_MEDIA_RECORD, "record" } ++ + + // Function keys + , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} +diff --git a/xbmc/input/XBMC_vkeys.h b/xbmc/input/XBMC_vkeys.h +index 00437db..981c62a 100644 +--- a/xbmc/input/XBMC_vkeys.h ++++ b/xbmc/input/XBMC_vkeys.h +@@ -190,6 +190,7 @@ typedef enum { + XBMCVK_LAUNCH_MEDIA_CENTER = 0xC3, + XBMCVK_MEDIA_REWIND = 0xC4, + XBMCVK_MEDIA_FASTFORWARD = 0xC5, ++ XBMCVK_MEDIA_RECORD = 0xC6, + + XBMCVK_LCONTROL = 0xD0, + XBMCVK_RCONTROL = 0xD1, +-- +1.9.3 + + +From 604e7e95d72b1e46d9cb0b2b11d32cb7bd11282a Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 10 Aug 2013 15:53:45 +0200 +Subject: [PATCH 099/122] X11: squash multi + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index df5fe9b..d8e04d6 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -437,7 +437,7 @@ void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) + + bool CWinSystemX11::IsCurrentOutput(CStdString output) + { +- return m_currentOutput.Equals(output); ++ return output.Equals("Default") || m_currentOutput.Equals(output); + } + + bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) +-- +1.9.3 + + +From bedf72410eed807d8eca3349f323f69332ca2aa0 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 3 Sep 2013 20:46:17 +0200 +Subject: [PATCH 100/122] X11: do not poll default monitor + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index d8e04d6..01f5272 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -722,7 +722,7 @@ void CWinSystemX11::NotifyXRREvent(bool poll) + if (poll) + { + CStdString output = CSettings::Get().GetString("videoscreen.monitor"); +- if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default")) ++ if (output.Equals(m_currentOutput) || output.Equals("Default")) + return; + + int numScreens = XScreenCount(m_dpy); +-- +1.9.3 + + +From 83ef9f474994ae77252fb3072d143b14ea39735b Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 29 Oct 2013 20:57:28 +0100 +Subject: [PATCH 101/122] X11: fix broken monitor switching + +--- + system/settings/settings.xml | 1 - + xbmc/settings/DisplaySettings.cpp | 40 ++++++++++++++++++++++++++------------- + 2 files changed, 27 insertions(+), 14 deletions(-) + +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index 798be52..890bb10 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2304,7 +2304,6 @@ + -1 + + +- + + + +diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp +index efb6cb1..da5873f 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -219,8 +219,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + + const std::string &settingId = setting->GetId(); + if (settingId == "videoscreen.resolution" || +- settingId == "videoscreen.screen" || +- settingId == "videoscreen.monitor") ++ settingId == "videoscreen.screen") + { + RESOLUTION newRes = RES_DESKTOP; + if (settingId == "videoscreen.resolution") +@@ -236,11 +235,6 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + // get desktop resolution for screen + newRes = GetResolutionForScreen(); + } +- else if (settingId == "videoscreen.monitor") +- { +- g_Windowing.UpdateResolutions(); +- newRes = GetResolutionForScreen(); +- } + + string screenmode = GetStringFromResolution(newRes); + CSettings::Get().SetString("videoscreen.screenmode", screenmode); +@@ -251,11 +245,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue()); + + SetCurrentResolution(newRes, false); +- bool outputChanged = false; +-#if defined(HAS_GLX) +- outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor")); +-#endif +- g_graphicsContext.SetVideoResolution(newRes, outputChanged); ++ g_graphicsContext.SetVideoResolution(newRes); + + // check if the old or the new resolution was/is windowed + // in which case we don't show any prompt to the user +@@ -274,6 +264,28 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) + m_resolutionChangeAborted = false; + } + } ++ else if (settingId == "videoscreen.monitor") ++ { ++ g_Windowing.UpdateResolutions(); ++ RESOLUTION newRes = GetResolutionForScreen(); ++ ++ SetCurrentResolution(newRes, false); ++ g_graphicsContext.SetVideoResolution(newRes, true); ++ ++ if (!m_resolutionChangeAborted) ++ { ++ bool cancelled = false; ++ if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000)) ++ { ++ m_resolutionChangeAborted = true; ++ return false; ++ } ++ } ++ else ++ m_resolutionChangeAborted = false; ++ ++ return true; ++ } + else if (settingId == "videoscreen.monitorsingle") + { + g_Windowing.UpdateResolutions(); +@@ -708,9 +720,11 @@ void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std + #if defined(HAS_GLX) + std::vector monitors; + g_Windowing.GetConnectedOutputs(&monitors); ++ std::string currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); + for (unsigned int i=0; i +Date: Tue, 29 Oct 2013 20:57:59 +0100 +Subject: [PATCH 102/122] X11: remove polling for connected outputs, use xrr + events + +--- + xbmc/windowing/WinEventsX11.cpp | 44 +++++++++++---------- + xbmc/windowing/WinEventsX11.h | 1 - + xbmc/windowing/X11/WinSystemX11.cpp | 76 ++++++++++++++----------------------- + xbmc/windowing/X11/WinSystemX11.h | 8 ++-- + 4 files changed, 58 insertions(+), 71 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index a38890c..fe91a2b 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + WinEvents->m_structureChanged = false; + WinEvents->m_xrrEventPending = false; +- WinEvents->m_xrrPollTimer.Set(3000); + + // open input method + char *old_locale = NULL, *old_modifiers = NULL; +@@ -280,7 +279,11 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) + #if defined(HAS_XRANDR) + int iReturn; + XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); +- XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); ++ int numScreens = XScreenCount(WinEvents->m_display); ++ for (int i = 0; i < numScreens; i++) ++ { ++ XRRSelectInput(WinEvents->m_display, RootWindow(WinEvents->m_display, i), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask); ++ } + #endif + + return true; +@@ -328,6 +331,26 @@ bool CWinEventsX11Imp::MessagePump() + memset(&xevent, 0, sizeof (XEvent)); + XNextEvent(WinEvents->m_display, &xevent); + ++#if defined(HAS_XRANDR) ++ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) ++ { ++ XRRUpdateConfiguration(&xevent); ++ if (xevent.xgeneric.serial != serial) ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ serial = xevent.xgeneric.serial; ++ continue; ++ } ++ else if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRNotify)) ++ { ++ if (xevent.xgeneric.serial != serial) ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ serial = xevent.xgeneric.serial; ++ continue; ++ } ++#endif ++ + if (XFilterEvent(&xevent, WinEvents->m_window)) + continue; + +@@ -575,18 +598,6 @@ bool CWinEventsX11Imp::MessagePump() + break; + } + }// switch event.type +- +-#if defined(HAS_XRANDR) +- if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) +- { +- XRRUpdateConfiguration(&xevent); +- if (xevent.xgeneric.serial != serial) +- g_Windowing.NotifyXRREvent(); +- WinEvents->m_xrrEventPending = false; +- serial = xevent.xgeneric.serial; +- } +-#endif +- + }// while + + #if defined(HAS_XRANDR) +@@ -596,11 +607,6 @@ bool CWinEventsX11Imp::MessagePump() + g_Windowing.NotifyXRREvent(); + WinEvents->m_xrrEventPending = false; + } +- else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast()) +- { +- g_Windowing.NotifyXRREvent(true); +- WinEvents->m_xrrPollTimer.Set(3000); +- } + #endif + + #ifdef HAS_SDL_JOYSTICK +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index 91a604f..6429291 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -62,6 +62,5 @@ class CWinEventsX11Imp + bool m_structureChanged; + int m_RREventBase; + XbmcThreads::EndTime m_xrrFailSafeTimer; +- XbmcThreads::EndTime m_xrrPollTimer; + bool m_xrrEventPending; + }; +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 01f5272..442efa6 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -168,8 +168,21 @@ bool CWinSystemX11::DestroyWindow() + + bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) + { ++ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); ++ if (m_userOutput.compare("Default") == 0) ++ { ++ std::vector outputs = g_xrandr.GetModes(); ++ if (outputs.size() > 0) ++ { ++ m_userOutput = outputs[0].name; ++ } ++ } ++ ++ m_userOutput = g_xrandr.GetModes()[0].name; ++ + if(m_nWidth == newWidth +- && m_nHeight == newHeight) ++ && m_nHeight == newHeight ++ && m_userOutput.compare(m_currentOutput) == 0) + return true; + + if (!SetWindow(newWidth, newHeight, false, m_userOutput)) +@@ -255,33 +268,23 @@ void CWinSystemX11::UpdateResolutions() + + bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle"); + m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); +- if (m_userOutput.Equals("Default")) ++ if (m_userOutput.compare("Default") == 0) + switchOnOff = false; + + if(g_xrandr.Query(true, !switchOnOff)) + { +- // check if the monitor is connected +- // might take a while when connected to a receiver +- XbmcThreads::EndTime timeout(3000); + XOutput *out = NULL; +- while (!m_userOutput.Equals("Default") && !timeout.IsTimePast()) ++ if (m_userOutput.compare("Default") != 0) + { + out = g_xrandr.GetOutput(m_userOutput); + if (out) + { + XMode mode = g_xrandr.GetCurrentMode(m_userOutput); +- if (mode.isCurrent || switchOnOff) +- break; +- else ++ if (!mode.isCurrent && !switchOnOff) + { + out = NULL; +- break; + } + } +- +- Sleep(500); +- if (!g_xrandr.Query(true, !switchOnOff)) +- break; + } + if (!out) + { +@@ -289,17 +292,16 @@ void CWinSystemX11::UpdateResolutions() + out = g_xrandr.GetOutput(m_userOutput); + } + +- // switch on output +- if(switchOnOff) +- g_xrandr.TurnOnOutput(m_userOutput); +- +- // switch off other outputs if desired + if (switchOnOff) + { ++ // switch on output ++ g_xrandr.TurnOnOutput(m_userOutput); ++ ++ // switch off other outputs + std::vector outputs = g_xrandr.GetModes(); + for (int i=0; i *outputs) + + bool CWinSystemX11::IsCurrentOutput(CStdString output) + { +- return output.Equals("Default") || m_currentOutput.Equals(output); ++ return (output.Equals("Default")) || (m_currentOutput.compare(output) == 0); + } + + bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) +@@ -715,34 +717,14 @@ void CWinSystemX11::CheckDisplayEvents() + #endif + } + +-void CWinSystemX11::NotifyXRREvent(bool poll) ++void CWinSystemX11::NotifyXRREvent() + { +- // we may not get an event if desired monitor becomes available +- // hence we need to poll +- if (poll) +- { +- CStdString output = CSettings::Get().GetString("videoscreen.monitor"); +- if (output.Equals(m_currentOutput) || output.Equals("Default")) +- return; +- +- int numScreens = XScreenCount(m_dpy); +- g_xrandr.SetNumScreens(numScreens); +- g_xrandr.Query(true); +- if (!g_xrandr.IsOutputConnected(output)) +- return; +- +- // if output is turned off by user, respect it +- XMode mode = g_xrandr.GetCurrentMode(output); +- if (!mode.isCurrent) +- return; +- } +- +- CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll); ++ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); + m_windowDirty = true; + + CSingleLock lock(g_graphicsContext); + +- if (!g_xrandr.Query(!poll)) ++ if (!g_xrandr.Query(true)) + { + CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); + return; +@@ -839,14 +821,14 @@ bool CWinSystemX11::EnableFrameLimiter() + return m_minimized; + } + +-bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) ++bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output) + { + bool changeWindow = false; + bool changeSize = false; + bool mouseActive = false; + float mouseX, mouseY; + +- if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) ++ if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty)) + { + mouseActive = g_Mouse.IsActive(); + if (mouseActive) +@@ -1035,7 +1017,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + m_bIsGrabbed = false; + + CDirtyRegionList dr; +- RefreshGlxContext(!m_currentOutput.Equals(output)); ++ RefreshGlxContext(m_currentOutput.compare(output) != 0); + XSync(m_dpy, FALSE); + g_graphicsContext.Clear(0); + g_graphicsContext.Flip(dr); +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 7ec5be4..14622cb 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -70,7 +70,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + Display* GetDisplay() { return m_dpy; } + GLXWindow GetWindow() { return m_glWindow; } + GLXContext GetGlxContext() { return m_glContext; } +- void NotifyXRREvent(bool poll = false); ++ void NotifyXRREvent(); + void GetConnectedOutputs(std::vector *outputs); + bool IsCurrentOutput(CStdString output); + void NotifyMouseCoverage(bool covered); +@@ -79,7 +79,7 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + bool RefreshGlxContext(bool force); + void CheckDisplayEvents(); + void OnLostDevice(); +- bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); ++ bool SetWindow(int width, int height, bool fullscreen, const std::string &output); + + Window m_glWindow, m_mainWindow; + GLXContext m_glContext; +@@ -95,8 +95,8 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + CCriticalSection m_resourceSection; + std::vector m_resources; + uint64_t m_dpyLostTime; +- CStdString m_currentOutput; +- CStdString m_userOutput; ++ std::string m_currentOutput; ++ std::string m_userOutput; + bool m_windowDirty; + bool m_bIsInternalXrr; + bool m_newGlContext; +-- +1.9.3 + + +From c461e4c108911240baa73ddc2a57d230c54eb8fc Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 09:37:13 +0100 +Subject: [PATCH 103/122] X11: remove grabbing of keyboard and mouse + +--- + xbmc/windowing/WinEventsX11.cpp | 4 ---- + xbmc/windowing/X11/WinSystemX11.cpp | 40 ------------------------------------- + xbmc/windowing/X11/WinSystemX11.h | 2 -- + 3 files changed, 46 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index fe91a2b..550c84d 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -538,16 +538,12 @@ bool CWinEventsX11Imp::MessagePump() + + case EnterNotify: + { +- if (xevent.xcrossing.mode == NotifyNormal) +- g_Windowing.NotifyMouseCoverage(true); + break; + } + + // lose mouse coverage + case LeaveNotify: + { +- if (xevent.xcrossing.mode == NotifyNormal) +- g_Windowing.NotifyMouseCoverage(false); + g_Mouse.SetActive(false); + break; + } +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 442efa6..695b352 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -153,8 +153,6 @@ bool CWinSystemX11::DestroyWindow() + + XUnmapWindow(m_dpy, m_mainWindow); + XSync(m_dpy,TRUE); +- XUngrabKeyboard(m_dpy, CurrentTime); +- XUngrabPointer(m_dpy, CurrentTime); + XDestroyWindow(m_dpy, m_glWindow); + XDestroyWindow(m_dpy, m_mainWindow); + m_glWindow = 0; +@@ -628,30 +626,6 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining) + m_bIgnoreNextFocusMessage = false; + } + +-void CWinSystemX11::NotifyMouseCoverage(bool covered) +-{ +- if (!m_bFullScreen || !m_mainWindow) +- return; +- +- if (covered && !m_bIsGrabbed) +- { +- int result = -1; +- while (result != GrabSuccess && result != AlreadyGrabbed) +- { +- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); +- XbmcThreads::ThreadSleep(100); +- } +- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); +- m_bIsGrabbed = true; +- } +- else if (!covered && m_bIsGrabbed) +- { +- XUngrabKeyboard(m_dpy, CurrentTime); +- XUngrabPointer(m_dpy, CurrentTime); +- m_bIsGrabbed = false; +- } +-} +- + bool CWinSystemX11::Minimize() + { + m_bWasFullScreenBeforeMinimize = m_bFullScreen; +@@ -1002,20 +976,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: + XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); + } + +- if (fullscreen) +- { +- int result = -1; +- while (result != GrabSuccess && result != AlreadyGrabbed) +- { +- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); +- XbmcThreads::ThreadSleep(100); +- } +- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); +- m_bIsGrabbed = true; +- } +- else +- m_bIsGrabbed = false; +- + CDirtyRegionList dr; + RefreshGlxContext(m_currentOutput.compare(output) != 0); + XSync(m_dpy, FALSE); +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index 14622cb..d1c8729 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -73,7 +73,6 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + void NotifyXRREvent(); + void GetConnectedOutputs(std::vector *outputs); + bool IsCurrentOutput(CStdString output); +- void NotifyMouseCoverage(bool covered); + + protected: + bool RefreshGlxContext(bool force); +@@ -90,7 +89,6 @@ class CWinSystemX11 : public CWinSystemBase, public ISettingCallback + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; + bool m_bIgnoreNextFocusMessage; +- bool m_bIsGrabbed; + int m_RREventBase; + CCriticalSection m_resourceSection; + std::vector m_resources; +-- +1.9.3 + + +From 51caedf9b9787a9fbab147bd27808397153fe1c4 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 10:46:40 +0100 +Subject: [PATCH 104/122] X11: set ExposureMask on gl window, fixes not updated + areas + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 695b352..e55583c 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -884,8 +884,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: + + swa.override_redirect = False; + swa.border_pixel = 0; +- swa.event_mask = 0; +- mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap; ++ swa.event_mask = ExposureMask; ++ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask; + + m_glWindow = XCreateWindow(m_dpy, m_mainWindow, + 0, 0, width, height, 0, vi->depth, +-- +1.9.3 + + +From d18232e9cc6457f7b5bdc8ebb8d1b7fc12b1770d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 11:25:19 +0100 +Subject: [PATCH 105/122] X11: drop shortcuts, have WM do this + +--- + xbmc/windowing/WinEventsX11.cpp | 21 --------------------- + xbmc/windowing/WinEventsX11.h | 1 - + 2 files changed, 22 deletions(-) + +diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp +index 550c84d..a5b4ba2 100644 +--- a/xbmc/windowing/WinEventsX11.cpp ++++ b/xbmc/windowing/WinEventsX11.cpp +@@ -678,10 +678,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) + break; + } + event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; +- +- bool ret = ProcessShortcuts(event); +- if (ret) +- return ret; + } + else if (event.type == XBMC_KEYUP) + { +@@ -723,23 +719,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) + return g_application.OnEvent(event); + } + +-bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) +-{ +- if (event.key.keysym.mod & XBMCKMOD_ALT) +- { +- switch(event.key.keysym.sym) +- { +- case XBMCK_TAB: // ALT+TAB to minimize/hide +- g_application.Minimize(); +- return true; +- +- default: +- return false; +- } +- } +- return false; +-} +- + XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) + { + // try direct mapping first +diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h +index 6429291..4334d21 100644 +--- a/xbmc/windowing/WinEventsX11.h ++++ b/xbmc/windowing/WinEventsX11.h +@@ -48,7 +48,6 @@ class CWinEventsX11Imp + protected: + static XBMCKey LookupXbmcKeySym(KeySym keysym); + static bool ProcessKey(XBMC_Event &event); +- static bool ProcessShortcuts(XBMC_Event& event); + static CWinEventsX11Imp *WinEvents; + Display *m_display; + Window m_window; +-- +1.9.3 + + +From 7c8ebe2ac23e44982f420b81d98b9992dc6c1292 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 7 Nov 2013 15:02:00 +0100 +Subject: [PATCH 106/122] X11: adapt to new settings + +--- + system/settings/settings.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index 890bb10..124a14d 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2264,6 +2264,7 @@ + HAS_GLX + 0 + false ++ + + + 0 +-- +1.9.3 + + +From ceab7d9f09a46e30e6659b74cf3ad6222c34e334 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 14 Nov 2013 09:28:24 +0100 +Subject: [PATCH 107/122] X11: adapt to changes in cstdstring + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 4 ++-- + xbmc/windowing/X11/XRandR.cpp | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index e55583c..9962f08 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -369,8 +369,8 @@ void CWinSystemX11::UpdateResolutions() + + CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio); + +- res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); +- res.strOutput = out.name; ++ res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); ++ res.strOutput = out->name; + res.strId = mode.id; + res.iSubtitles = (int)(0.965*mode.h); + res.fRefreshRate = mode.hz; +diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp +index 8525ede..c94f2e3 100644 +--- a/xbmc/windowing/X11/XRandR.cpp ++++ b/xbmc/windowing/X11/XRandR.cpp +@@ -74,7 +74,7 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) + CStdString cmd; + cmd = getenv("XBMC_BIN_HOME"); + cmd += "/xbmc-xrandr"; +- cmd.AppendFormat(" -q --screen %d", screennum); ++ cmd = StringUtils::Format("%s -q --screen %d", cmd.c_str(), screennum); + + FILE* file = popen(cmd.c_str(),"r"); + if (!file) +@@ -156,7 +156,7 @@ bool CXRandR::TurnOffOutput(CStdString name) + CStdString cmd; + cmd = getenv("XBMC_BIN_HOME"); + cmd += "/xbmc-xrandr"; +- cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str()); ++ cmd = StringUtils::Format("%s --screen %d --output %s --off", cmd.c_str(), output->screen, name.c_str()); + + int status = system(cmd.c_str()); + if (status == -1) +-- +1.9.3 + + +From 65c0c8b1a9ea4bc1def18c62742f76c6ea1c84bc Mon Sep 17 00:00:00 2001 +From: Marcel Groothuis +Date: Thu, 5 Dec 2013 22:02:50 +0100 +Subject: [PATCH 108/122] ffmpeg demuxer: faster channel change for PVR addons + without internal demuxing (such as MediaPortal, ArgusTV, MythTV, NextPVR) + Credits: FernetMenta, Davilla, Popcornmix, Whaupt + +--- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 143 ++++++++++++++++++--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 5 +- + .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 13 +- + 3 files changed, 139 insertions(+), 22 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 3a4b3f7..a1f1de4 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -52,6 +52,8 @@ + #include "URL.h" + #include "cores/FFmpeg.h" + ++#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) ++ + void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) + { + if(!m_stream) return; +@@ -153,6 +155,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() + m_program = UINT_MAX; + m_pkt.result = -1; + memset(&m_pkt.pkt, 0, sizeof(AVPacket)); ++ m_streaminfo = true; /* set to true if we want to look for streams before playback */ + } + + CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() +@@ -173,10 +176,11 @@ bool CDVDDemuxFFmpeg::Aborted() + return false; + } + +-bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) ++bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) + { + AVInputFormat* iformat = NULL; + std::string strFile; ++ m_streaminfo = streaminfo; + m_iCurrentPts = DVD_NOPTS_VALUE; + m_speed = DVD_PLAYSPEED_NORMAL; + m_program = UINT_MAX; +@@ -187,8 +191,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + m_pInput = pInput; + strFile = m_pInput->GetFileName(); + +- bool streaminfo = true; /* set to true if we want to look for streams before playback*/ +- + if( m_pInput->GetContent().length() > 0 ) + { + std::string content = m_pInput->GetContent(); +@@ -378,13 +380,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" + m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; + +- if (streaminfo) ++ if (m_streaminfo) + { +- /* too speed up dvd switches, only analyse very short */ ++ /* to speed up dvd switches, only analyse very short */ + if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) + m_pFormatContext->max_analyze_duration = 500000; + +- + CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__); + int iErr = avformat_find_stream_info(m_pFormatContext, NULL); + if (iErr < 0) +@@ -404,6 +405,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + } + CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); + } ++ else ++ m_program = 0; ++ + // reset any timeout + m_timeout.SetInfinite(); + +@@ -457,7 +461,7 @@ void CDVDDemuxFFmpeg::Reset() + { + CDVDInputStream* pInputStream = m_pInput; + Dispose(); +- Open(pInputStream); ++ Open(pInputStream, m_streaminfo); + } + + void CDVDDemuxFFmpeg::Flush() +@@ -652,25 +656,32 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() + } + else + { ++ ParsePacket(&m_pkt.pkt); ++ + AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index]; + +- if (m_program != UINT_MAX) ++ if (IsVideoReady()) + { +- /* check so packet belongs to selected program */ +- for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) ++ if (m_program != UINT_MAX) + { +- if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) ++ /* check so packet belongs to selected program */ ++ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) + { +- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); +- break; ++ if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) ++ { ++ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); ++ break; ++ } + } +- } + +- if (!pPacket) +- bReturnEmpty = true; ++ if (!pPacket) ++ bReturnEmpty = true; ++ } ++ else ++ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); + } + else +- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); ++ bReturnEmpty = true; + + if (pPacket) + { +@@ -1608,3 +1619,101 @@ bool CDVDDemuxFFmpeg::IsProgramChange() + } + return false; + } ++ ++void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) ++{ ++ AVStream *st = m_pFormatContext->streams[pkt->stream_index]; ++ CDemuxStream *stream = GetStreamInternal(pkt->stream_index); ++ ++ // if the stream is new, tell ffmpeg to parse the stream ++ if (!stream && !st->parser) ++ { ++ st->need_parsing = AVSTREAM_PARSE_FULL; ++ } ++ ++ // split extradata ++ if(st->parser && st->parser->parser->split && !st->codec->extradata) ++ { ++ int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); ++ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) ++ { ++ // Found extradata, fill it in. This will cause ++ // a new stream to be created and used. ++ st->codec->extradata_size = i; ++ st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); ++ if (st->codec->extradata) ++ { ++ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size); ++ memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); ++ memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); ++ } ++ else ++ { ++ st->codec->extradata_size = 0; ++ } ++ } ++ } ++ ++ // for video we need a decoder to get desired information into codec context ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ++ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) ++ { ++ // open a decoder, it will be cleared down by ffmpeg on closing the stream ++ if (!st->codec->codec) ++ { ++ const AVCodec* codec; ++ AVDictionary *thread_opt = NULL; ++ codec = avcodec_find_decoder(st->codec->codec_id); ++ // Force thread count to 1 since the h264 decoder will not extract ++ // SPS and PPS to extradata during multi-threaded decoding ++ av_dict_set(&thread_opt, "threads", "1", 0); ++ avcodec_open2(st->codec, codec, &thread_opt); ++ ++ av_dict_free(&thread_opt); ++ } ++ ++ // We don't need to actually decode here ++ // we just want to transport SPS data into codec context ++ st->codec->skip_idct = AVDISCARD_ALL; ++ st->codec->skip_frame = AVDISCARD_ALL; ++ st->codec->skip_loop_filter = AVDISCARD_ALL; ++ ++ // We are looking for an IDR frame ++ AVFrame picture; ++ memset(&picture, 0, sizeof(AVFrame)); ++ picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE; ++ picture.pkt_pos = -1; ++ picture.key_frame = 1; ++ picture.format = -1; ++ ++ int got_picture = 0; ++ avcodec_decode_video2(st->codec, &picture, &got_picture, pkt); ++ } ++} ++ ++bool CDVDDemuxFFmpeg::IsVideoReady() ++{ ++ AVStream *st; ++ if(m_program != UINT_MAX) ++ { ++ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) ++ { ++ int idx = m_pFormatContext->programs[m_program]->stream_index[i]; ++ st = m_pFormatContext->streams[idx]; ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ++ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) ++ return false; ++ } ++ } ++ else ++ { ++ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) ++ { ++ st = m_pFormatContext->streams[i]; ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ++ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) ++ return false; ++ } ++ } ++ return true; ++} +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index 3b0f615..083182e 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -88,7 +88,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux + CDVDDemuxFFmpeg(); + virtual ~CDVDDemuxFFmpeg(); + +- bool Open(CDVDInputStream* pInput); ++ bool Open(CDVDInputStream* pInput, bool streaminfo = true); + void Dispose(); + void Reset(); + void Flush(); +@@ -127,6 +127,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux + CDemuxStream* GetStreamInternal(int iStreamId); + void CreateStreams(unsigned int program = UINT_MAX); + void DisposeStreams(); ++ void ParsePacket(AVPacket *pkt); ++ bool IsVideoReady(); + + AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); + double ConvertTimestamp(int64_t pts, int den, int num); +@@ -157,5 +159,6 @@ class CDVDDemuxFFmpeg : public CDVDDemux + + bool m_bPtsWrap, m_bPtsWrapChecked; + int64_t m_iStartTime, m_iMaxTime, m_iEndTime; ++ bool m_streaminfo; + }; + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +index ca689d0..f383563 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +@@ -99,26 +99,31 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) + } + #endif + ++ bool streaminfo = true; /* Look for streams before playback */ + if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) + { + CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; + CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); ++ ++ /* Don't parse the streaminfo for live streams to reduce the channel switch time */ ++ bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels"); ++ streaminfo = !liveStream; ++ + if(pOtherStream) + { + /* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */ + if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) + { + auto_ptr demuxer(new CDVDDemuxFFmpeg()); +- if(demuxer->Open(pOtherStream)) ++ if(demuxer->Open(pOtherStream, streaminfo)) + return demuxer.release(); + else + return NULL; + } + } + +- std::string filename = pInputStream->GetFileName(); + /* Use PVR demuxer only for live streams */ +- if (filename.substr(0, 14) == "pvr://channels") ++ if (liveStream) + { + boost::shared_ptr client; + if (g_PVRClients->GetPlayingClient(client) && +@@ -134,7 +139,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) + } + + auto_ptr demuxer(new CDVDDemuxFFmpeg()); +- if(demuxer->Open(pInputStream)) ++ if(demuxer->Open(pInputStream, streaminfo)) + return demuxer.release(); + else + return NULL; +-- +1.9.3 + + +From dc7b1612c9f02556a88e4ecef3eccea88994e5a8 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 14 Nov 2013 20:35:04 +0100 +Subject: [PATCH 109/122] ffmpeg demuxer: make sure we start mpegts video with + an i-frame + +--- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 31 +++++++++++++++++++++- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 + + 2 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index a1f1de4..1eefb27 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -376,6 +376,13 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) + if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) + m_pFormatContext->max_analyze_duration = 500000; + ++ bool short_analyze = false; ++ if (iformat && (strcmp(iformat->name, "mpegts") == 0)) ++ { ++ m_pFormatContext->max_analyze_duration = 500000; ++ short_analyze = true; ++ } ++ + // we need to know if this is matroska or avi later + m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" + m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; +@@ -404,6 +411,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) + } + } + CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); ++ ++ if (short_analyze) ++ { ++ // make sure we start video with an i-frame ++ ResetVideoStreams(); ++ } + } + else + m_program = 0; +@@ -1655,7 +1668,7 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) + } + + // for video we need a decoder to get desired information into codec context +- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata && + (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) + { + // open a decoder, it will be cleared down by ffmpeg on closing the stream +@@ -1717,3 +1730,19 @@ bool CDVDDemuxFFmpeg::IsVideoReady() + } + return true; + } ++ ++void CDVDDemuxFFmpeg::ResetVideoStreams() ++{ ++ AVStream *st; ++ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) ++ { ++ st = m_pFormatContext->streams[i]; ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ++ { ++ if (st->codec->extradata) ++ m_dllAvUtil.av_free(st->codec->extradata); ++ st->codec->extradata = NULL; ++ st->codec->width = 0; ++ } ++ } ++} +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index 083182e..26ee264 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -129,6 +129,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux + void DisposeStreams(); + void ParsePacket(AVPacket *pkt); + bool IsVideoReady(); ++ void ResetVideoStreams(); + + AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); + double ConvertTimestamp(int64_t pts, int den, int num); +-- +1.9.3 + + +From ad4bacddffdeed3bbfe9f4c8d44191ce7fe9c1ab Mon Sep 17 00:00:00 2001 +From: Wolfgang Haupt +Date: Thu, 5 Dec 2013 22:11:57 +0100 +Subject: [PATCH 110/122] DVDFactoryDemuxer: skip streaminfo for udp tcp and + pvr-channels + +--- + .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 14 ++++++--- + xbmc/utils/URIUtils.cpp | 35 ++++++++++++++++++++++ + xbmc/utils/URIUtils.h | 4 +++ + 3 files changed, 49 insertions(+), 4 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +index f383563..d6580fd 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +@@ -105,9 +105,9 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) + CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; + CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); + +- /* Don't parse the streaminfo for live streams to reduce the channel switch time */ +- bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels"); +- streaminfo = !liveStream; ++ /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */ ++ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); ++ streaminfo = !useFastswitch; + + if(pOtherStream) + { +@@ -123,7 +123,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) + } + + /* Use PVR demuxer only for live streams */ +- if (liveStream) ++ if (URIUtils::IsPVRChannel(pInputStream->GetFileName())) + { + boost::shared_ptr client; + if (g_PVRClients->GetPlayingClient(client) && +@@ -138,6 +138,12 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) + } + } + ++ if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) ++ { ++ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); ++ streaminfo = !useFastswitch; ++ } ++ + auto_ptr demuxer(new CDVDDemuxFFmpeg()); + if(demuxer->Open(pInputStream, streaminfo)) + return demuxer.release(); +diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp +index fd2eb5a..22932b7 100644 +--- a/xbmc/utils/URIUtils.cpp ++++ b/xbmc/utils/URIUtils.cpp +@@ -788,6 +788,36 @@ bool URIUtils::IsFTP(const CStdString& strFile) + StringUtils::StartsWithNoCase(strFile2, "ftps:"); + } + ++bool URIUtils::IsUDP(const CStdString& strFile) ++{ ++ CStdString strFile2(strFile); ++ ++ if (IsStack(strFile)) ++ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); ++ ++ return StringUtils::StartsWithNoCase(strFile2, "udp:"); ++} ++ ++bool URIUtils::IsTCP(const CStdString& strFile) ++{ ++ CStdString strFile2(strFile); ++ ++ if (IsStack(strFile)) ++ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); ++ ++ return StringUtils::StartsWithNoCase(strFile2, "tcp:"); ++} ++ ++bool URIUtils::IsPVRChannel(const CStdString& strFile) ++{ ++ CStdString strFile2(strFile); ++ ++ if (IsStack(strFile)) ++ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); ++ ++ return StringUtils::StartsWithNoCase(strFile2, "pvr://channels"); ++} ++ + bool URIUtils::IsDAV(const CStdString& strFile) + { + CStdString strFile2(strFile); +@@ -1284,3 +1314,8 @@ bool URIUtils::UpdateUrlEncoding(std::string &strFilename) + strFilename = newFilename; + return true; + } ++ ++bool URIUtils::IsUsingFastSwitch(const CStdString& strFile) ++{ ++ return IsUDP(strFile) || IsTCP(strFile) || IsPVRChannel(strFile); ++} +diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h +index b94e94c..b45630f 100644 +--- a/xbmc/utils/URIUtils.h ++++ b/xbmc/utils/URIUtils.h +@@ -88,6 +88,8 @@ class URIUtils + static bool IsDOSPath(const CStdString &path); + static bool IsDVD(const CStdString& strFile); + static bool IsFTP(const CStdString& strFile); ++ static bool IsUDP(const CStdString& strFile); ++ static bool IsTCP(const CStdString& strFile); + static bool IsHD(const CStdString& strFileName); + static bool IsHDHomeRun(const CStdString& strFile); + static bool IsSlingbox(const CStdString& strFile); +@@ -127,6 +129,8 @@ class URIUtils + static bool IsAndroidApp(const CStdString& strFile); + static bool IsLibraryFolder(const CStdString& strFile); + static bool IsLibraryContent(const std::string& strFile); ++ static bool IsPVRChannel(const CStdString& strFile); ++ static bool IsUsingFastSwitch(const CStdString& strFile); + + static void AddSlashAtEnd(std::string& strFolder); + static bool HasSlashAtEnd(const std::string& strFile, bool checkURL = false); +-- +1.9.3 + + +From 49b54f3972ef51ddad0bd10e055c7e50e219fe63 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 08:43:29 +0100 +Subject: [PATCH 111/122] squash fast switch + +--- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 23 ++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 1eefb27..c4dad38 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -1707,15 +1707,19 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) + bool CDVDDemuxFFmpeg::IsVideoReady() + { + AVStream *st; ++ bool hasVideo = false; + if(m_program != UINT_MAX) + { + for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) + { + int idx = m_pFormatContext->programs[m_program]->stream_index[i]; + st = m_pFormatContext->streams[idx]; +- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && +- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) +- return false; ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ++ { ++ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) ++ return true; ++ hasVideo = true; ++ } + } + } + else +@@ -1723,12 +1727,15 @@ bool CDVDDemuxFFmpeg::IsVideoReady() + for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) + { + st = m_pFormatContext->streams[i]; +- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && +- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) +- return false; ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ++ { ++ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) ++ return true; ++ hasVideo = true; ++ } + } + } +- return true; ++ return !hasVideo; + } + + void CDVDDemuxFFmpeg::ResetVideoStreams() +@@ -1740,7 +1747,7 @@ void CDVDDemuxFFmpeg::ResetVideoStreams() + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) + { + if (st->codec->extradata) +- m_dllAvUtil.av_free(st->codec->extradata); ++ av_free(st->codec->extradata); + st->codec->extradata = NULL; + st->codec->width = 0; + } +-- +1.9.3 + + +From 47d6c7531a239723e39a390aafc245bd2a09564d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 13 Apr 2014 10:52:26 +0200 +Subject: [PATCH 112/122] squash fast channel + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 13 ++++++++++--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 + + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index c4dad38..61272ee 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -156,6 +156,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() + m_pkt.result = -1; + memset(&m_pkt.pkt, 0, sizeof(AVPacket)); + m_streaminfo = true; /* set to true if we want to look for streams before playback */ ++ m_checkvideo = false; + } + + CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() +@@ -376,11 +377,10 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) + if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) + m_pFormatContext->max_analyze_duration = 500000; + +- bool short_analyze = false; + if (iformat && (strcmp(iformat->name, "mpegts") == 0)) + { + m_pFormatContext->max_analyze_duration = 500000; +- short_analyze = true; ++ m_checkvideo = true; + } + + // we need to know if this is matroska or avi later +@@ -412,14 +412,17 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) + } + CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); + +- if (short_analyze) ++ if (m_checkvideo) + { + // make sure we start video with an i-frame + ResetVideoStreams(); + } + } + else ++ { + m_program = 0; ++ m_checkvideo = true; ++ } + + // reset any timeout + m_timeout.SetInfinite(); +@@ -1708,6 +1711,10 @@ bool CDVDDemuxFFmpeg::IsVideoReady() + { + AVStream *st; + bool hasVideo = false; ++ ++ if(!m_checkvideo) ++ return true; ++ + if(m_program != UINT_MAX) + { + for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +index 26ee264..322a3b8 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +@@ -161,5 +161,6 @@ class CDVDDemuxFFmpeg : public CDVDDemux + bool m_bPtsWrap, m_bPtsWrapChecked; + int64_t m_iStartTime, m_iMaxTime, m_iEndTime; + bool m_streaminfo; ++ bool m_checkvideo; + }; + +-- +1.9.3 + + +From 9e986651dfd5eeb1cdad071456b73a68067e311a Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 22 Dec 2013 14:52:29 +0100 +Subject: [PATCH 113/122] linux: add shared lib for sse4 operations + +--- + Makefile.in | 8 ++- + configure.in | 18 +++++++ + xbmc/DllPaths_generated.h.in | 3 ++ + xbmc/linux/sse4/CopyFrame.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ + xbmc/linux/sse4/DllLibSSE4.h | 43 ++++++++++++++++ + xbmc/linux/sse4/Makefile.in | 20 ++++++++ + 6 files changed, 206 insertions(+), 1 deletion(-) + create mode 100644 xbmc/linux/sse4/CopyFrame.cpp + create mode 100644 xbmc/linux/sse4/DllLibSSE4.h + create mode 100644 xbmc/linux/sse4/Makefile.in + +diff --git a/Makefile.in b/Makefile.in +index 5339447..e9e2a4c 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -311,6 +311,12 @@ CHECK_LIBADD=@WAYLAND_TEST_LIBS@ + endif + endif + ++ifeq (@USE_SSE4@,1) ++LIBSSE4+=sse4 ++sse4 : force ++ $(MAKE) -C xbmc/linux/sse4 ++endif ++ + CHECK_PROGRAMS = xbmc-test + + CLEAN_FILES += $(CHECK_PROGRAMS) $(CHECK_EXTENSIONS) +@@ -438,7 +444,7 @@ endif + + codecs: papcodecs dvdpcodecs dvdpextcodecs + +-libs: libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH) ++libs: $(LIBSSE4) libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH) + + externals: codecs libs visualizations screensavers libaddon pvraddons + +diff --git a/configure.in b/configure.in +index d9e0dab..062add6 100644 +--- a/configure.in ++++ b/configure.in +@@ -827,6 +827,19 @@ elif test "$use_arch" = "arm"; then + fi + fi + ++use_sse4=no ++if test "$ARCH" = "x86_64-linux" || test "$ARCH" = "i486-linux"; then ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="-msse4.1" ++ AC_COMPILE_IFELSE( ++ [AC_LANG_SOURCE([int foo;])], ++ [ use_sse4=yes ++ USE_SSE4=1], ++ [ use_sse=no ++ USE_SSE4=0]) ++ CFLAGS="$SAVE_CFLAGS" ++fi ++ + # Checks for library functions. + AC_FUNC_ALLOCA + AC_FUNC_CHOWN +@@ -2605,6 +2618,10 @@ if test "$use_codec_libstagefright" = "yes"; then + OUTPUT_FILES="$OUTPUT_FILES xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile" + fi + ++if test "$use_sse4" = "yes"; then ++OUTPUT_FILES="$OUTPUT_FILES xbmc/linux/sse4/Makefile" ++fi ++ + OUTPUT_FILES="$OUTPUT_FILES \ + xbmc/interfaces/python/Makefile \ + xbmc/interfaces/python/test/Makefile" +@@ -2686,6 +2703,7 @@ AC_SUBST(USE_PVR_ADDONS) + AC_SUBST(GNUTLS_ALL_LIBS) + AC_SUBST(HOGWEED_ALL_LIBS) + AC_SUBST(VORBISENC_ALL_LIBS) ++AC_SUBST(USE_SSE4) + + # pushd and popd are not available in other shells besides bash, so implement + # our own pushd/popd functions +diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in +index 8e81555..dd6e0ed 100644 +--- a/xbmc/DllPaths_generated.h.in ++++ b/xbmc/DllPaths_generated.h.in +@@ -94,4 +94,7 @@ + /* xkbcommon */ + #define DLL_PATH_XKBCOMMON "@XKBCOMMON_LIBRARY_SONAME@" + ++/* sse4 */ ++#define DLL_PATH_LIBSSE4 "special://xbmcbin/system/libsse4-@ARCH@.so" ++ + #endif +diff --git a/xbmc/linux/sse4/CopyFrame.cpp b/xbmc/linux/sse4/CopyFrame.cpp +new file mode 100644 +index 0000000..6d23d83 +--- /dev/null ++++ b/xbmc/linux/sse4/CopyFrame.cpp +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "smmintrin.h" ++ ++#define CACHED_BUFFER_SIZE 4096 ++typedef unsigned int UINT; ++ ++extern "C" ++{ ++ ++/* ++ * http://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers ++ * COPIES VIDEO FRAMES FROM USWC MEMORY TO WB SYSTEM MEMORY VIA CACHED BUFFER ++ * ASSUMES PITCH IS A MULTIPLE OF 64B CACHE LINE SIZE, WIDTH MAY NOT BE ++ */ ++void copy_frame( void * pSrc, void * pDest, void * pCacheBlock, ++ UINT width, UINT height, UINT pitch ) ++{ ++ __m128i x0, x1, x2, x3; ++ __m128i *pLoad; ++ __m128i *pStore; ++ __m128i *pCache; ++ UINT x, y, yLoad, yStore; ++ UINT rowsPerBlock; ++ UINT width64; ++ UINT extraPitch; ++ ++ ++ rowsPerBlock = CACHED_BUFFER_SIZE / pitch; ++ width64 = (width + 63) & ~0x03f; ++ extraPitch = (pitch - width64) / 16; ++ ++ pLoad = (__m128i *)pSrc; ++ pStore = (__m128i *)pDest; ++ ++ // COPY THROUGH 4KB CACHED BUFFER ++ for( y = 0; y < height; y += rowsPerBlock ) ++ { ++ // ROWS LEFT TO COPY AT END ++ if( y + rowsPerBlock > height ) ++ rowsPerBlock = height - y; ++ ++ pCache = (__m128i *)pCacheBlock; ++ ++ _mm_mfence(); ++ ++ // LOAD ROWS OF PITCH WIDTH INTO CACHED BLOCK ++ for( yLoad = 0; yLoad < rowsPerBlock; yLoad++ ) ++ { ++ // COPY A ROW, CACHE LINE AT A TIME ++ for( x = 0; x < pitch; x +=64 ) ++ { ++ x0 = _mm_stream_load_si128( pLoad +0 ); ++ x1 = _mm_stream_load_si128( pLoad +1 ); ++ x2 = _mm_stream_load_si128( pLoad +2 ); ++ x3 = _mm_stream_load_si128( pLoad +3 ); ++ ++ _mm_store_si128( pCache +0, x0 ); ++ _mm_store_si128( pCache +1, x1 ); ++ _mm_store_si128( pCache +2, x2 ); ++ _mm_store_si128( pCache +3, x3 ); ++ ++ pCache += 4; ++ pLoad += 4; ++ } ++ } ++ ++ _mm_mfence(); ++ ++ pCache = (__m128i *)pCacheBlock; ++ ++ // STORE ROWS OF FRAME WIDTH FROM CACHED BLOCK ++ for( yStore = 0; yStore < rowsPerBlock; yStore++ ) ++ { ++ // copy a row, cache line at a time ++ for( x = 0; x < width64; x +=64 ) ++ { ++ x0 = _mm_load_si128( pCache ); ++ x1 = _mm_load_si128( pCache +1 ); ++ x2 = _mm_load_si128( pCache +2 ); ++ x3 = _mm_load_si128( pCache +3 ); ++ ++ _mm_stream_si128( pStore, x0 ); ++ _mm_stream_si128( pStore +1, x1 ); ++ _mm_stream_si128( pStore +2, x2 ); ++ _mm_stream_si128( pStore +3, x3 ); ++ ++ pCache += 4; ++ pStore += 4; ++ } ++ ++ pCache += extraPitch; ++ pStore += extraPitch; ++ } ++ } ++} ++} +diff --git a/xbmc/linux/sse4/DllLibSSE4.h b/xbmc/linux/sse4/DllLibSSE4.h +new file mode 100644 +index 0000000..01424ac +--- /dev/null ++++ b/xbmc/linux/sse4/DllLibSSE4.h +@@ -0,0 +1,43 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program 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, or (at your option) ++ * any later version. ++ * ++ * This Program 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 XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "DynamicDll.h" ++ ++extern "C" { ++ ++} ++ ++class DllLibSSE4Interface ++{ ++public: ++ virtual ~DllLibSSE4Interface() {} ++ virtual void copy_frame(void * pSrc, void * pDest, void * pCacheBlock, UINT width, UINT height, UINT pitch) = 0; ++}; ++ ++class DllLibSSE4 : public DllDynamic, DllLibSSE4Interface ++{ ++ DECLARE_DLL_WRAPPER(DllLibSSE4, DLL_PATH_LIBSSE4) ++ DEFINE_METHOD6(void, copy_frame, (void *p1, void *p2, void *p3, UINT p4, UINT p5, UINT p6)) ++ ++ BEGIN_METHOD_RESOLVE() ++ RESOLVE_METHOD(copy_frame) ++ END_METHOD_RESOLVE() ++}; +diff --git a/xbmc/linux/sse4/Makefile.in b/xbmc/linux/sse4/Makefile.in +new file mode 100644 +index 0000000..45aa826 +--- /dev/null ++++ b/xbmc/linux/sse4/Makefile.in +@@ -0,0 +1,20 @@ ++ARCH=@ARCH@ ++DEFINES+= ++CXXFLAGS=-fPIC -msse4.1 ++LIBNAME=libsse4 ++OBJS=CopyFrame.o ++ ++LIB_SHARED=@abs_top_srcdir@/system/$(LIBNAME)-$(ARCH).so ++ ++all: $(LIB_SHARED) ++ ++$(LIB_SHARED): $(OBJS) ++ $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS) ++ ++CLEAN_FILES = \ ++ $(LIB_SHARED) \ ++ ++DISTCLEAN_FILES= \ ++ Makefile \ ++ ++include ../../../Makefile.include +-- +1.9.3 + + +From c859a8c637094e6a13c999b161ed6378fac45525 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 19 Dec 2013 15:36:11 +0100 +Subject: [PATCH 114/122] vaapi: option to enable sw filters + +--- + language/English/strings.po | 17 ++- + system/settings/settings.xml | 15 ++ + xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +- + xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 1 + + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 76 +++++++++-- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 3 + + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 152 +++++++++++++++++++++ + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 31 +++++ + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 32 ++--- + 9 files changed, 290 insertions(+), 41 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 9cc2090..88b945e 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -6092,7 +6092,13 @@ msgctxt "#13456" + msgid "Hardware accelerated" + msgstr "" + +-#empty strings from id 13457 to 13499 ++#. Option for video related setting #13454: sw filter ++#: system/settings/settings.xml ++msgctxt "#13457" ++msgid "Use SW Filter for VAAPI" ++msgstr "" ++ ++#empty strings from id 13458 to 13499 + + #: system/settings/settings.xml + msgctxt "#13500" +@@ -15177,7 +15183,14 @@ msgctxt "#36431" + msgid "Defines whether video decoding should be performed in software (requires more CPU) or with hardware acceleration where possible." + msgstr "" + +-#empty strings from id 36432 to 36499 ++#. Description for video related setting #13457: vaapi sw filter ++#: system/settings/settings.xml ++msgctxt "#36432" ++msgid "This option enables the deinterlacing methods available for software decoding. It gives the possiblity to use high quality deinterlacers in combination with VAAPI." ++msgstr "" ++ ++#empty strings from id 36433 to 36499 ++ + #end reservation + + #: system/settings/settings.xml +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index 124a14d..fdf5f41 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -715,6 +715,21 @@ + false + + ++ ++ HAVE_LIBVA ++ ++ ++ ++ true ++ 1 ++ ++ ++ true ++ ++ 3 ++ false ++ ++ + + HasDXVA2 + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index 5e9f666..32ce5bb 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -988,10 +988,10 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO + if (mInt == VS_INTERLACEMETHOD_NONE) + return VS_INTERLACEMETHOD_NONE; + +- if(!m_pRenderer->Supports(mInt)) ++ if(m_pRenderer && !m_pRenderer->Supports(mInt)) + mInt = VS_INTERLACEMETHOD_AUTO; + +- if (mInt == VS_INTERLACEMETHOD_AUTO) ++ if (m_pRenderer && mInt == VS_INTERLACEMETHOD_AUTO) + return m_pRenderer->AutoInterlaceMethod(); + + return mInt; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +index 2958d43..06e0010 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +@@ -464,6 +464,7 @@ static const EFormatMap g_format_map[] = { + , { PIX_FMT_YUV420P16, RENDER_FMT_YUV420P16 } + , { PIX_FMT_UYVY422, RENDER_FMT_UYVY422 } + , { PIX_FMT_YUYV422, RENDER_FMT_YUYV422 } ++, { PIX_FMT_NV12, RENDER_FMT_NV12 } + , { PIX_FMT_VAAPI_VLD, RENDER_FMT_VAAPI } + , { PIX_FMT_DXVA2_VLD, RENDER_FMT_DXVA } + , { PIX_FMT_NONE , RENDER_FMT_NONE } +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 3b384f4..39d8f9a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -38,6 +38,7 @@ + #include "utils/log.h" + #include "boost/shared_ptr.hpp" + #include "threads/Atomics.h" ++#include "settings/MediaSettings.h" + + #ifndef TARGET_POSIX + #define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5))) +@@ -168,6 +169,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() + m_dts = DVD_NOPTS_VALUE; + m_started = false; + m_decoderPts = DVD_NOPTS_VALUE; ++ m_interlace = false; + } + + CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() +@@ -372,7 +374,7 @@ unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags) + { + m_filters_next.clear(); + +- if(m_pHardware) ++ if(m_pHardware && !m_pHardware->UseFilter()) + return 0; + + if(flags & FILTER_ROTATE) +@@ -446,10 +448,10 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + if(section) + lock = shared_ptr(new CSingleLock(*section)); + +- int result; ++ int result = 0; + if(pData) + result = m_pHardware->Check(m_pCodecContext); +- else ++ else if (!m_pHardware->UseFilter()) + result = m_pHardware->Decode(m_pCodecContext, NULL); + + if(result) +@@ -504,19 +506,60 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + || m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3) + m_started = true; + +- if(m_pHardware == NULL) ++ m_interlace = m_pFrame->interlaced_frame; ++ ++ if(m_pHardware == NULL || m_pHardware->UseFilter()) + { ++ if (m_pHardware) ++ { ++ m_pFrame->pkt_dts = pts_dtoi(m_dts); ++ int result = m_pHardware->Decode(m_pCodecContext, m_pFrame); ++ if (result == VC_BUFFER || result == VC_ERROR) ++ return result; ++ m_pHardware->MapFrame(m_pCodecContext, m_pFrame); ++ m_dts = pts_itod(m_pFrame->pkt_dts); ++ m_pFrame->pkt_dts = 0; ++ } ++ + bool need_scale = std::find( m_formats.begin() + , m_formats.end() +- , m_pCodecContext->pix_fmt) == m_formats.end(); ++ , m_pFrame->format) == m_formats.end(); + + bool need_reopen = false; ++ ++ ++ // ask codec to do deinterlacing if possible ++ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; ++ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); ++ ++ unsigned int mFilters = 0; ++ ++ if (mDeintMode != VS_DEINTERLACEMODE_OFF) ++ { ++ if (mDeintMode == VS_DEINTERLACEMODE_FORCE || ++ m_pFrame->interlaced_frame) ++ { ++ if (mInt == VS_INTERLACEMETHOD_DEINTERLACE) ++ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY; ++ else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF) ++ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED; ++ ++ if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters) ++ mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED; ++ } ++ } ++ ++ if (!g_renderManager.Supports(RENDERFEATURE_ROTATION)) ++ mFilters |= CDVDVideoCodec::FILTER_ROTATE; ++ ++ SetFilters(mFilters); ++ + if(!m_filters.Equals(m_filters_next)) + need_reopen = true; + + if(m_pFilterIn) + { +- if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt ++ if(m_pFilterIn->outputs[0]->format != m_pFrame->format + || m_pFilterIn->outputs[0]->w != m_pCodecContext->width + || m_pFilterIn->outputs[0]->h != m_pCodecContext->height) + need_reopen = true; +@@ -533,7 +576,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + } + + int result; +- if(m_pHardware) ++ if(m_pHardware && !m_pHardware->UseFilter()) + result = m_pHardware->Decode(m_pCodecContext, m_pFrame); + else if(m_pFilterGraph) + result = FilterProcess(m_pFrame); +@@ -617,6 +660,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location; + pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries; + pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc; ++ pDvdVideoPicture->color_matrix = m_pCodecContext->colorspace; + if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG + || m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P) + pDvdVideoPicture->color_range = 1; +@@ -640,7 +684,11 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN; + } + +- pDvdVideoPicture->dts = m_dts; ++ if (pDvdVideoPicture->iRepeatPicture) ++ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; ++ else ++ pDvdVideoPicture->dts = m_dts; ++ + m_dts = DVD_NOPTS_VALUE; + if (m_pFrame->reordered_opaque) + pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque); +@@ -671,7 +719,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + + bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) + { +- if(m_pHardware) ++ if(m_pHardware && !m_pHardware->UseFilter()) + return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture); + + if(!GetPictureCommon(pDvdVideoPicture)) +@@ -691,6 +739,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) + pix_fmt = (PixelFormat)m_pFrame->format; + + pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt); ++ + return true; + } + +@@ -704,7 +753,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + if (filters.empty() && !scale) + return 0; + +- if (m_pHardware) ++ if (m_pHardware && !m_pHardware->UseFilter()) + { + CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode"); + return 0; +@@ -722,7 +771,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) + CStdString args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d", + m_pCodecContext->width, + m_pCodecContext->height, +- m_pCodecContext->pix_fmt, ++ m_pFrame->format, + m_pCodecContext->time_base.num, + m_pCodecContext->time_base.den, + m_pCodecContext->sample_aspect_ratio.num, +@@ -849,10 +898,7 @@ bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &in + { + pts = m_decoderPts; + skippedDeint = m_skippedDeint; +- if (m_pFrame) +- interlaced = m_pFrame->interlaced_frame; +- else +- interlaced = 0; ++ interlaced = m_interlace; + return true; + } + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index 95c6489..dd8e620 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -53,6 +53,8 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + virtual bool CanSkipDeint() {return false; } + virtual const std::string Name() = 0; + virtual CCriticalSection* Section() { return NULL; } ++ virtual bool UseFilter() { return false; } ++ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame) { return false; } + }; + + CDVDVideoCodecFFmpeg(); +@@ -129,4 +131,5 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + int m_skippedDeint; + bool m_requestSkipDeint; + int m_codecControlFlags; ++ bool m_interlace; + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index 386d50a..315f3ca 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -26,6 +26,15 @@ + #include + #include "utils/log.h" + #include "threads/SingleLock.h" ++#include "XMemUtils.h" ++#include "utils/CPUInfo.h" ++#include "settings/Settings.h" ++ ++extern "C" { ++#include "libavutil/avutil.h" ++} ++ ++#define CACHED_BUFFER_SIZE 4096 + + #define CHECK(a) \ + do { \ +@@ -168,12 +177,17 @@ CDecoder::CDecoder() + m_context = 0; + m_hwaccel = (vaapi_context*)calloc(1, sizeof(vaapi_context)); + memset(m_surfaces, 0, sizeof(*m_surfaces)); ++ m_frame_buffer = NULL; ++ m_cache = NULL; + } + + CDecoder::~CDecoder() + { + Close(); + free(m_hwaccel); ++ _aligned_free(m_frame_buffer); ++ _aligned_free(m_cache); ++ m_dllSSE4.Unload(); + } + + void CDecoder::RelBuffer(uint8_t *data) +@@ -393,6 +407,11 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + if (!EnsureContext(avctx)) + return false; + ++ if (avctx->width <= 1920 && avctx->height <= 1088) ++ CheckUseFilter(); ++ else ++ m_use_filter = false; ++ + m_hwaccel->display = m_display->get(); + + avctx->hwaccel_context = m_hwaccel; +@@ -475,7 +494,35 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) + return status; + + if(frame) ++ { ++ if (m_use_filter) ++ { ++ VASurfaceID surface = GetSurfaceID(frame); ++ std::list::iterator it; ++ for(it = m_surfaces_used.begin(); it != m_surfaces_used.end(); ++it) ++ { ++ if((*it)->m_id == surface) ++ { ++ m_holder.surface = *it; ++ break; ++ } ++ } ++ if (it == m_surfaces_used.end()) ++ { ++ CLog::Log(LOGERROR, "VAAPI::Decode - surface not found"); ++ return VC_ERROR; ++ } ++ CProcPic pic; ++ memset(&pic.frame, 0, sizeof(AVFrame)); ++ av_frame_ref(&pic.frame, frame); ++ pic.surface = *it; ++ m_surfaces_proc.push_back(pic); ++ if (m_surfaces_proc.size() < m_renderbuffers_count) ++ return VC_BUFFER; ++ } ++ + return VC_BUFFER | VC_PICTURE; ++ } + else + return VC_BUFFER; + } +@@ -553,4 +600,109 @@ unsigned CDecoder::GetAllowedReferences() + return m_renderbuffers_count; + } + ++void CDecoder::Reset() ++{ ++ m_surfaces_proc.clear(); ++} ++ ++void CDecoder::CheckUseFilter() ++{ ++ m_use_filter = true; ++ _aligned_free(m_frame_buffer); ++ _aligned_free(m_cache); ++ if (CSettings::Get().GetBool("videoplayer.usevaapiswfilter")) ++ { ++ if (!(g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE4)) ++ { ++ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter cpu does not support SSE4"); ++ m_use_filter = false; ++ return; ++ } ++ if (!m_dllSSE4.Load()) ++ { ++ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter failed loading sse4 lib"); ++ m_use_filter = false; ++ return; ++ } ++ VAImage image; ++ VASurfaceID surface = m_surfaces_free.front()->m_id; ++ VAStatus status = vaDeriveImage(m_display->get(), surface, &image); ++ m_use_filter = true; ++ if (status != VA_STATUS_SUCCESS) ++ { ++ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter vaDeriveImage not supported"); ++ m_use_filter = false; ++ } ++ if (image.format.fourcc != VA_FOURCC_NV12) ++ { ++ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter image format not NV12"); ++ m_use_filter = false; ++ } ++ if ((image.pitches[0] % 64) || (image.pitches[1] % 64)) ++ { ++ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter patches no multiple of 64"); ++ m_use_filter = false; ++ } ++ if (m_use_filter) ++ { ++ m_frame_buffer = (uint8_t*)_aligned_malloc(image.height*image.width*2 + 256, 64); ++ m_cache = (uint8_t*)_aligned_malloc(CACHED_BUFFER_SIZE, 64); ++ } ++ vaDestroyImage(m_display->get(),image.image_id); ++ } ++ else ++ { ++ m_use_filter = false; ++ } ++} ++ ++bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame) ++{ ++ if (m_surfaces_proc.empty()) ++ { ++ return false; ++ } ++ if(frame) ++ { ++ CProcPic pic = m_surfaces_proc.front(); ++ m_surfaces_proc.pop_front(); ++ VASurfaceID surface = pic.surface->m_id; ++ VASurfaceStatus surf_status; ++ VAImage image; ++ uint8_t *buf; ++ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status)) ++ while (surf_status != VASurfaceReady) ++ { ++ Sleep(1); ++ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status)) ++ } ++ CHECK(vaDeriveImage(m_display->get(), surface, &image)); ++ CHECK(vaMapBuffer(m_display->get(), image.buf, (void**)&buf)) ++ ++ uint8_t *src, *dst; ++ src = buf + image.offsets[0]; ++ dst = m_frame_buffer + image.offsets[0]; ++ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height, image.pitches[0]); ++ src = buf + image.offsets[1]; ++ dst = m_frame_buffer + image.offsets[1]; ++ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]); ++ ++ av_frame_unref(frame); ++ av_frame_move_ref(frame, &pic.frame); ++ ++ frame->format = AV_PIX_FMT_NV12; ++ frame->data[0] = m_frame_buffer + image.offsets[0]; ++ frame->linesize[0] = image.pitches[0]; ++ frame->data[1] = m_frame_buffer + image.offsets[1]; ++ frame->linesize[1] = image.pitches[1]; ++ frame->data[2] = NULL; ++ frame->data[3] = NULL; ++ frame->pkt_size = image.data_size; ++ ++ CHECK(vaUnmapBuffer(m_display->get(), image.buf)) ++ CHECK(vaDestroyImage(m_display->get(),image.image_id)) ++ } ++ return true; ++} ++ + #endif +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +index ec99162..616b124 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +@@ -27,9 +27,11 @@ + #include + #include + #include ++#include "linux/sse4/DllLibSSE4.h" + + extern "C" { + #include "libavcodec/vaapi.h" ++#include "libavcodec/avcodec.h" + } + + namespace VAAPI { +@@ -102,11 +104,31 @@ struct CHolder + {} + }; + ++struct CProcPic ++{ ++ AVFrame frame; ++ CSurfacePtr surface; ++ CProcPic() ++ {} ++ CProcPic(const CProcPic &other) ++ { ++ memcpy(&this->frame, &other.frame, sizeof(AVFrame)); ++ surface = other.surface; ++ } ++ CProcPic & operator= (const CProcPic &other) ++ { ++ memcpy(&this->frame, &other.frame, sizeof(AVFrame)); ++ surface = other.surface; ++ return *this; ++ } ++}; ++ + class CDecoder + : public CDVDVideoCodecFFmpeg::IHardwareDecoder + { + bool EnsureContext(AVCodecContext *avctx); + bool EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count); ++ void CheckUseFilter(); + public: + CDecoder(); + ~CDecoder(); +@@ -115,9 +137,12 @@ class CDecoder + virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); + virtual int Check (AVCodecContext* avctx); + virtual void Close(); ++ virtual void Reset(); + virtual const std::string Name() { return "vaapi"; } + virtual CCriticalSection* Section() { if(m_display) return m_display.get(); else return NULL; } + virtual unsigned GetAllowedReferences(); ++ virtual bool UseFilter() { return m_use_filter; } ++ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame); + + int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); + void RelBuffer(uint8_t *data); +@@ -133,14 +158,20 @@ class CDecoder + int m_refs; + std::list m_surfaces_used; + std::list m_surfaces_free; ++ std::list m_surfaces_proc; + + CDisplayPtr m_display; + VAConfigID m_config; + VAContextID m_context; ++ bool m_use_filter; ++ uint8_t *m_frame_buffer; ++ uint8_t *m_cache; + + vaapi_context *m_hwaccel; + + CHolder m_holder; // silly struct to pass data to renderer ++ ++ DllLibSSE4 m_dllSSE4; + }; + + } +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 9c5469b..b30e450 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -554,28 +554,6 @@ void CDVDPlayerVideo::Process() + // decoder still needs to provide an empty image structure, with correct flags + m_pVideoCodec->SetDropState(bRequestDrop); + +- // ask codec to do deinterlacing if possible +- EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; +- EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); +- +- unsigned int mFilters = 0; +- +- if (mDeintMode != VS_DEINTERLACEMODE_OFF) +- { +- if (mInt == VS_INTERLACEMETHOD_DEINTERLACE) +- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY; +- else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF) +- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED; +- +- if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters) +- mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED; +- } +- +- if (!g_renderManager.Supports(RENDERFEATURE_ROTATION)) +- mFilters |= CDVDVideoCodec::FILTER_ROTATE; +- +- mFilters = m_pVideoCodec->SetFilters(mFilters); +- + int iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts); + + // buffer packets so we can recover should decoder flush for some reason +@@ -662,6 +640,8 @@ void CDVDPlayerVideo::Process() + + //Deinterlace if codec said format was interlaced or if we have selected we want to deinterlace + //this video ++ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; ++ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); + if ((mDeintMode == VS_DEINTERLACEMODE_AUTO && (picture.iFlags & DVP_FLAG_INTERLACED)) || mDeintMode == VS_DEINTERLACEMODE_FORCE) + { + if(mInt == VS_INTERLACEMETHOD_SW_BLEND) +@@ -704,7 +684,15 @@ void CDVDPlayerVideo::Process() + } + + if (picture.iRepeatPicture) ++ { ++ double pts; ++ int skipped, deint; ++ m_pVideoCodec->GetCodecStats(pts, skipped, deint); ++ picture.iDuration = frametime; ++ if (deint && (frametime <= 0.02*DVD_TIME_BASE)) ++ picture.iDuration *= 2; + picture.iDuration *= picture.iRepeatPicture + 1; ++ } + + int iResult = OutputPicture(&picture, pts); + +-- +1.9.3 + + +From 08c078beb01f88ee5e1f29301e3e14d66d9158a3 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 3 Jan 2014 20:50:46 +0100 +Subject: [PATCH 115/122] X11: check for user output on resize window + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 9962f08..c95f4ec 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -167,7 +167,20 @@ bool CWinSystemX11::DestroyWindow() + bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) + { + m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); +- if (m_userOutput.compare("Default") == 0) ++ XOutput *out = NULL; ++ if (m_userOutput.compare("Default") != 0) ++ { ++ out = g_xrandr.GetOutput(m_userOutput); ++ if (out) ++ { ++ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); ++ if (!mode.isCurrent) ++ { ++ out = NULL; ++ } ++ } ++ } ++ if (!out) + { + std::vector outputs = g_xrandr.GetModes(); + if (outputs.size() > 0) +@@ -176,8 +189,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n + } + } + +- m_userOutput = g_xrandr.GetModes()[0].name; +- + if(m_nWidth == newWidth + && m_nHeight == newHeight + && m_userOutput.compare(m_currentOutput) == 0) +-- +1.9.3 + + +From 08289a85bb1d68cbf9ac647ac31a81d37d144b2d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 10:05:26 +0100 +Subject: [PATCH 116/122] xbmc pr 3080 + +--- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 39d8f9a..aa82a03 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -474,6 +474,14 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p + av_init_packet(&avpkt); + avpkt.data = pData; + avpkt.size = iSize; ++#define SET_PKT_TS(ts) \ ++ if(ts != DVD_NOPTS_VALUE)\ ++ avpkt.ts = (ts / DVD_TIME_BASE) * AV_TIME_BASE;\ ++ else\ ++ avpkt.ts = AV_NOPTS_VALUE ++ SET_PKT_TS(pts); ++ SET_PKT_TS(dts); ++#undef SET_PKT_TS + /* We lie, but this flag is only used by pngdec.c. + * Setting it correctly would allow CorePNG decoding. */ + avpkt.flags = AV_PKT_FLAG_KEY; +@@ -690,8 +698,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + pDvdVideoPicture->dts = m_dts; + + m_dts = DVD_NOPTS_VALUE; +- if (m_pFrame->reordered_opaque) +- pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque); ++ ++ int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame); ++ if(bpts != AV_NOPTS_VALUE) ++ pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; + else + pDvdVideoPicture->pts = DVD_NOPTS_VALUE; + +-- +1.9.3 + + +From 43aef197110cc9c2c6175f58da30d145c3f5e24d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 17:24:58 +0100 +Subject: [PATCH 117/122] set preatpicture if pts is equal to last frame + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index aa82a03..9dd1da7 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -701,7 +701,15 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) + + int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame); + if(bpts != AV_NOPTS_VALUE) ++ { + pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; ++ if (pDvdVideoPicture->pts == m_decoderPts) ++ { ++ pDvdVideoPicture->iRepeatPicture = -0.5; ++ pDvdVideoPicture->pts = DVD_NOPTS_VALUE; ++ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; ++ } ++ } + else + pDvdVideoPicture->pts = DVD_NOPTS_VALUE; + +-- +1.9.3 + + +From 273514c5aa9cfe6f329aef4138d70957a102fa6b Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Mon, 27 Jan 2014 19:49:03 +0100 +Subject: [PATCH 118/122] Introduce SWCodec - these are codecs that don't have + any GPU acceleration (yet) - add HVEC + +--- + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 15 +++++++++------ + .../cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- + xbmc/settings/AdvancedSettings.cpp | 4 ++-- + xbmc/settings/AdvancedSettings.h | 2 +- + 4 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 9dd1da7..f2f0cf5 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -163,7 +163,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() + m_iScreenHeight = 0; + m_iOrientation = 0; + m_bSoftware = false; +- m_isHi10p = false; ++ m_isSWCodec = false; + m_pHardware = NULL; + m_iLastKeyframe = 0; + m_dts = DVD_NOPTS_VALUE; +@@ -209,10 +209,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + // this is needed to not open the decoders + m_bSoftware = true; + // this we need to enable multithreading for hi10p via advancedsettings +- m_isHi10p = true; ++ m_isSWCodec = true; + break; + } + } ++ else if (hints.codec == AV_CODEC_ID_HEVC) ++ m_isSWCodec = true; + + if(pCodec == NULL) + pCodec = avcodec_find_decoder(hints.codec); +@@ -238,12 +240,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + * sensitive to changes in frame sizes, and it causes crashes + * during HW accell - so we unset it in this case. + * +- * When we detect Hi10p and user did not disable hi10pmultithreading ++ * When we detect a pure SW codec and user did not disable SWmultithreading + * via advancedsettings.xml we keep the ffmpeg default thread type. + * */ +- if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading) ++ if(m_isSWCodec && !g_advancedSettings.m_videoDisableSWMultithreading) + { +- CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d", ++ CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for swcodec: %d", + m_pCodecContext->thread_type); + } + else if ((EDECODEMETHOD) CSettings::Get().GetInt("videoplayer.decodingmethod") == VS_DECODEMETHOD_SOFTWARE && CSettings::Get().GetBool("videoplayer.useframemtdec")) +@@ -295,7 +297,8 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount()); + if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded + && ( pCodec->id == AV_CODEC_ID_H264 +- || pCodec->id == AV_CODEC_ID_MPEG4 )) ++ || pCodec->id == AV_CODEC_ID_MPEG4 ++ || pCodec->id == AV_CODEC_ID_HEVC)) + m_pCodecContext->thread_count = num_threads; + + if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index dd8e620..6baf42a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -121,7 +121,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + + std::string m_name; + bool m_bSoftware; +- bool m_isHi10p; ++ bool m_isSWCodec; + IHardwareDecoder *m_pHardware; + int m_iLastKeyframe; + double m_dts; +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index 7532914..0d5e546 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -182,7 +182,7 @@ void CAdvancedSettings::Initialize() + m_stagefrightConfig.useInputDTS = false; + + m_videoDefaultLatency = 0.0; +- m_videoDisableHi10pMultithreading = false; ++ m_videoDisableSWMultithreading = false; + + m_musicUseTimeSeeking = true; + m_musicTimeSeekForward = 10; +@@ -599,7 +599,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) + XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f); + XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); + XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); +- XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading); ++ XMLUtils::GetBoolean(pElement,"disableswmultithreading",m_videoDisableSWMultithreading); + XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); + XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); + XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD); +diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h +index c43351d..7075f05 100644 +--- a/xbmc/settings/AdvancedSettings.h ++++ b/xbmc/settings/AdvancedSettings.h +@@ -194,7 +194,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler + bool m_DXVANoDeintProcForProgressive; + int m_videoFpsDetect; + int m_videoBusyDialogDelay_ms; +- bool m_videoDisableHi10pMultithreading; ++ bool m_videoDisableSWMultithreading; + StagefrightConfig m_stagefrightConfig; + + CStdString m_videoDefaultPlayer; +-- +1.9.3 + + +From bbf2866f6ac6d5fdf5177a04cc8ee436bc348d28 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 11 Feb 2014 18:15:06 +0100 +Subject: [PATCH 119/122] ActiveAE: add some debug logging + +--- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +index 0287e73..6904cb9 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +@@ -276,7 +276,13 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size) + } + } + if (!m_inMsgEvent.WaitMSec(200)) ++ { ++ double cachetime = GetCacheTime(); ++ CSingleLock lock(m_streamLock); ++ CLog::Log(LOGWARNING, "CActiveAEStream::AddData - timeout waiting for buffer, paused: %d, cache time: %f, free buffers: %d", ++ m_paused, cachetime, m_streamFreeBuffers); + break; ++ } + } + return copied; + } +-- +1.9.3 + + +From 33c86bfac93c35cdf64a8c4d4b676f207dc0a3b8 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 1 Apr 2014 15:45:16 +0200 +Subject: [PATCH 120/122] X11: remove obsolete sdl include + +--- + xbmc/windowing/X11/WinSystemX11.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h +index d1c8729..5489543 100644 +--- a/xbmc/windowing/X11/WinSystemX11.h ++++ b/xbmc/windowing/X11/WinSystemX11.h +@@ -25,7 +25,6 @@ + + #include "system_gl.h" + #include +-#include + + #include "windowing/WinSystem.h" + #include "utils/Stopwatch.h" +-- +1.9.3 + + +From 397042ce2eddd0116c8106cd6d533fed33296004 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 13 Apr 2014 15:34:26 +0200 +Subject: [PATCH 121/122] X11: do not call xrandr until we have a window + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index c95f4ec..d1e6c1f 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -243,15 +243,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + + // only call xrandr if mode changes +- if (currmode.w != mode.w || currmode.h != mode.h || +- currmode.hz != mode.hz || currmode.id != mode.id) ++ if (m_mainWindow) + { +- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); +- OnLostDevice(); +- m_bIsInternalXrr = true; +- g_xrandr.SetMode(out, mode); +- if (m_mainWindow) ++ if (currmode.w != mode.w || currmode.h != mode.h || ++ currmode.hz != mode.hz || currmode.id != mode.id) ++ { ++ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); ++ OnLostDevice(); ++ m_bIsInternalXrr = true; ++ g_xrandr.SetMode(out, mode); + return true; ++ } + } + } + #endif +-- +1.9.3 + + +From e41281c608aa075fa87e1abf67837ad8d27bab63 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 13 May 2014 08:21:37 +0200 +Subject: [PATCH 122/122] dvdplayer: demuxFFmpeg - use bits_per_coded_sample if + bits_per_raw_sample is zero + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 61272ee..286ac4f 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -1226,6 +1226,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + st->iBlockAlign = pStream->codec->block_align; + st->iBitRate = pStream->codec->bit_rate; + st->iBitsPerSample = pStream->codec->bits_per_raw_sample; ++ if (st->iBitsPerSample == 0) ++ st->iBitsPerSample = pStream->codec->bits_per_coded_sample; + + if(av_dict_get(pStream->metadata, "title", NULL, 0)) + st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; +-- +1.9.3 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch b/packages/mediacenter/xbmc/patches/x86/xbmc-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch rename to packages/mediacenter/xbmc/patches/x86/xbmc-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.03-keymap.patch b/packages/mediacenter/xbmc/patches/x86/xbmc-995.03-keymap.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-995.03-keymap.patch rename to packages/mediacenter/xbmc/patches/x86/xbmc-995.03-keymap.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch deleted file mode 100644 index 99199f8169..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch +++ /dev/null @@ -1,11231 +0,0 @@ -From cd390c16efd020e7b02296bcdac9d700ce088e5c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 01/96] videoplayer: adapt lateness detection and dropping to - buffering - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 16 +- - xbmc/cores/VideoRenderers/RenderManager.h | 12 +- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 15 +- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 31 ++++ - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 + - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 194 +++++++++++++++++---- - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 23 +++ - 7 files changed, 260 insertions(+), 38 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index a33591d..9e2c055 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -284,6 +284,8 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_bIsStarted = true; - m_bReconfigured = true; - m_presentstep = PRESENT_IDLE; -+ m_presentpts = DVD_NOPTS_VALUE; -+ m_sleeptime = 1.0; - m_presentevent.notifyAll(); - - m_firstFlipPage = false; // tempfix -@@ -627,7 +629,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) - m_pRenderer->SetViewMode(iViewMode); - } - --void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) -+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) - { - { CSharedLock lock(m_sharedSection); - -@@ -695,6 +697,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - m.timestamp = timestamp; - m.presentfield = sync; - m.presentmethod = presentmethod; -+ m.pts = pts; - requeue(m_queued, m_free); - - /* signal to any waiters to check state */ -@@ -1063,6 +1066,8 @@ void CXBMCRenderManager::PrepareNextRender() - m_discard.push_back(m_presentsource); - m_presentsource = idx; - m_queued.pop_front(); -+ m_sleeptime = m_Queue[idx].timestamp - clocktime; -+ m_presentpts = m_Queue[idx].pts; - m_presentevent.notifyAll(); - } - } -@@ -1079,3 +1084,12 @@ void CXBMCRenderManager::DiscardBuffer() - m_presentstep = PRESENT_IDLE; - m_presentevent.notifyAll(); - } -+ -+bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel) -+{ -+ CSingleLock lock(m_presentlock); -+ sleeptime = m_sleeptime; -+ pts = m_presentpts; -+ bufferLevel = m_queued.size() + m_discard.size(); -+ return true; -+} -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index c469795..949c652 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -98,10 +98,11 @@ public: - * - * @param bStop reference to stop flag of calling thread - * @param timestamp of frame delivered with AddVideoPicture -+ * @param pts used for lateness detection - * @param source depreciated - * @param sync signals frame, top, or bottom field - */ -- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); -+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); - unsigned int PreInit(); - void UnInit(); - bool Flush(); -@@ -176,6 +177,12 @@ public: - int WaitForBuffer(volatile bool& bStop, int timeout = 100); - - /** -+ * Can be called by player for lateness detection. This is done best by -+ * looking at the end of the queue. -+ */ -+ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); -+ -+ /** - * Video player call this on flush in oder to discard any queued frames - */ - void DiscardBuffer(); -@@ -222,6 +229,7 @@ protected: - - struct SPresent - { -+ double pts; - double timestamp; - EFIELDSYNC presentfield; - EPRESENTMETHOD presentmethod; -@@ -233,6 +241,8 @@ protected: - - ERenderFormat m_format; - -+ double m_sleeptime; -+ double m_presentpts; - double m_presentcorr; - double m_presenterr; - double m_errorbuff[ERRORBUFFSIZE]; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index f6751f4..fb34463 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -132,6 +132,10 @@ struct DVDVideoUserData - #define DVP_FLAG_NOSKIP 0x00000010 // indicate this picture should never be dropped - #define DVP_FLAG_DROPPED 0x00000020 // indicate that this picture has been dropped in decoder stage, will have no data - -+#define DVP_FLAG_DROPDEINT 0x00000040 // indicate that this picture was requested to have been dropped in deint stage -+#define DVP_FLAG_NO_POSTPROC 0x00000100 -+#define DVP_FLAG_DRAIN 0x00000200 -+ - // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2! - - #define DVP_QSCALE_UNKNOWN 0 -@@ -149,6 +153,9 @@ class CDVDCodecOptions; - #define VC_PICTURE 0x00000004 // the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data - #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data - #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again -+#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped -+#define VC_HURRY 0x00000040 -+ - class CDVDVideoCodec - { - public: -@@ -266,7 +273,6 @@ public: - return 0; - } - -- - /** - * Number of references to old pictures that are allowed to - * be retained when calling decode on the next demux packet -@@ -283,4 +289,11 @@ public: - * Interact with user settings so that user disabled codecs are disabled - */ - static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id); -+ -+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) -+ { -+ return false; -+ } -+ -+ virtual void SetCodecControl(int flags) {} - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 9b6a34d..413151d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -164,6 +164,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() - m_iLastKeyframe = 0; - m_dts = DVD_NOPTS_VALUE; - m_started = false; -+ m_decoderPts = DVD_NOPTS_VALUE; - } - - CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() -@@ -355,6 +356,14 @@ void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop) - { - if( m_pCodecContext ) - { -+ if (bDrop && m_pHardware && m_pHardware->CanSkipDeint()) -+ { -+ m_requestSkipDeint = true; -+ bDrop = false; -+ } -+ else -+ m_requestSkipDeint = false; -+ - // i don't know exactly how high this should be set - // couldn't find any good docs on it. think it varies - // from codec to codec on what it does -@@ -556,6 +565,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - void CDVDVideoCodecFFmpeg::Reset() - { - m_started = false; -+ m_decoderPts = DVD_NOPTS_VALUE; - m_iLastKeyframe = m_pCodecContext->has_b_frames; - m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); - -@@ -665,6 +675,22 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - else - pDvdVideoPicture->pts = DVD_NOPTS_VALUE; - -+ if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE) -+ m_decoderPts = pDvdVideoPicture->pts; -+ else -+ m_decoderPts = m_dts; -+ -+ if (m_requestSkipDeint) -+ { -+ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPDEINT; -+ m_skippedDeint = 1; -+ } -+ else -+ m_skippedDeint = 0; -+ -+ m_requestSkipDeint = false; -+ pDvdVideoPicture->iFlags |= m_codecControlFlags; -+ - if(!m_started) - pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; - -@@ -924,3 +950,8 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences() - else - return 0; - } -+ -+void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) -+{ -+ m_codecControlFlags = flags; -+} -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 2287031..8376f72 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -45,6 +45,7 @@ public: - virtual int Check (AVCodecContext* avctx) = 0; - virtual void Reset () {} - virtual unsigned GetAllowedReferences() { return 0; } -+ virtual bool CanSkipDeint() {return false; } - virtual const std::string Name() = 0; - virtual CCriticalSection* Section() { return NULL; } - }; -@@ -62,6 +63,8 @@ public: - virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open - virtual unsigned GetConvergeCount(); - virtual unsigned GetAllowedReferences(); -+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} -+ virtual void SetCodecControl(int flags); - - bool IsHardwareAllowed() { return !m_bSoftware; } - IHardwareDecoder * GetHardware() { return m_pHardware; }; -@@ -127,4 +130,8 @@ protected: - double m_dts; - bool m_started; - std::vector m_formats; -+ double m_decoderPts, m_decoderInterval; -+ int m_skippedDeint; -+ bool m_requestSkipDeint; -+ int m_codecControlFlags; - }; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 99b3155..4fad1a3 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -38,6 +38,7 @@ - #include "DVDCodecs/DVDCodecs.h" - #include "DVDCodecs/Overlay/DVDOverlayCodecCC.h" - #include "DVDCodecs/Overlay/DVDOverlaySSA.h" -+#include "guilib/GraphicContext.h" - #include - #include - #include -@@ -320,8 +321,10 @@ void CDVDPlayerVideo::Process() - - int iDropped = 0; //frames dropped in a row - bool bRequestDrop = false; -+ int iDropDirective; - - m_videoStats.Start(); -+ m_droppingStats.Reset(); - - while (!m_bStop) - { -@@ -431,6 +434,7 @@ void CDVDPlayerVideo::Process() - picture.iFlags &= ~DVP_FLAG_ALLOCATED; - m_packets.clear(); - m_started = false; -+ m_droppingStats.Reset(); - } - else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) - { -@@ -443,6 +447,7 @@ void CDVDPlayerVideo::Process() - //we need to recalculate the framerate - //TODO: this needs to be set on a streamchange instead - ResetFrameRateCalc(); -+ m_droppingStats.Reset(); - - m_stalled = true; - m_started = false; -@@ -460,8 +465,10 @@ void CDVDPlayerVideo::Process() - m_speed = static_cast(pMsg)->m_value; - if(m_speed == DVD_PLAYSPEED_PAUSE) - m_iNrOfPicturesNotToSkip = 0; -+ - if (m_pVideoCodec) - m_pVideoCodec->SetSpeed(m_speed); -+ m_droppingStats.Reset(); - } - else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) - { -@@ -507,6 +514,28 @@ void CDVDPlayerVideo::Process() - m_iNrOfPicturesNotToSkip = 1; - } - -+ bRequestDrop = false; -+ iDropDirective = CalcDropRequirement(pts); -+ if (iDropDirective & EOS_VERYLATE) -+ { -+ if (m_bAllowDrop) -+ { -+ m_pullupCorrection.Flush(); -+ bRequestDrop = true; -+ } -+ } -+ int codecControl = 0; -+ if (iDropDirective & EOS_BUFFER_LEVEL) -+ codecControl |= DVP_FLAG_DRAIN; -+ if (m_speed > DVD_PLAYSPEED_NORMAL) -+ codecControl |= DVP_FLAG_NO_POSTPROC; -+ m_pVideoCodec->SetCodecControl(codecControl); -+ if (iDropDirective & EOS_DROPPED) -+ { -+ m_iDroppedFrames++; -+ iDropped++; -+ } -+ - if (m_messageQueue.GetDataSize() == 0 - || m_speed < 0) - { -@@ -559,15 +588,7 @@ void CDVDPlayerVideo::Process() - } - - m_videoStats.AddSampleBytes(pPacket->iSize); -- // assume decoder dropped a picture if it didn't give us any -- // picture from a demux packet, this should be reasonable -- // for libavformat as a demuxer as it normally packetizes -- // pictures when they come from demuxer -- if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE)) -- { -- m_iDroppedFrames++; -- iDropped++; -- } -+ - // reset the request, the following while loop may break before - // setting the flag to a new value - bRequestDrop = false; -@@ -1176,33 +1197,12 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - m_FlipTimeStamp += max(0.0, iSleepTime); - m_FlipTimeStamp += iFrameDuration; - -- if (iSleepTime <= 0 && m_speed) -- m_iLateFrames++; -- else -- m_iLateFrames = 0; -- -- // ask decoder to drop frames next round, as we are very late -- if(m_iLateFrames > 10) -+ if ((pPicture->iFlags & DVP_FLAG_DROPPED)) - { -- if (!(pPicture->iFlags & DVP_FLAG_NOSKIP)) -- { -- //if we're calculating the framerate, -- //don't drop frames until we've calculated a stable framerate -- if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL) -- { -- result |= EOS_VERYLATE; -- m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it -- } -- m_iDroppedRequest++; -- } -- } -- else -- { -- m_iDroppedRequest = 0; -- } -- -- if( (pPicture->iFlags & DVP_FLAG_DROPPED) ) -+ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); -+ CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__); - return result | EOS_DROPPED; -+ } - - // set fieldsync if picture is interlaced - EFIELDSYNC mDisplayField = FS_NONE; -@@ -1235,7 +1235,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - if (index < 0) - return EOS_DROPPED; - -- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); -+ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); - - return result; - #else -@@ -1535,3 +1535,127 @@ void CDVDPlayerVideo::CalcFrameRate() - m_iFrameRateCount = 0; - } - } -+ -+int CDVDPlayerVideo::CalcDropRequirement(double pts) -+{ -+ int result = 0; -+ double iSleepTime; -+ double iDecoderPts, iRenderPts; -+ double iInterval; -+ int interlaced; -+ double iGain; -+ double iLateness; -+ bool bNewFrame; -+ int iSkippedDeint = 0; -+ int iBufferLevel; -+ -+ // get decoder stats -+ if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) -+ iDecoderPts = pts; -+ if (iDecoderPts == DVD_NOPTS_VALUE) -+ iDecoderPts = pts; -+ -+ // get render stats -+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); -+ -+ if (iBufferLevel < 0) -+ result |= EOS_BUFFER_LEVEL; -+ else if (iBufferLevel < 2) -+ { -+ result |= EOS_BUFFER_LEVEL; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - hurry: %d", iBufferLevel); -+ } -+ -+ bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts; -+ -+ if (interlaced) -+ iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE; -+ else -+ iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; -+ -+ if (m_droppingStats.m_lastDecoderPts > 0 -+ && bNewFrame -+ && m_bAllowDrop -+ && m_droppingStats.m_dropRequests > 0) -+ { -+ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE; -+ if (iSkippedDeint) -+ { -+ CDroppingStats::CGain gain; -+ gain.gain = 1/m_fFrameRate; -+ gain.pts = iDecoderPts; -+ m_droppingStats.m_gain.push_back(gain); -+ m_droppingStats.m_totalGain += gain.gain; -+ result |= EOS_DROPPED; -+ m_droppingStats.m_dropRequests = 0; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped de-interlacing cycle, Sleeptime: %f, Bufferlevel: %d", iSleepTime, iBufferLevel); -+ } -+ else if (iGain > 1/m_fFrameRate) -+ { -+ CDroppingStats::CGain gain; -+ gain.gain = iGain; -+ gain.pts = iDecoderPts; -+ m_droppingStats.m_gain.push_back(gain); -+ m_droppingStats.m_totalGain += iGain; -+ result |= EOS_DROPPED; -+ m_droppingStats.m_dropRequests = 0; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped in decoder, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain); -+ } -+ } -+ m_droppingStats.m_lastDecoderPts = iDecoderPts; -+ -+ // subtract gains -+ while (!m_droppingStats.m_gain.empty() && -+ iRenderPts >= m_droppingStats.m_gain.front().pts) -+ { -+ m_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().gain; -+ m_droppingStats.m_gain.pop_front(); -+ } -+ -+ // calculate lateness -+ iLateness = iSleepTime + m_droppingStats.m_totalGain; -+ if (iLateness < 0 && m_speed) -+ { -+ if (bNewFrame) -+ m_droppingStats.m_lateFrames++; -+ -+ // if lateness is smaller than frametime, we observe this state -+ // for 10 cycles -+ if (m_droppingStats.m_lateFrames > 10 || iLateness < -2/m_fFrameRate) -+ { -+ // is frame allowed to skip -+ if (m_iNrOfPicturesNotToSkip <= 0) -+ { -+ result |= EOS_VERYLATE; -+ if (bNewFrame) -+ m_droppingStats.m_dropRequests++; -+ } -+ } -+ } -+ else -+ { -+ m_droppingStats.m_dropRequests = 0; -+ m_droppingStats.m_lateFrames = 0; -+ } -+ m_droppingStats.m_lastRenderPts = iRenderPts; -+ return result; -+} -+ -+void CDroppingStats::Reset() -+{ -+ m_gain.clear(); -+ m_totalGain = 0; -+ m_lastDecoderPts = 0; -+ m_lastRenderPts = 0; -+ m_lateFrames = 0; -+ m_dropRequests = 0; -+} -+ -+void CDroppingStats::AddOutputDropGain(double pts, double frametime) -+{ -+ CDroppingStats::CGain gain; -+ gain.gain = frametime; -+ gain.pts = pts; -+ m_gain.push_back(gain); -+ m_totalGain += frametime; -+} -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index f8ad541..186e271 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -36,6 +36,25 @@ class CDVDOverlayCodecCC; - - #define VIDEO_PICTURE_QUEUE_SIZE 1 - -+class CDroppingStats -+{ -+public: -+ void Reset(); -+ void AddOutputDropGain(double pts, double frametime); -+ struct CGain -+ { -+ double gain; -+ double pts; -+ }; -+ std::deque m_gain; -+ double m_totalGain; -+ double m_lastDecoderPts; -+ double m_lastRenderPts; -+ unsigned int m_lateFrames; -+ unsigned int m_dropRequests; -+}; -+ -+ - class CDVDPlayerVideo : public CThread - { - public: -@@ -104,6 +123,7 @@ protected: - #define EOS_ABORT 1 - #define EOS_DROPPED 2 - #define EOS_VERYLATE 4 -+#define EOS_BUFFER_LEVEL 8 - - void AutoCrop(DVDVideoPicture* pPicture); - void AutoCrop(DVDVideoPicture *pPicture, RECT &crop); -@@ -129,6 +149,7 @@ protected: - - void ResetFrameRateCalc(); - void CalcFrameRate(); -+ int CalcDropRequirement(double pts); - - double m_fFrameRate; //framerate of the video currently playing - bool m_bCalcFrameRate; //if we should calculate the framerate from the timestamps -@@ -182,5 +203,7 @@ protected: - CPullupCorrection m_pullupCorrection; - - std::list m_packets; -+ -+ CDroppingStats m_droppingStats; - }; - --- -1.9.1 - - -From 3b8554f9ad09aaed840ae6e00f5073c6e0015721 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 02/96] video player: present correct pts to user for a/v sync - (after buffering in renderer) - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 25 +++++++++++++++++++++++++ - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 2 +- - 2 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 4fad1a3..1d29b6f 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1455,6 +1455,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc() - g_advancedSettings.m_videoFpsDetect == 0; - } - -+double CDVDPlayerVideo::GetCurrentPts() -+{ -+ double iSleepTime, iRenderPts; -+ int iBufferLevel; -+ -+ // get render stats -+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); -+ -+ if( m_stalled ) -+ iRenderPts = DVD_NOPTS_VALUE; -+ else -+ iRenderPts = iRenderPts - max(0.0, iSleepTime); -+ -+ return iRenderPts; -+} -+ - #define MAXFRAMERATEDIFF 0.01 - #define MAXFRAMESERR 1000 - -@@ -1573,6 +1589,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - else - iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; - -+ -+ m_FlipTimeStamp = m_pClock->GetAbsoluteClock() + max(0.0, iSleepTime) + iInterval; -+ -+ if( m_stalled ) -+ m_iCurrentPts = DVD_NOPTS_VALUE; -+ else -+ m_iCurrentPts = iRenderPts - max(0.0, iSleepTime); -+ -+ - if (m_droppingStats.m_lastDecoderPts > 0 - && bNewFrame - && m_bAllowDrop -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index 186e271..59c7f09 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -100,7 +100,7 @@ public: - - bool InitializedOutputDevice(); - -- double GetCurrentPts() { return m_iCurrentPts; } -+ double GetCurrentPts(); - int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); } - - double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */ --- -1.9.1 - - -From 1b02662cd1ad58a5421f4dccb61cef38fea3de4e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 18:25:53 +0100 -Subject: [PATCH 03/96] videoplayer: some rework and documentation - ---- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 28 ++++++++++++++++++++-- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 11 +++++++++ - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 4 files changed, 39 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index fb34463..ecd325c 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -154,7 +154,6 @@ class CDVDCodecOptions; - #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data - #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again - #define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped --#define VC_HURRY 0x00000040 - - class CDVDVideoCodec - { -@@ -290,10 +289,35 @@ public: - */ - static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id); - -- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) -+ /* For calculation of dropping requirements player asks for some information. -+ * -+ * - pts : right after decoder, used to detect gaps (dropped frames in decoder) -+ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle -+ * instead of dropping a full frame -+ * - interlaced : when detecting gaps in pts, player needs to know whether -+ * it's interlaced or not -+ * -+ * If codec does not implement this method, pts of decoded frame at input -+ * video player is used. In case coded does post-proc and de-interlacing there -+ * may be quite some frames queued up between exit decoder and entry player. -+ */ -+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced) - { - return false; - } - -+ /** -+ * Codec can be informed by player with the following flags: -+ * -+ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off -+ * postprocessing and de-interlacing -+ * -+ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing. -+ * If video buffers in RenderManager are about to run dry, -+ * this is signaled to codec. Codec can wait for post-proc -+ * to be finished instead of returning empty and getting another -+ * packet. -+ * -+ */ - virtual void SetCodecControl(int flags) {} - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 413151d..b59c1ee 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -951,6 +951,17 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences() - return 0; - } - -+bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced) -+{ -+ pts = m_decoderPts; -+ skippedDeint = m_skippedDeint; -+ if (m_pFrame) -+ interlaced = m_pFrame->interlaced_frame; -+ else -+ interlaced = 0; -+ return true; -+} -+ - void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) - { - m_codecControlFlags = flags; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 8376f72..c0ce198 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -63,7 +63,7 @@ public: - virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open - virtual unsigned GetConvergeCount(); - virtual unsigned GetAllowedReferences(); -- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} -+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced); - virtual void SetCodecControl(int flags); - - bool IsHardwareAllowed() { return !m_bSoftware; } -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 1d29b6f..ee07f30 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1566,7 +1566,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - int iBufferLevel; - - // get decoder stats -- if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) -+ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) - iDecoderPts = pts; - if (iDecoderPts == DVD_NOPTS_VALUE) - iDecoderPts = pts; --- -1.9.1 - - -From 79a3a5317beae2966b118a77a25b60b8b3a88c22 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 1 Jun 2013 11:21:19 +0200 -Subject: [PATCH 04/96] renderer: bump buffers to 5 - ---- - xbmc/cores/VideoRenderers/BaseRenderer.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index dc2712a..9edfbd4 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -29,7 +29,7 @@ - - #define MAX_PLANES 3 - #define MAX_FIELDS 3 --#define NUM_BUFFERS 3 -+#define NUM_BUFFERS 5 - - class CSetting; - --- -1.9.1 - - -From 307a65669e2b2936d77ec1f06cb60ff45fa5ffa9 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 05/96] videoplayer: update frametime, it might change due to - fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index ee07f30..b3175cd 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -708,6 +708,8 @@ void CDVDPlayerVideo::Process() - - int iResult = OutputPicture(&picture, pts); - -+ frametime = (double)DVD_TIME_BASE/m_fFrameRate; -+ - if(m_started == false) - { - m_codecname = m_pVideoCodec->GetName(); --- -1.9.1 - - -From 0c8b92541bac2a40e3cad9f7da8fd6ce028a27ae Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 06/96] videoplayer: give streams with invalid fps a chance for - fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index b3175cd..9c36bdb 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1497,7 +1497,7 @@ void CDVDPlayerVideo::CalcFrameRate() - double frameduration = m_pullupCorrection.GetFrameDuration(); - - if (frameduration == DVD_NOPTS_VALUE || -- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) -+ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) - { - //reset the stored framerates if no good framerate was detected - m_fStableFrameRate = 0.0; --- -1.9.1 - - -From 08385386346bd04b66867a679271e8e6ad99ff6c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 07/96] dvdplayer: allow rewinding at end of stream, do a seek - after rewind - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 3a37dee..15e490c 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1633,7 +1633,7 @@ void CDVDPlayer::HandlePlaySpeed() - - } - else if (m_CurrentVideo.id >= 0 -- && m_CurrentVideo.inited == true -+ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file - && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() - && m_SpeedState.lasttime != GetTime()) - { -@@ -2294,6 +2294,12 @@ void CDVDPlayer::HandleMessages() - pvrinputstream->Pause( speed == 0 ); - } - -+ // do a seek after rewind, clock is not in sync with current pts -+ if (m_playSpeed < 0 && speed >= 0) -+ { -+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ } -+ - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE - // audioplayer, stops outputing audio to audiorendere, but still tries to - // sleep an correct amount for each packet --- -1.9.1 - - -From 79e223a725462b9e0ce94c5d9f820a92e782a197 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 08/96] X11: ditch SDL for video and window events - ---- - xbmc/Application.cpp | 2 +- - xbmc/system.h | 5 + - xbmc/windowing/Makefile.in | 1 + - xbmc/windowing/WinEvents.cpp | 4 + - xbmc/windowing/WinEventsX11.cpp | 784 ++++++++++++++++++++++++++++++++++++ - xbmc/windowing/WinEventsX11.h | 65 +++ - xbmc/windowing/X11/WinSystemX11.cpp | 386 ++++++++++++------ - xbmc/windowing/X11/WinSystemX11.h | 10 +- - 8 files changed, 1129 insertions(+), 128 deletions(-) - create mode 100644 xbmc/windowing/WinEventsX11.cpp - create mode 100644 xbmc/windowing/WinEventsX11.h - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 5e31453..5a24ffb 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -917,7 +917,7 @@ bool CApplication::CreateGUI() - - uint32_t sdlFlags = 0; - --#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2) -+#if (defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)) && !defined(HAS_GLX) - sdlFlags |= SDL_INIT_VIDEO; - #endif - -diff --git a/xbmc/system.h b/xbmc/system.h -index 1f4e15f..075e44a 100644 ---- a/xbmc/system.h -+++ b/xbmc/system.h -@@ -171,16 +171,21 @@ - #define HAS_GL - #ifdef HAVE_X11 - #define HAS_GLX -+#define HAS_X11_WIN_EVENTS - #endif - #ifdef HAVE_SDL - #define HAS_SDL - #ifndef HAS_SDL_OPENGL - #define HAS_SDL_OPENGL - #endif -+#ifndef HAVE_X11 - #define HAS_SDL_WIN_EVENTS -+#endif - #else -+#ifndef HAVE_X11 - #define HAS_LINUX_EVENTS - #endif -+#endif - #define HAS_LINUX_NETWORK - #define HAS_LIRC - #ifdef HAVE_LIBPULSE -diff --git a/xbmc/windowing/Makefile.in b/xbmc/windowing/Makefile.in -index 6704967..4b41723 100644 ---- a/xbmc/windowing/Makefile.in -+++ b/xbmc/windowing/Makefile.in -@@ -1,6 +1,7 @@ - SRCS=WinEventsSDL.cpp \ - WinEventsLinux.cpp \ - WinEventsWayland.cpp \ -+ WinEventsX11.cpp \ - WinSystem.cpp \ - WinEvents.cpp - -diff --git a/xbmc/windowing/WinEvents.cpp b/xbmc/windowing/WinEvents.cpp -index 1022ad2..8e64497 100644 ---- a/xbmc/windowing/WinEvents.cpp -+++ b/xbmc/windowing/WinEvents.cpp -@@ -42,6 +42,10 @@ - #include "WinEventsSDL.h" - #define WinEventsType CWinEventsSDL - -+#elif (defined(TARGET_FREEBSD) || defined(TARGET_LINUX)) && defined(HAS_X11_WIN_EVENTS) -+#include "WinEventsX11.h" -+#define WinEventsType CWinEventsX11 -+ - #elif defined(HAVE_WAYLAND) - #include "WinEventsWayland.h" - #define WinEventsType CWinEventsWayland -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -new file mode 100644 -index 0000000..ad58aad ---- /dev/null -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -0,0 +1,784 @@ -+/* -+* Copyright (C) 2005-2012 Team XBMC -+* http://www.xbmc.org -+* -+* This Program 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, or (at your option) -+* any later version. -+* -+* This Program 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 XBMC; see the file COPYING. If not, write to -+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+* http://www.gnu.org/copyleft/gpl.html -+* -+*/ -+ -+#include "system.h" -+ -+#ifdef HAS_X11_WIN_EVENTS -+ -+#include "WinEvents.h" -+#include "WinEventsX11.h" -+#include "Application.h" -+#include "ApplicationMessenger.h" -+#include -+#include "X11/WinSystemX11GL.h" -+#include "X11/keysymdef.h" -+#include "X11/XF86keysym.h" -+#include "utils/log.h" -+#include "guilib/GUIWindowManager.h" -+#include "input/MouseStat.h" -+ -+CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0; -+ -+static uint32_t SymMappingsX11[][2] = -+{ -+ {XK_BackSpace, XBMCK_BACKSPACE} -+, {XK_Tab, XBMCK_TAB} -+, {XK_Clear, XBMCK_CLEAR} -+, {XK_Return, XBMCK_RETURN} -+, {XK_Pause, XBMCK_PAUSE} -+, {XK_Escape, XBMCK_ESCAPE} -+, {XK_Delete, XBMCK_DELETE} -+// multi-media keys -+, {XF86XK_Back, XBMCK_BROWSER_BACK} -+, {XF86XK_Forward, XBMCK_BROWSER_FORWARD} -+, {XF86XK_Refresh, XBMCK_BROWSER_REFRESH} -+, {XF86XK_Stop, XBMCK_BROWSER_STOP} -+, {XF86XK_Search, XBMCK_BROWSER_SEARCH} -+, {XF86XK_Favorites, XBMCK_BROWSER_FAVORITES} -+, {XF86XK_HomePage, XBMCK_BROWSER_HOME} -+, {XF86XK_AudioMute, XBMCK_VOLUME_MUTE} -+, {XF86XK_AudioLowerVolume, XBMCK_VOLUME_DOWN} -+, {XF86XK_AudioRaiseVolume, XBMCK_VOLUME_UP} -+, {XF86XK_AudioNext, XBMCK_MEDIA_NEXT_TRACK} -+, {XF86XK_AudioPrev, XBMCK_MEDIA_PREV_TRACK} -+, {XF86XK_AudioStop, XBMCK_MEDIA_STOP} -+, {XF86XK_AudioPause, XBMCK_MEDIA_PLAY_PAUSE} -+, {XF86XK_Mail, XBMCK_LAUNCH_MAIL} -+, {XF86XK_Select, XBMCK_LAUNCH_MEDIA_SELECT} -+, {XF86XK_Launch0, XBMCK_LAUNCH_APP1} -+, {XF86XK_Launch1, XBMCK_LAUNCH_APP2} -+, {XF86XK_WWW, XBMCK_LAUNCH_FILE_BROWSER} -+, {XF86XK_AudioMedia, XBMCK_LAUNCH_MEDIA_CENTER } -+ // Numeric keypad -+, {XK_KP_0, XBMCK_KP0} -+, {XK_KP_1, XBMCK_KP1} -+, {XK_KP_2, XBMCK_KP2} -+, {XK_KP_3, XBMCK_KP3} -+, {XK_KP_4, XBMCK_KP4} -+, {XK_KP_5, XBMCK_KP5} -+, {XK_KP_6, XBMCK_KP6} -+, {XK_KP_7, XBMCK_KP7} -+, {XK_KP_8, XBMCK_KP8} -+, {XK_KP_9, XBMCK_KP9} -+, {XK_KP_Separator, XBMCK_KP_PERIOD} -+, {XK_KP_Divide, XBMCK_KP_DIVIDE} -+, {XK_KP_Multiply, XBMCK_KP_MULTIPLY} -+, {XK_KP_Subtract, XBMCK_KP_MINUS} -+, {XK_KP_Add, XBMCK_KP_PLUS} -+, {XK_KP_Enter, XBMCK_KP_ENTER} -+, {XK_KP_Equal, XBMCK_KP_EQUALS} -+ // Arrows + Home/End pad -+, {XK_Up, XBMCK_UP} -+, {XK_Down, XBMCK_DOWN} -+, {XK_Right, XBMCK_RIGHT} -+, {XK_Left, XBMCK_LEFT} -+, {XK_Insert, XBMCK_INSERT} -+, {XK_Home, XBMCK_HOME} -+, {XK_End, XBMCK_END} -+, {XK_Page_Up, XBMCK_PAGEUP} -+, {XK_Page_Down, XBMCK_PAGEDOWN} -+ // Function keys -+, {XK_F1, XBMCK_F1} -+, {XK_F2, XBMCK_F2} -+, {XK_F3, XBMCK_F3} -+, {XK_F4, XBMCK_F4} -+, {XK_F5, XBMCK_F5} -+, {XK_F6, XBMCK_F6} -+, {XK_F7, XBMCK_F7} -+, {XK_F8, XBMCK_F8} -+, {XK_F9, XBMCK_F9} -+, {XK_F10, XBMCK_F10} -+, {XK_F11, XBMCK_F11} -+, {XK_F12, XBMCK_F12} -+, {XK_F13, XBMCK_F13} -+, {XK_F14, XBMCK_F14} -+, {XK_F15, XBMCK_F15} -+ // Key state modifier keys -+, {XK_Num_Lock, XBMCK_NUMLOCK} -+, {XK_Caps_Lock, XBMCK_CAPSLOCK} -+, {XK_Scroll_Lock, XBMCK_SCROLLOCK} -+, {XK_Shift_R, XBMCK_RSHIFT} -+, {XK_Shift_L, XBMCK_LSHIFT} -+, {XK_Control_R, XBMCK_RCTRL} -+, {XK_Control_L, XBMCK_LCTRL} -+, {XK_Alt_R, XBMCK_RALT} -+, {XK_Alt_L, XBMCK_LALT} -+, {XK_Meta_R, XBMCK_RMETA} -+, {XK_Meta_L, XBMCK_LMETA} -+, {XK_Super_L, XBMCK_LSUPER} -+, {XK_Super_R, XBMCK_RSUPER} -+, {XK_Mode_switch, XBMCK_MODE} -+, {XK_Multi_key, XBMCK_COMPOSE} -+ // Miscellaneous function keys -+, {XK_Help, XBMCK_HELP} -+, {XK_Print, XBMCK_PRINT} -+//, {0, XBMCK_SYSREQ} -+, {XK_Break, XBMCK_BREAK} -+, {XK_Menu, XBMCK_MENU} -+, {XF86XK_PowerOff, XBMCK_POWER} -+, {XK_EcuSign, XBMCK_EURO} -+, {XK_Undo, XBMCK_UNDO} -+ /* Media keys */ -+, {XF86XK_Eject, XBMCK_EJECT} -+, {XF86XK_Stop, XBMCK_STOP} -+, {XF86XK_AudioRecord, XBMCK_RECORD} -+, {XF86XK_AudioRewind, XBMCK_REWIND} -+, {XF86XK_Phone, XBMCK_PHONE} -+, {XF86XK_AudioPlay, XBMCK_PLAY} -+, {XF86XK_AudioRandomPlay, XBMCK_SHUFFLE} -+, {XF86XK_AudioForward, XBMCK_FASTFORWARD} -+}; -+ -+bool CWinEventsX11::MessagePump() -+{ -+ return CWinEventsX11Imp::MessagePump(); -+} -+ -+size_t CWinEventsX11::GetQueueSize() -+{ -+ return CWinEventsX11Imp::GetQueueSize(); -+} -+ -+CWinEventsX11Imp::CWinEventsX11Imp() -+{ -+ m_display = 0; -+ m_window = 0; -+ m_keybuf = 0; -+ m_utf16buf = 0; -+} -+ -+CWinEventsX11Imp::~CWinEventsX11Imp() -+{ -+ if (m_keybuf); -+ { -+ free(m_keybuf); -+ m_keybuf = 0; -+ } -+ -+ if (m_utf16buf) -+ { -+ free(m_utf16buf); -+ m_utf16buf = 0; -+ } -+ -+ if (m_xic) -+ { -+ XUnsetICFocus(m_xic); -+ XDestroyIC(m_xic); -+ m_xic = 0; -+ } -+ -+ if (m_xim) -+ { -+ XCloseIM(m_xim); -+ m_xim = 0; -+ } -+ -+ m_symLookupTable.clear(); -+} -+ -+bool CWinEventsX11Imp::Init(Display *dpy, Window win) -+{ -+ if (WinEvents) -+ return true; -+ -+ WinEvents = new CWinEventsX11Imp(); -+ WinEvents->m_display = dpy; -+ WinEvents->m_window = win; -+ WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -+ WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); -+ WinEvents->m_keymodState = 0; -+ WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -+ WinEvents->m_structureChanged = false; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); -+ -+ // open input method -+ char *old_locale = NULL, *old_modifiers = NULL; -+ char res_name[8]; -+ const char *p; -+ size_t n; -+ -+ // set resource name to xbmc, not used -+ strcpy(res_name, "xbmc"); -+ -+ // save current locale, this should be "C" -+ p = setlocale(LC_ALL, NULL); -+ if (p) -+ { -+ old_locale = (char*)malloc(strlen(p) +1); -+ strcpy(old_locale, p); -+ } -+ p = XSetLocaleModifiers(NULL); -+ if (p) -+ { -+ old_modifiers = (char*)malloc(strlen(p) +1); -+ strcpy(old_modifiers, p); -+ } -+ -+ // set users preferences and open input method -+ p = setlocale(LC_ALL, ""); -+ XSetLocaleModifiers(""); -+ WinEvents->m_xim = XOpenIM(WinEvents->m_display, NULL, res_name, res_name); -+ -+ // restore old locale -+ if (old_locale) -+ { -+ setlocale(LC_ALL, old_locale); -+ free(old_locale); -+ } -+ if (old_modifiers) -+ { -+ XSetLocaleModifiers(old_modifiers); -+ free(old_modifiers); -+ } -+ -+ WinEvents->m_xic = NULL; -+ if (WinEvents->m_xim) -+ { -+ WinEvents->m_xic = XCreateIC(WinEvents->m_xim, -+ XNClientWindow, WinEvents->m_window, -+ XNFocusWindow, WinEvents->m_window, -+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing, -+ XNResourceName, res_name, -+ XNResourceClass, res_name, -+ NULL); -+ } -+ -+ if (!WinEvents->m_xic) -+ CLog::Log(LOGWARNING,"CWinEventsX11::Init - no input method found"); -+ -+ // build Keysym lookup table -+ for (unsigned int i = 0; i < sizeof(SymMappingsX11)/(2*sizeof(uint32_t)); ++i) -+ { -+ WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; -+ } -+ -+ return true; -+} -+ -+void CWinEventsX11Imp::Quit() -+{ -+ if (!WinEvents) -+ return; -+ -+ delete WinEvents; -+ WinEvents = 0; -+} -+ -+bool CWinEventsX11Imp::HasStructureChanged() -+{ -+ if (!WinEvents) -+ return false; -+ -+ bool ret = WinEvents->m_structureChanged; -+ WinEvents->m_structureChanged = false; -+ return ret; -+} -+ -+bool CWinEventsX11Imp::MessagePump() -+{ -+ if (!WinEvents) -+ return false; -+ -+ bool ret = false; -+ XEvent xevent; -+ unsigned long serial = 0; -+ -+ while (WinEvents && XPending(WinEvents->m_display)) -+ { -+ memset(&xevent, 0, sizeof (XEvent)); -+ XNextEvent(WinEvents->m_display, &xevent); -+ -+ // ignore events generated by auto-repeat -+ if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) -+ { -+ XEvent peekevent; -+ XPeekEvent(WinEvents->m_display, &peekevent); -+ if ((peekevent.type == KeyPress) && -+ (peekevent.xkey.keycode == xevent.xkey.keycode) && -+ ((peekevent.xkey.time - xevent.xkey.time) < 2)) -+ { -+ XNextEvent(WinEvents->m_display, &peekevent); -+ continue; -+ } -+ } -+ -+ if (XFilterEvent(&xevent, None)) -+ continue; -+ -+ switch (xevent.type) -+ { -+ case MapNotify: -+ { -+ g_application.SetRenderGUI(true); -+ break; -+ } -+ -+ case UnmapNotify: -+ { -+ g_application.SetRenderGUI(false); -+ break; -+ } -+ -+ case FocusIn: -+ { -+ if (WinEvents->m_xic) -+ XSetICFocus(WinEvents->m_xic); -+ g_application.m_AppFocused = true; -+ if (serial == xevent.xfocus.serial) -+ break; -+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -+ break; -+ } -+ -+ case FocusOut: -+ { -+ if (WinEvents->m_xic) -+ XUnsetICFocus(WinEvents->m_xic); -+ g_application.m_AppFocused = false; -+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -+ serial = xevent.xfocus.serial; -+ break; -+ } -+ -+ case Expose: -+ { -+ g_windowManager.MarkDirty(); -+ break; -+ } -+ -+ case ConfigureNotify: -+ { -+ if (xevent.xconfigure.window != WinEvents->m_window) -+ break; -+ -+ WinEvents->m_structureChanged = true; -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_VIDEORESIZE; -+ newEvent.resize.w = xevent.xconfigure.width; -+ newEvent.resize.h = xevent.xconfigure.height; -+ ret |= g_application.OnEvent(newEvent); -+ g_windowManager.MarkDirty(); -+ break; -+ } -+ -+ case ClientMessage: -+ { -+ if (xevent.xclient.data.l[0] == WinEvents->m_wmDeleteMessage) -+ if (!g_application.m_bStop) CApplicationMessenger::Get().Quit(); -+ break; -+ } -+ -+ case KeyPress: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_KEYDOWN; -+ KeySym xkeysym; -+ -+ // fallback if we have no IM -+ if (!WinEvents->m_xic) -+ { -+ static XComposeStatus state; -+ char keybuf[32]; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ if (XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state)) -+ { -+ newEvent.key.keysym.unicode = keybuf[0]; -+ } -+ ret |= ProcessKey(newEvent, 500); -+ break; -+ } -+ -+ Status status; -+ int utf16size; -+ int utf16length; -+ int len; -+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ &xkeysym, &status); -+ if (status == XBufferOverflow) -+ { -+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); -+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ &xkeysym, &status); -+ } -+ switch (status) -+ { -+ case XLookupNone: -+ break; -+ case XLookupChars: -+ case XLookupBoth: -+ { -+ if (len == 0) -+ break; -+ utf16size = len * sizeof(uint16_t); -+ if (utf16size > sizeof(WinEvents->m_utf16buf)) -+ { -+ WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); -+ if (WinEvents->m_utf16buf == NULL) -+ { -+ break; -+ } -+ } -+ utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); -+ if (utf16length < 0) -+ { -+ break; -+ } -+ for (unsigned int i = 0; i < utf16length - 1; i++) -+ { -+ newEvent.key.keysym.sym = XBMCK_UNKNOWN; -+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 500); -+ } -+ if (utf16length > 0) -+ { -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ -+ ret |= ProcessKey(newEvent, 500); -+ } -+ break; -+ } -+ -+ case XLookupKeySym: -+ { -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 500); -+ break; -+ } -+ -+ }// switch status -+ break; -+ } //KeyPress -+ -+ case KeyRelease: -+ { -+ XBMC_Event newEvent; -+ KeySym xkeysym; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_KEYUP; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 0); -+ break; -+ } -+ -+ // lose mouse coverage -+ case LeaveNotify: -+ { -+ g_Mouse.SetActive(false); -+ break; -+ } -+ -+ case MotionNotify: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEMOTION; -+ newEvent.motion.xrel = (int16_t)xevent.xmotion.x_root; -+ newEvent.motion.yrel = (int16_t)xevent.xmotion.y_root; -+ newEvent.motion.x = (int16_t)xevent.xmotion.x; -+ newEvent.motion.y = (int16_t)xevent.xmotion.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ case ButtonPress: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEBUTTONDOWN; -+ newEvent.button.button = (unsigned char)xevent.xbutton.button; -+ newEvent.button.state = XBMC_PRESSED; -+ newEvent.button.x = (int16_t)xevent.xbutton.x; -+ newEvent.button.y = (int16_t)xevent.xbutton.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ case ButtonRelease: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEBUTTONUP; -+ newEvent.button.button = (unsigned char)xevent.xbutton.button; -+ newEvent.button.state = XBMC_RELEASED; -+ newEvent.button.x = (int16_t)xevent.xbutton.x; -+ newEvent.button.y = (int16_t)xevent.xbutton.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ default: -+ { -+ break; -+ } -+ }// switch event.type -+ }// while -+ -+ ret |= ProcessKeyRepeat(); -+ -+ return ret; -+} -+ -+size_t CWinEventsX11Imp::GetQueueSize() -+{ -+ int ret = 0; -+ -+ if (WinEvents) -+ ret = XPending(WinEvents->m_display); -+ -+ return ret; -+} -+ -+bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) -+{ -+ if (event.type == XBMC_KEYDOWN) -+ { -+ // check key modifiers -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_LSHIFT: -+ WinEvents->m_keymodState |= XBMCKMOD_LSHIFT; -+ break; -+ case XBMCK_RSHIFT: -+ WinEvents->m_keymodState |= XBMCKMOD_RSHIFT; -+ break; -+ case XBMCK_LCTRL: -+ WinEvents->m_keymodState |= XBMCKMOD_LCTRL; -+ break; -+ case XBMCK_RCTRL: -+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LALT: -+ WinEvents->m_keymodState |= XBMCKMOD_LALT; -+ break; -+ case XBMCK_RALT: -+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LMETA: -+ WinEvents->m_keymodState |= XBMCKMOD_LMETA; -+ break; -+ case XBMCK_RMETA: -+ WinEvents->m_keymodState |= XBMCKMOD_RMETA; -+ break; -+ case XBMCK_MODE: -+ WinEvents->m_keymodState |= XBMCKMOD_MODE; -+ break; -+ default: -+ break; -+ } -+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -+ memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); -+ WinEvents->m_repeatKeyTimeout.Set(repeatDelay); -+ -+ bool ret = ProcessShortcuts(event); -+ if (ret) -+ return ret; -+ } -+ else if (event.type == XBMC_KEYUP) -+ { -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_LSHIFT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LSHIFT; -+ break; -+ case XBMCK_RSHIFT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RSHIFT; -+ break; -+ case XBMCK_LCTRL: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LCTRL; -+ break; -+ case XBMCK_RCTRL: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LALT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LALT; -+ break; -+ case XBMCK_RALT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LMETA: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LMETA; -+ break; -+ case XBMCK_RMETA: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RMETA; -+ break; -+ case XBMCK_MODE: -+ WinEvents->m_keymodState &= ~XBMCKMOD_MODE; -+ break; -+ default: -+ break; -+ } -+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(event)); -+ } -+ -+ return g_application.OnEvent(event); -+} -+ -+bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) -+{ -+ if (event.key.keysym.mod & XBMCKMOD_ALT) -+ { -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_TAB: // ALT+TAB to minimize/hide -+ g_application.Minimize(); -+ return true; -+ -+ default: -+ return false; -+ } -+ } -+ return false; -+} -+ -+bool CWinEventsX11Imp::ProcessKeyRepeat() -+{ -+ if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) -+ { -+ if (WinEvents->m_repeatKeyTimeout.IsTimePast()) -+ { -+ return ProcessKey(WinEvents->m_lastKey, 10); -+ } -+ } -+ return false; -+} -+ -+int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) -+{ -+ // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. -+ uint16_t *p = utf16; -+ uint16_t const *const maxPtr = utf16 + utf16MaxLength; -+ -+ // end_of_input points to the last byte of input as opposed to the next to the last byte. -+ char const *const endOfInput = utf8 + utf8Length - 1; -+ -+ while (utf8 <= endOfInput) -+ { -+ unsigned char const c = *utf8; -+ if (p >= maxPtr) -+ { -+ //No more output space. -+ return -1; -+ } -+ if (c < 0x80) -+ { -+ //One byte ASCII. -+ *p++ = c; -+ utf8 += 1; -+ } -+ else if (c < 0xC0) -+ { -+ // Follower byte without preceding leader bytes. -+ return -1; -+ } -+ // 11 bits -+ else if (c < 0xE0) -+ { -+ // Two byte sequence. We need one follower byte. -+ if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) -+ { -+ return -1; -+ } -+ *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); -+ utf8 += 2; -+ } -+ // 16 bis -+ else if (c < 0xF0) -+ { -+ // Three byte sequence. We need two follower byte. -+ if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) -+ { -+ return -1; -+ } -+ *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); -+ utf8 += 3; -+ } -+ // 21 bits -+ else if (c < 0xF8) -+ { -+ int plane; -+ // Four byte sequence. We need three follower bytes. -+ if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || -+ ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) -+ { -+ return -1; -+ } -+ uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + -+ ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); -+ utf8 += 4; -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ } -+ // 26 bits -+ else if (c < 0xFC) -+ { -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ utf8 += 5; -+ } -+ // 31 bit -+ else -+ { -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ utf8 += 6; -+ } -+ } -+ return p - utf16; -+} -+ -+XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) -+{ -+ // try direct mapping first -+ std::map::iterator it; -+ it = WinEvents->m_symLookupTable.find(keysym); -+ if (it != WinEvents->m_symLookupTable.end()) -+ { -+ return (XBMCKey)(it->second); -+ } -+ -+ // try ascii mappings -+ if (keysym>>8 == 0x00) -+ return (XBMCKey)(keysym & 0xFF); -+ -+ return (XBMCKey)keysym; -+} -+#endif -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -new file mode 100644 -index 0000000..ce57c23 ---- /dev/null -+++ b/xbmc/windowing/WinEventsX11.h -@@ -0,0 +1,65 @@ -+/* -+* Copyright (C) 2005-2012 Team XBMC -+* http://www.xbmc.org -+* -+* This Program 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, or (at your option) -+* any later version. -+* -+* This Program 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 XBMC; see the file COPYING. If not, write to -+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+* http://www.gnu.org/copyleft/gpl.html -+* -+*/ -+#pragma once -+ -+#include "WinEvents.h" -+#include -+#include "threads/SystemClock.h" -+#include -+ -+class CWinEventsX11 : public IWinEvents -+{ -+public: -+ virtual bool MessagePump(); -+ virtual size_t GetQueueSize(); -+}; -+ -+class CWinEventsX11Imp -+{ -+public: -+ CWinEventsX11Imp(); -+ virtual ~CWinEventsX11Imp(); -+ static bool Init(Display *dpy, Window win); -+ static void Quit(); -+ static bool HasStructureChanged(); -+ static bool MessagePump(); -+ static size_t GetQueueSize(); -+ -+protected: -+ static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); -+ static XBMCKey LookupXbmcKeySym(KeySym keysym); -+ static bool ProcessKey(XBMC_Event &event, int repeatDelay); -+ static bool ProcessKeyRepeat(); -+ static bool ProcessShortcuts(XBMC_Event& event); -+ static CWinEventsX11Imp *WinEvents; -+ Display *m_display; -+ Window m_window; -+ Atom m_wmDeleteMessage; -+ char *m_keybuf; -+ uint16_t *m_utf16buf; -+ XIM m_xim; -+ XIC m_xic; -+ XBMC_Event m_lastKey; -+ XbmcThreads::EndTime m_repeatKeyTimeout; -+ std::map m_symLookupTable; -+ int m_keymodState; -+ bool m_structureChanged; -+}; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 083d1e9..40b8403 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -22,7 +22,6 @@ - - #ifdef HAS_GLX - --#include - #include "WinSystemX11.h" - #include "settings/DisplaySettings.h" - #include "settings/Settings.h" -@@ -34,7 +33,6 @@ - #include "XRandR.h" - #include - #include "threads/SingleLock.h" --#include - #include "cores/VideoRenderers/RenderManager.h" - #include "utils/TimeUtils.h" - #include "utils/StringUtils.h" -@@ -43,19 +41,22 @@ - #include - #endif - -+#include "../WinEventsX11.h" -+#include "input/MouseStat.h" -+ - using namespace std; - - CWinSystemX11::CWinSystemX11() : CWinSystemBase() - { - m_eWindowSystem = WINDOW_SYSTEM_X11; - m_glContext = NULL; -- m_SDLSurface = NULL; - m_dpy = NULL; - m_glWindow = 0; -- m_wmWindow = 0; - m_bWasFullScreenBeforeMinimize = false; - m_minimized = false; -+ m_bIgnoreNextFocusMessage = false; - m_dpyLostTime = 0; -+ m_invisibleCursor = 0; - - XSetErrorHandler(XErrorHandler); - } -@@ -68,18 +69,6 @@ bool CWinSystemX11::InitWindowSystem() - { - if ((m_dpy = XOpenDisplay(NULL))) - { -- -- SDL_EnableUNICODE(1); -- // set repeat to 10ms to ensure repeat time < frame time -- // so that hold times can be reliably detected -- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10); -- -- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); -- - return CWinSystemBase::InitWindowSystem(); - } - else -@@ -117,45 +106,37 @@ bool CWinSystemX11::DestroyWindowSystem() - - bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) - { -- RESOLUTION_INFO& desktop = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP); -- -- if (fullScreen && -- (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || -- res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) -- { -- //on the first call to SDL_SetVideoMode, SDL stores the current displaymode -- //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode -- //before the first call to SDL_SetVideoMode, SDL changes the displaymode back -- //to the wrong mode on exit -- -- CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); -- if (!SetFullScreen(true, desktop, false)) -- return false; -- } -- - if(!SetFullScreen(fullScreen, res, false)) - return false; - -- CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon256x256.png"); -- -- if (iconTexture) -- SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); -- SDL_WM_SetCaption("XBMC Media Center", NULL); -- delete iconTexture; -- -- // register XRandR Events --#if defined(HAS_XRANDR) -- int iReturn; -- XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn); -- XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask); --#endif -- - m_bWindowCreated = true; - return true; - } - - bool CWinSystemX11::DestroyWindow() - { -+ if (!m_glWindow) -+ return true; -+ -+ if (m_glContext) -+ glXMakeCurrent(m_dpy, None, NULL); -+ -+ if (m_invisibleCursor) -+ { -+ XUndefineCursor(m_dpy, m_glWindow); -+ XFreeCursor(m_dpy, m_invisibleCursor); -+ m_invisibleCursor = 0; -+ } -+ -+ CWinEventsX11Imp::Quit(); -+ -+ XUnmapWindow(m_dpy, m_glWindow); -+ XSync(m_dpy,TRUE); -+ XUngrabKeyboard(m_dpy, CurrentTime); -+ XUngrabPointer(m_dpy, CurrentTime); -+ XDestroyWindow(m_dpy, m_glWindow); -+ m_glWindow = 0; -+ - return true; - } - -@@ -165,67 +146,105 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - && m_nHeight == newHeight) - return true; - -+ if (!SetWindow(newWidth, newHeight, false)) -+ { -+ return false; -+ } -+ -+ RefreshGlxContext(); - m_nWidth = newWidth; - m_nHeight = newHeight; -+ m_bFullScreen = false; - -- int options = SDL_OPENGL; -- if (m_bFullScreen) -- options |= SDL_FULLSCREEN; -- else -- options |= SDL_RESIZABLE; -+ return false; -+} - -- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) -+void CWinSystemX11::RefreshWindow() -+{ -+ g_xrandr.Query(true); -+ XOutput out = g_xrandr.GetCurrentOutput(); -+ XMode mode = g_xrandr.GetCurrentMode(out.name); -+ -+ // only overwrite desktop resolution, if we are not in fullscreen mode -+ if (!g_graphicsContext.IsFullScreenVideo()) - { -- SetGrabMode(); -- RefreshGlxContext(); -- return true; -+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; -+ g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; - } - -- return false; -+ RESOLUTION_INFO res; -+ unsigned int i; -+ bool found(false); -+ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) -+ { -+ if (g_settings.m_ResInfo[i].strId == mode.id) -+ { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -+ return; -+ } -+ -+ if (g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -+ else -+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); - } - - bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { -- m_nWidth = res.iWidth; -- m_nHeight = res.iHeight; -- m_bFullScreen = fullScreen; - - #if defined(HAS_XRANDR) - XOutput out; - XMode mode; -- out.name = res.strOutput; -- mode.w = res.iWidth; -- mode.h = res.iHeight; -- mode.hz = res.fRefreshRate; -- mode.id = res.strId; -+ -+ if (fullScreen) -+ { -+ out.name = res.strOutput; -+ mode.w = res.iWidth; -+ mode.h = res.iHeight; -+ mode.hz = res.fRefreshRate; -+ mode.id = res.strId; -+ } -+ else -+ { -+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ } - -- if(m_bFullScreen) -+ XOutput currout = g_xrandr.GetCurrentOutput(); -+ XMode currmode = g_xrandr.GetCurrentMode(currout.name); -+ -+ // only call xrandr if mode changes -+ if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || -+ currmode.hz != mode.hz || currmode.id != mode.id) - { -+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); - OnLostDevice(); - g_xrandr.SetMode(out, mode); - } -- else -- g_xrandr.RestoreState(); - #endif - -- int options = SDL_OPENGL; -- if (m_bFullScreen) -- options |= SDL_FULLSCREEN; -- else -- options |= SDL_RESIZABLE; -- -- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) -- { -- if ((m_SDLSurface->flags & SDL_OPENGL) != SDL_OPENGL) -- CLog::Log(LOGERROR, "CWinSystemX11::SetFullScreen SDL_OPENGL not set, SDL_GetError:%s", SDL_GetError()); -+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) -+ return false; - -- SetGrabMode(); -- RefreshGlxContext(); -+ RefreshGlxContext(); - -- return true; -- } -+ m_nWidth = res.iWidth; -+ m_nHeight = res.iHeight; -+ m_bFullScreen = fullScreen; - -- return false; -+ return true; - } - - void CWinSystemX11::UpdateResolutions() -@@ -327,17 +346,10 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - bool CWinSystemX11::RefreshGlxContext() - { - bool retVal = false; -- SDL_SysWMinfo info; -- SDL_VERSION(&info.version); -- if (SDL_GetWMInfo(&info) <= 0) -- { -- CLog::Log(LOGERROR, "Failed to get window manager info from SDL"); -- return false; -- } - -- if(m_glWindow == info.info.x11.window && m_glContext) -+ if (m_glContext) - { -- CLog::Log(LOGERROR, "GLX: Same window as before, refreshing context"); -+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); - return true; -@@ -349,8 +361,6 @@ bool CWinSystemX11::RefreshGlxContext() - int availableVisuals = 0; - vMask.screen = DefaultScreen(m_dpy); - XWindowAttributes winAttr; -- m_glWindow = info.info.x11.window; -- m_wmWindow = info.info.x11.wmwindow; - - /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() - or XGetVisualInfo() fail. That shouldn't happen unless something is -@@ -421,7 +431,10 @@ bool CWinSystemX11::RefreshGlxContext() - - void CWinSystemX11::ShowOSMouse(bool show) - { -- SDL_ShowCursor(show ? 1 : 0); -+ if (show) -+ XUndefineCursor(m_dpy,m_glWindow); -+ else if (m_invisibleCursor) -+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); - } - - void CWinSystemX11::ResetOSScreensaver() -@@ -435,8 +448,6 @@ void CWinSystemX11::ResetOSScreensaver() - { - m_screensaverReset.StartZero(); - XResetScreenSaver(m_dpy); -- //need to flush the output buffer, since we don't check for events on m_dpy -- XFlush(m_dpy); - } - } - else -@@ -452,13 +463,27 @@ void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - - m_minimized = !bActivated; - } -+ -+void CWinSystemX11::NotifyAppFocusChange(bool bGaining) -+{ -+ if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && -+ !g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.ToggleFullScreenRoot(); -+ if (!bGaining) -+ m_bIgnoreNextFocusMessage = false; -+} -+ - bool CWinSystemX11::Minimize() - { - m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); - if (m_bWasFullScreenBeforeMinimize) -+ { -+ m_bIgnoreNextFocusMessage = true; - g_graphicsContext.ToggleFullScreenRoot(); -+ } -+ -+ XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); - -- SDL_WM_IconifyWindow(); - m_minimized = true; - return true; - } -@@ -468,13 +493,13 @@ bool CWinSystemX11::Restore() - } - bool CWinSystemX11::Hide() - { -- XUnmapWindow(m_dpy, m_wmWindow); -+ XUnmapWindow(m_dpy, m_glWindow); - XSync(m_dpy, False); - return true; - } - bool CWinSystemX11::Show(bool raise) - { -- XMapWindow(m_dpy, m_wmWindow); -+ XMapWindow(m_dpy, m_glWindow); - XSync(m_dpy, False); - m_minimized = false; - return true; -@@ -506,6 +531,7 @@ void CWinSystemX11::CheckDisplayEvents() - if (bGotEvent || bTimeout) - { - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -+ RefreshWindow(); - - CSingleLock lock(m_resourceSection); - -@@ -564,37 +590,151 @@ bool CWinSystemX11::EnableFrameLimiter() - return m_minimized; - } - --void CWinSystemX11::SetGrabMode(const CSetting *setting /*= NULL*/) -+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - { -- bool enabled; -- if (setting) -- enabled = ((CSettingBool*)setting)->GetValue(); -- else -- enabled = CSettings::Get().GetBool("input.enablesystemkeys"); -- -- if (m_SDLSurface && m_SDLSurface->flags & SDL_FULLSCREEN) -+ bool changeWindow = false; -+ bool changeSize = false; -+ bool mouseActive = false; -+ float mouseX, mouseY; -+ -+ if (m_glWindow && (m_bFullScreen != fullscreen)) - { -- if (enabled) -+ mouseActive = g_Mouse.IsActive(); -+ if (mouseActive) - { -- //SDL will always call XGrabPointer and XGrabKeyboard when in fullscreen -- //so temporarily zero the SDL_FULLSCREEN flag, then turn off SDL grab mode -- //this will make SDL call XUnGrabPointer and XUnGrabKeyboard -- m_SDLSurface->flags &= ~SDL_FULLSCREEN; -- SDL_WM_GrabInput(SDL_GRAB_OFF); -- m_SDLSurface->flags |= SDL_FULLSCREEN; -+ Window root_return, child_return; -+ int root_x_return, root_y_return; -+ int win_x_return, win_y_return; -+ unsigned int mask_return; -+ bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, -+ &root_x_return, &root_y_return, -+ &win_x_return, &win_y_return, -+ &mask_return); -+ if (isInWin) -+ { -+ mouseX = (float)win_x_return/m_nWidth; -+ mouseY = (float)win_y_return/m_nHeight; -+ g_Mouse.SetActive(false); -+ } -+ else -+ mouseActive = false; - } -- else -+ DestroyWindow(); -+ } -+ -+ // create main window -+ if (!m_glWindow) -+ { -+ GLint att[] = - { -- //turn off key grabbing, which will actually make SDL turn it on when in fullscreen -- SDL_WM_GrabInput(SDL_GRAB_OFF); -- } -+ GLX_RGBA, -+ GLX_RED_SIZE, 8, -+ GLX_GREEN_SIZE, 8, -+ GLX_BLUE_SIZE, 8, -+ GLX_ALPHA_SIZE, 8, -+ GLX_DEPTH_SIZE, 24, -+ GLX_DOUBLEBUFFER, -+ None -+ }; -+ Colormap cmap; -+ XSetWindowAttributes swa; -+ XVisualInfo *vi; -+ -+ vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); -+ cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); -+ -+ int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -+ swa.override_redirect = fullscreen ? True : False; -+ swa.border_pixel = fullscreen ? 0 : 5; -+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; -+ swa.colormap = cmap; -+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; -+ swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | -+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | -+ PropertyChangeMask | StructureNotifyMask | KeymapStateMask | -+ EnterWindowMask | LeaveWindowMask | ExposureMask; -+ unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; -+ -+ m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -+ 0, 0, width, height, 0, vi->depth, -+ InputOutput, vi->visual, -+ mask, &swa); -+ -+ // define invisible cursor -+ Pixmap bitmapNoData; -+ XColor black; -+ static char noData[] = { 0,0,0,0,0,0,0,0 }; -+ black.red = black.green = black.blue = 0; -+ -+ bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); -+ m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, -+ &black, &black, 0, 0); -+ XFreePixmap(m_dpy, bitmapNoData); -+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); -+ -+ //init X11 events -+ CWinEventsX11Imp::Init(m_dpy, m_glWindow); -+ -+ changeWindow = true; -+ changeSize = true; - } --} - --void CWinSystemX11::OnSettingChanged(const CSetting *setting) --{ -- if (setting->GetId() == "input.enablesystemkeys") -- SetGrabMode(setting); -+ if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) -+ { -+ changeSize = true; -+ } -+ -+ if (changeSize || changeWindow) -+ { -+ XResizeWindow(m_dpy, m_glWindow, width, height); -+ } -+ -+ if (changeWindow) -+ { -+ if (!fullscreen) -+ { -+ XWMHints wm_hints; -+ XClassHint class_hints; -+ XTextProperty windowName, iconName; -+ std::string titleString = "XBMC Media Center"; -+ char *title = (char*)titleString.c_str(); -+ -+ XStringListToTextProperty(&title, 1, &windowName); -+ XStringListToTextProperty(&title, 1, &iconName); -+ wm_hints.initial_state = NormalState; -+ wm_hints.input = True; -+ wm_hints.icon_pixmap = None; -+ wm_hints.flags = StateHint | IconPixmapHint | InputHint; -+ -+ XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -+ NULL, 0, NULL, &wm_hints, -+ NULL); -+ -+ // register interest in the delete window message -+ Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); -+ XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); -+ } -+ XMapRaised(m_dpy, m_glWindow); -+ XSync(m_dpy,TRUE); -+ -+ if (changeWindow && mouseActive) -+ { -+ XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); -+ } -+ -+ if (fullscreen) -+ { -+ int result = -1; -+ while (result != GrabSuccess) -+ { -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); -+ XbmcThreads::ThreadSleep(100); -+ } -+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ -+ } -+ } -+ return true; - } - - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index b1464d0..34b912f 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -54,6 +54,7 @@ public: - virtual bool EnableFrameLimiter(); - - virtual void NotifyAppActiveChange(bool bActivated); -+ virtual void NotifyAppFocusChange(bool bGaining); - - virtual bool Minimize(); - virtual bool Restore() ; -@@ -66,20 +67,21 @@ public: - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -- virtual void OnSettingChanged(const CSetting *setting); -+ void RefreshWindow(); - - protected: - bool RefreshGlxContext(); - void CheckDisplayEvents(); - void OnLostDevice(); -+ bool SetWindow(int width, int height, bool fullscreen); - -- SDL_Surface* m_SDLSurface; -+ Window m_glWindow; - GLXContext m_glContext; -- GLXWindow m_glWindow; -- Window m_wmWindow; - Display* m_dpy; -+ Cursor m_invisibleCursor; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; -+ bool m_bIgnoreNextFocusMessage; - int m_RREventBase; - CCriticalSection m_resourceSection; - std::vector m_resources; --- -1.9.1 - - -From df8808f316b757da4e760ee8669326901191a6e5 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 09/96] X11: Add xbmc icon - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 126 +++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 3 +- - 2 files changed, 127 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 40b8403..858ea5e 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -137,6 +137,9 @@ bool CWinSystemX11::DestroyWindow() - XDestroyWindow(m_dpy, m_glWindow); - m_glWindow = 0; - -+ if (m_icon) -+ XFreePixmap(m_dpy, m_icon); -+ - return true; - } - -@@ -691,8 +694,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - - if (changeWindow) - { -+ m_icon = None; - if (!fullscreen) - { -+ CreateIconPixmap(); - XWMHints wm_hints; - XClassHint class_hints; - XTextProperty windowName, iconName; -@@ -703,7 +708,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - XStringListToTextProperty(&title, 1, &iconName); - wm_hints.initial_state = NormalState; - wm_hints.input = True; -- wm_hints.icon_pixmap = None; -+ wm_hints.icon_pixmap = m_icon; - wm_hints.flags = StateHint | IconPixmapHint | InputHint; - - XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -@@ -737,4 +742,123 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - return true; - } - -+bool CWinSystemX11::CreateIconPixmap() -+{ -+ int depth; -+ XImage *img = NULL; -+ Visual *vis; -+ XWindowAttributes wndattribs; -+ XVisualInfo visInfo; -+ double rRatio; -+ double gRatio; -+ double bRatio; -+ int outIndex = 0; -+ int i,j; -+ int numBufBytes; -+ unsigned char *buf; -+ uint32_t *newBuf = 0; -+ size_t numNewBufBytes; -+ -+ // Get visual Info -+ XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs); -+ visInfo.visualid = wndattribs.visual->visualid; -+ int nvisuals = 0; -+ XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals); -+ if (nvisuals != 1) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual"); -+ return false; -+ } -+ visInfo = visuals[0]; -+ XFree(visuals); -+ -+ depth = visInfo.depth; -+ vis = visInfo.visual; -+ -+ if (depth < 15) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth"); -+ return false; -+ } -+ -+ rRatio = vis->red_mask / 255.0; -+ gRatio = vis->green_mask / 255.0; -+ bRatio = vis->blue_mask / 255.0; -+ -+ CTexture iconTexture; -+ iconTexture.LoadFromFile("special://xbmc/media/icon256x256.png"); -+ buf = iconTexture.GetPixels(); -+ -+ numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; -+ -+ if (depth>=24) -+ numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ else -+ numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ -+ newBuf = (uint32_t*)malloc(numNewBufBytes); -+ if (!newBuf) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed"); -+ return false; -+ } -+ -+ for (i=0; ired_mask; -+ g &= vis->green_mask; -+ b &= vis->blue_mask; -+ newBuf[outIndex] = r | g | b; -+ ++outIndex; -+ } -+ } -+ img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, -+ iconTexture.GetWidth(), iconTexture.GetHeight(), -+ (depth>=24)?32:16, 0); -+ if (!img) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image"); -+ free(newBuf); -+ return false; -+ } -+ if (!XInitImage(img)) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed"); -+ XDestroyImage(img); -+ return false; -+ } -+ -+ // set byte order -+ union -+ { -+ char c[sizeof(short)]; -+ short s; -+ } order; -+ order.s = 1; -+ if ((1 == order.c[0])) -+ { -+ img->byte_order = LSBFirst; -+ } -+ else -+ { -+ img->byte_order = MSBFirst; -+ } -+ -+ // create icon pixmap from image -+ m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth); -+ GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL); -+ XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height); -+ XFreeGC(m_dpy, gc); -+ XDestroyImage(img); // this also frees newBuf -+ -+ return true; -+} -+ - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 34b912f..352e90e 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -79,6 +79,7 @@ protected: - GLXContext m_glContext; - Display* m_dpy; - Cursor m_invisibleCursor; -+ Pixmap m_icon; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -@@ -90,7 +91,7 @@ protected: - private: - bool IsSuitableVisual(XVisualInfo *vInfo); - static int XErrorHandler(Display* dpy, XErrorEvent* error); -- void SetGrabMode(const CSetting *setting = NULL); -+ bool CreateIconPixmap(); - - CStopWatch m_screensaverReset; - }; --- -1.9.1 - - -From 66e95a677c6705dcbf031610fa2f3dbf5d15efbe Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 10/96] X11: add SDL joystick until we have a better solution - ---- - xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index ad58aad..6f57a87 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -35,6 +35,10 @@ - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -+#ifdef HAS_SDL_JOYSTICK -+#include "input/SDLJoystick.h" -+#endif -+ - CWinEventsX11Imp* CWinEventsX11Imp::WinEvents = 0; - - static uint32_t SymMappingsX11[][2] = -@@ -556,6 +560,28 @@ bool CWinEventsX11Imp::MessagePump() - - ret |= ProcessKeyRepeat(); - -+#ifdef HAS_SDL_JOYSTICK -+ SDL_Event event; -+ while (SDL_PollEvent(&event)) -+ { -+ switch(event.type) -+ { -+ case SDL_JOYBUTTONUP: -+ case SDL_JOYBUTTONDOWN: -+ case SDL_JOYAXISMOTION: -+ case SDL_JOYBALLMOTION: -+ case SDL_JOYHATMOTION: -+ g_Joystick.Update(event); -+ ret = true; -+ break; -+ -+ default: -+ break; -+ } -+ memset(&event, 0, sizeof(SDL_Event)); -+ } -+#endif -+ - return ret; - } - --- -1.9.1 - - -From 3f976cfab6a42dd7232464c7a366f4e6fa43b19f Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 11/96] X11: factor out code handling device reset notification - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 22 ++++++++++++++-------- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 15 insertions(+), 8 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 858ea5e..304dac8 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -533,14 +533,7 @@ void CWinSystemX11::CheckDisplayEvents() - - if (bGotEvent || bTimeout) - { -- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -- RefreshWindow(); -- -- CSingleLock lock(m_resourceSection); -- -- // tell any shared resources -- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -- (*i)->OnResetDevice(); -+ NotifyXRREvent(); - - // reset fail safe timer - m_dpyLostTime = 0; -@@ -548,6 +541,19 @@ void CWinSystemX11::CheckDisplayEvents() - #endif - } - -+void CWinSystemX11::NotifyXRREvent() -+{ -+ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -+ RefreshWindow(); -+ -+ CSingleLock lock(m_resourceSection); -+ -+ // tell any shared resources -+ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -+ (*i)->OnResetDevice(); -+ -+} -+ - void CWinSystemX11::OnLostDevice() - { - CLog::Log(LOGDEBUG, "%s - notify display change event", __FUNCTION__); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 352e90e..3f91b9b 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -68,6 +68,7 @@ public: - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } - void RefreshWindow(); -+ void NotifyXRREvent(); - - protected: - bool RefreshGlxContext(); --- -1.9.1 - - -From ff1ddbc3986fb6e541d9850c4e51321fed42dab8 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 12/96] X11: move xrandr events to WinEventsX11 - ---- - xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++++ - xbmc/windowing/WinEventsX11.h | 5 +++++ - xbmc/windowing/X11/WinSystemX11.cpp | 6 +++++- - 3 files changed, 52 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 6f57a87..d77cb2a 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -35,6 +35,10 @@ - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -+#if defined(HAS_XRANDR) -+#include -+#endif -+ - #ifdef HAS_SDL_JOYSTICK - #include "input/SDLJoystick.h" - #endif -@@ -212,6 +216,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -+ WinEvents->m_xrrEventPending = false; - memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - - // open input method -@@ -275,6 +280,13 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; - } - -+ // register for xrandr events -+#if defined(HAS_XRANDR) -+ int iReturn; -+ XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); -+ XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); -+#endif -+ - return true; - } - -@@ -297,6 +309,15 @@ bool CWinEventsX11Imp::HasStructureChanged() - return ret; - } - -+void CWinEventsX11Imp::SetXRRFailSafeTimer(int millis) -+{ -+ if (!WinEvents) -+ return; -+ -+ WinEvents->m_xrrFailSafeTimer.Set(millis); -+ WinEvents->m_xrrEventPending = true; -+} -+ - bool CWinEventsX11Imp::MessagePump() - { - if (!WinEvents) -@@ -556,10 +577,31 @@ bool CWinEventsX11Imp::MessagePump() - break; - } - }// switch event.type -+ -+#if defined(HAS_XRANDR) -+ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) -+ { -+ XRRUpdateConfiguration(&xevent); -+ if (xevent.xgeneric.serial != serial) -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ serial = xevent.xgeneric.serial; -+ } -+#endif -+ - }// while - - ret |= ProcessKeyRepeat(); - -+#if defined(HAS_XRANDR) -+ if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) -+ { -+ CLog::Log(LOGERROR,"CWinEventsX11::MessagePump - missed XRR Events"); -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ } -+#endif -+ - #ifdef HAS_SDL_JOYSTICK - SDL_Event event; - while (SDL_PollEvent(&event)) -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index ce57c23..a412f32 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -40,6 +40,8 @@ public: - static bool Init(Display *dpy, Window win); - static void Quit(); - static bool HasStructureChanged(); -+ static void PendingResize(int width, int height); -+ static void SetXRRFailSafeTimer(int millis); - static bool MessagePump(); - static size_t GetQueueSize(); - -@@ -62,4 +64,7 @@ protected: - std::map m_symLookupTable; - int m_keymodState; - bool m_structureChanged; -+ int m_RREventBase; -+ XbmcThreads::EndTime m_xrrFailSafeTimer; -+ bool m_xrrEventPending; - }; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 304dac8..16b13aa 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -510,7 +510,7 @@ bool CWinSystemX11::Show(bool raise) - - void CWinSystemX11::CheckDisplayEvents() - { --#if defined(HAS_XRANDR) -+#if defined(HAS_XRANDR) && defined(HAS_SDL_VIDEO_X11) - bool bGotEvent(false); - bool bTimeout(false); - XEvent Event; -@@ -566,8 +566,12 @@ void CWinSystemX11::OnLostDevice() - (*i)->OnLostDevice(); - } - -+#if defined(HAS_SDL_VIDEO_X11) - // fail safe timer - m_dpyLostTime = CurrentHostCounter(); -+#else -+ CWinEventsX11Imp::SetXRRFailSafeTimer(3000); -+#endif - } - - void CWinSystemX11::Register(IDispResource *resource) --- -1.9.1 - - -From 3a1d2d126d78b438efa6da902b41fb4f65866dd0 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 13/96] xrandr: remove method RestoreState - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++-- - xbmc/windowing/X11/XRandR.cpp | 19 ------------------- - xbmc/windowing/X11/XRandR.h | 1 - - 3 files changed, 11 insertions(+), 22 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 16b13aa..f61d425 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -80,9 +80,18 @@ bool CWinSystemX11::InitWindowSystem() - bool CWinSystemX11::DestroyWindowSystem() - { - #if defined(HAS_XRANDR) -- //restore videomode on exit -+ //restore desktop resolution on exit - if (m_bFullScreen) -- g_xrandr.RestoreState(); -+ { -+ XOutput out; -+ XMode mode; -+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ g_xrandr.SetMode(out, mode); -+ } - #endif - - if (m_dpy) -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 0ac17ab..7e06655 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -139,25 +139,6 @@ void CXRandR::SaveState() - Query(true); - } - --void CXRandR::RestoreState() --{ -- vector::iterator outiter; -- for (outiter=m_current.begin() ; outiter!=m_current.end() ; outiter++) -- { -- vector modes = (*outiter).modes; -- vector::iterator modeiter; -- for (modeiter=modes.begin() ; modeiter!=modes.end() ; modeiter++) -- { -- XMode mode = *modeiter; -- if (mode.isCurrent) -- { -- SetMode(*outiter, mode); -- return; -- } -- } -- } --} -- - bool CXRandR::SetMode(XOutput output, XMode mode) - { - if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 0aec487..00b49dc 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -99,7 +99,6 @@ public: - bool SetMode(XOutput output, XMode mode); - void LoadCustomModeLinesToAllOutputs(void); - void SaveState(); -- void RestoreState(); - //bool Has1080i(); - //bool Has1080p(); - //bool Has720p(); --- -1.9.1 - - -From 17b89c5e0ee97f7a162ba8c0f46c6efeb11fdd24 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 14/96] xrandr: observe orientation - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 89 ++++++++++++++++++++++++++++++------- - xbmc/windowing/X11/WinSystemX11.h | 2 + - xbmc/windowing/X11/XRandR.cpp | 7 +++ - xbmc/windowing/X11/XRandR.h | 1 + - 4 files changed, 82 insertions(+), 17 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index f61d425..4257aeb 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -85,11 +85,11 @@ bool CWinSystemX11::DestroyWindowSystem() - { - XOutput out; - XMode mode; -- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput; -+ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth; -+ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight; -+ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate; -+ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; - g_xrandr.SetMode(out, mode); - } - #endif -@@ -173,25 +173,34 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - - void CWinSystemX11::RefreshWindow() - { -- g_xrandr.Query(true); -+ if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } - XOutput out = g_xrandr.GetCurrentOutput(); - XMode mode = g_xrandr.GetCurrentMode(out.name); - -+ RotateResolutions(); -+ - // only overwrite desktop resolution, if we are not in fullscreen mode - if (!g_graphicsContext.IsFullScreenVideo()) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -- g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; -- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; -+ if (!out.isRotated) -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -+ else -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); -+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; -+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; - } - - RESOLUTION_INFO res; - unsigned int i; - bool found(false); -- for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) -+ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) - { -- if (g_settings.m_ResInfo[i].strId == mode.id) -+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) - { - found = true; - break; -@@ -227,16 +236,24 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - else - { -- out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -- mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -- mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -- mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -- mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ out.name = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput; -+ mode.w = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iWidth; -+ mode.h = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).iHeight; -+ mode.hz = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).fRefreshRate; -+ mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; - } - - XOutput currout = g_xrandr.GetCurrentOutput(); - XMode currmode = g_xrandr.GetCurrentMode(currout.name); - -+ // flip h/w when rotated -+ if (m_bIsRotated) -+ { -+ int w = mode.w; -+ mode.w = mode.h; -+ mode.h = w; -+ } -+ - // only call xrandr if mode changes - if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || - currmode.hz != mode.hz || currmode.id != mode.id) -@@ -269,7 +286,11 @@ void CWinSystemX11::UpdateResolutions() - { - XOutput out = g_xrandr.GetCurrentOutput(); - XMode mode = g_xrandr.GetCurrentMode(out.name); -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -+ m_bIsRotated = out.isRotated; -+ if (!m_bIsRotated) -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -+ else -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; - } -@@ -308,6 +329,16 @@ void CWinSystemX11::UpdateResolutions() - res.iHeight = mode.h; - res.iScreenWidth = mode.w; - res.iScreenHeight = mode.h; -+ if (!m_bIsRotated) -+ { -+ res.iWidth = mode.w; -+ res.iHeight = mode.h; -+ } -+ else -+ { -+ res.iWidth = mode.h; -+ res.iHeight = mode.w; -+ } - if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) - res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); - else -@@ -335,6 +366,30 @@ void CWinSystemX11::UpdateResolutions() - - } - -+void CWinSystemX11::RotateResolutions() -+{ -+#if defined(HAS_XRANDR) -+ XOutput out = g_xrandr.GetCurrentOutput(); -+ if (out.isRotated == m_bIsRotated) -+ return; -+ -+ for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) -+ { -+ int width = CDisplaySettings::Get().GetResolutionInfo(i).iWidth; -+ CDisplaySettings::Get().GetResolutionInfo(i).iWidth = CDisplaySettings::Get().GetResolutionInfo(i).iHeight; -+ CDisplaySettings::Get().GetResolutionInfo(i).iHeight = width; -+ } -+ // update desktop resolution -+// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); -+ -+ m_bIsRotated = out.isRotated; -+ -+#endif -+} -+ - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - { - int value; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 3f91b9b..4175aab 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -75,12 +75,14 @@ protected: - void CheckDisplayEvents(); - void OnLostDevice(); - bool SetWindow(int width, int height, bool fullscreen); -+ void RotateResolutions(); - - Window m_glWindow; - GLXContext m_glContext; - Display* m_dpy; - Cursor m_invisibleCursor; - Pixmap m_icon; -+ bool m_bIsRotated; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 7e06655..330e945 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -98,6 +98,13 @@ bool CXRandR::Query(bool force) - xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); - xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); - xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); -+ if (output->Attribute("rotation") != NULL -+ && (strcasecmp(output->Attribute("rotation"), "left") == 0 || strcasecmp(output->Attribute("rotation"), "right") == 0)) -+ { -+ xoutput.isRotated = true; -+ } -+ else -+ xoutput.isRotated = false; - - if (!xoutput.isConnected) - continue; -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 00b49dc..508604d 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -86,6 +86,7 @@ public: - int wmm; - int hmm; - std::vector modes; -+ bool isRotated; - }; - - class CXRandR --- -1.9.1 - - -From 50b8649389095c3b80ed2d698630eaf95fc9218e Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 15/96] xrandr: allow getting info for multiple screen's - -Refactored by: Joakim Plate ---- - xbmc/windowing/X11/XRandR.cpp | 65 +++++++++++++++++++++++++++++++++---------- - xbmc/windowing/X11/XRandR.h | 8 ++++-- - 2 files changed, 57 insertions(+), 16 deletions(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 330e945..4685413 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -40,6 +40,7 @@ using namespace std; - CXRandR::CXRandR(bool query) - { - m_bInit = false; -+ m_numScreens = 1; - if (query) - Query(); - } -@@ -56,11 +57,21 @@ bool CXRandR::Query(bool force) - return false; - - m_outputs.clear(); -- m_current.clear(); -+ // query all screens -+ for(unsigned int screennum=0; screennumValue(), "screen") != 0) -+ if (strcasecmp(pRootElement->Value(), "screen") != screennum) - { - // TODO ERROR - return false; -@@ -92,6 +103,7 @@ bool CXRandR::Query(bool force) - xoutput.name = output->Attribute("name"); - StringUtils::Trim(xoutput.name); - xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0); -+ xoutput.screen = screennum; - xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0); - xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); - xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); -@@ -123,7 +135,6 @@ bool CXRandR::Query(bool force) - xoutput.modes.push_back(xmode); - if (xmode.isCurrent) - { -- m_current.push_back(xoutput); - hascurrent = true; - } - } -@@ -247,17 +258,6 @@ bool CXRandR::SetMode(XOutput output, XMode mode) - return true; - } - --XOutput CXRandR::GetCurrentOutput() --{ -- Query(); -- for (unsigned int j = 0; j < m_outputs.size(); j++) -- { -- if(m_outputs[j].isConnected) -- return m_outputs[j]; -- } -- XOutput empty; -- return empty; --} - XMode CXRandR::GetCurrentMode(CStdString outputName) - { - Query(); -@@ -329,6 +329,43 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void) - } - } - -+void CXRandR::SetNumScreens(unsigned int num) -+{ -+ m_numScreens = num; -+ m_bInit = false; -+} -+ -+bool CXRandR::IsOutputConnected(CStdString name) -+{ -+ bool result = false; -+ Query(); -+ -+ for (unsigned int i = 0; i < m_outputs.size(); ++i) -+ { -+ if (m_outputs[i].name == name) -+ { -+ result = true; -+ break; -+ } -+ } -+ return result; -+} -+ -+XOutput* CXRandR::GetOutput(CStdString outputName) -+{ -+ XOutput *result = 0; -+ Query(); -+ for (unsigned int i = 0; i < m_outputs.size(); ++i) -+ { -+ if (m_outputs[i].name == outputName) -+ { -+ result = &m_outputs[i]; -+ break; -+ } -+ } -+ return result; -+} -+ - CXRandR g_xrandr; - - #endif // HAS_XRANDR -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 508604d..d37838a 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -79,6 +79,7 @@ public: - } - CStdString name; - bool isConnected; -+ int screen; - int w; - int h; - int x; -@@ -94,12 +95,15 @@ class CXRandR - public: - CXRandR(bool query=false); - bool Query(bool force=false); -+ bool Query(bool force, int screennum); - std::vector GetModes(void); -- XOutput GetCurrentOutput(); - XMode GetCurrentMode(CStdString outputName); -+ XOutput *GetOutput(CStdString outputName); - bool SetMode(XOutput output, XMode mode); - void LoadCustomModeLinesToAllOutputs(void); - void SaveState(); -+ void SetNumScreens(unsigned int num); -+ bool IsOutputConnected(CStdString name); - //bool Has1080i(); - //bool Has1080p(); - //bool Has720p(); -@@ -107,10 +111,10 @@ public: - - private: - bool m_bInit; -- std::vector m_current; - std::vector m_outputs; - CStdString m_currentOutput; - CStdString m_currentMode; -+ unsigned int m_numScreens; - }; - - extern CXRandR g_xrandr; --- -1.9.1 - - -From 1c4250942d2478de4241bfd7f54b627faf476824 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 16/96] X11: fix multi-head setups - ---- - language/English/strings.po | 4 +- - system/settings/settings.xml | 11 ++ - xbmc/rendering/gl/RenderSystemGL.h | 1 + - xbmc/settings/DisplaySettings.cpp | 44 ++++++- - xbmc/settings/DisplaySettings.h | 2 + - xbmc/settings/Settings.cpp | 6 + - xbmc/windowing/WinEventsX11.cpp | 7 + - xbmc/windowing/X11/WinSystemX11.cpp | 255 +++++++++++++++++++++--------------- - xbmc/windowing/X11/WinSystemX11.h | 10 +- - 9 files changed, 227 insertions(+), 113 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 616a321..685847c 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -1021,7 +1021,9 @@ msgctxt "#245" - msgid "Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1) (VShift: %2.2f)" - msgstr "" - --#empty string with id 246 -+msgctxt "#246" -+msgid "Monitor" -+msgstr "" - - msgctxt "#247" - msgid "Scripts" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index f92bd59..fba4561 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2251,6 +2251,15 @@ -
- - -+ -+ HAS_GLX -+ 0 -+ Default -+ -+ monitors -+ -+ -+ - - 0 - 0 -@@ -2272,6 +2281,7 @@ - -1 - - -+ - - - -@@ -2289,6 +2299,7 @@ - -1 - - -+ - - - -diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h -index 4bd540b..f1e2c50 100644 ---- a/xbmc/rendering/gl/RenderSystemGL.h -+++ b/xbmc/rendering/gl/RenderSystemGL.h -@@ -44,6 +44,7 @@ public: - virtual bool IsExtSupported(const char* extension); - - virtual void SetVSync(bool vsync); -+ virtual void ResetVSync() { m_bVsyncInit = false; } - - virtual void SetViewPort(CRect& viewPort); - virtual void GetViewPort(CRect& viewPort); -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index daa1b18..db2f667 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -219,7 +219,8 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - - const std::string &settingId = setting->GetId(); - if (settingId == "videoscreen.resolution" || -- settingId == "videoscreen.screen") -+ settingId == "videoscreen.screen" || -+ settingId == "videoscreen.monitor") - { - RESOLUTION newRes = RES_DESKTOP; - if (settingId == "videoscreen.resolution") -@@ -235,6 +236,11 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - // get desktop resolution for screen - newRes = GetResolutionForScreen(); - } -+ else if (settingId == "videoscreen.monitor") -+ { -+ g_Windowing.UpdateResolutions(); -+ newRes = GetResolutionForScreen(); -+ } - - string screenmode = GetStringFromResolution(newRes); - CSettings::Get().SetString("videoscreen.screenmode", screenmode); -@@ -245,7 +251,11 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue()); - - SetCurrentResolution(newRes, false); -- g_graphicsContext.SetVideoResolution(newRes); -+ bool outputChanged = false; -+#if defined(HAS_GLX) -+ outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor")); -+#endif -+ g_graphicsContext.SetVideoResolution(newRes, outputChanged); - - // check if the old or the new resolution was/is windowed - // in which case we don't show any prompt to the user -@@ -641,6 +651,10 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std: - if (g_advancedSettings.m_canWindowed) - list.push_back(make_pair(g_localizeStrings.Get(242), DM_WINDOWED)); - -+#if defined(HAS_GLX) -+ list.push_back(make_pair(g_localizeStrings.Get(244), 0)); -+#else -+ - for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++) - { - int screen = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP + idx).iScreen; -@@ -655,6 +669,7 @@ void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std: - RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res); - current = resInfo.iScreen; - } -+#endif - } - - void CDisplaySettings::SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t) -@@ -683,3 +698,28 @@ void CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller(const - SettingOptionsStereoscopicModesFiller(setting, list, current); - list.push_back(make_pair(g_localizeStrings.Get(36525), RENDER_STEREO_MODE_AUTO)); // option for autodetect - } -+ -+void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t) -+{ -+#if defined(HAS_GLX) -+ std::vector monitors; -+ g_Windowing.GetConnectedOutputs(&monitors); -+ for (unsigned int i=0; i RES_CUSTOM) -+ { -+ std::vector::iterator firstCustom = m_resolutions.begin()+RES_CUSTOM; -+ m_resolutions.erase(firstCustom, m_resolutions.end()); -+ } -+} -diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h -index 8ee1be2..bead24b 100644 ---- a/xbmc/settings/DisplaySettings.h -+++ b/xbmc/settings/DisplaySettings.h -@@ -78,6 +78,7 @@ public: - - void ApplyCalibrations(); - void UpdateCalibrations(); -+ void ClearCustomResolutions(); - - float GetZoomAmount() const { return m_zoomAmount; } - void SetZoomAmount(float zoomAmount) { m_zoomAmount = zoomAmount; } -@@ -95,6 +96,7 @@ public: - static void SettingOptionsVerticalSyncsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); - static void SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); - static void SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t); -+ static void SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair > &list, std::string ¤t); - - protected: - CDisplaySettings(); -diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp -index d8d50ea..013adf9 100644 ---- a/xbmc/settings/Settings.cpp -+++ b/xbmc/settings/Settings.cpp -@@ -406,6 +406,7 @@ void CSettings::Uninitialize() - m_settingsManager->UnregisterSettingOptionsFiller("screens"); - m_settingsManager->UnregisterSettingOptionsFiller("stereoscopicmodes"); - m_settingsManager->UnregisterSettingOptionsFiller("preferedstereoscopicviewmodes"); -+ m_settingsManager->UnregisterSettingOptionsFiller("monitors"); - m_settingsManager->UnregisterSettingOptionsFiller("shutdownstates"); - m_settingsManager->UnregisterSettingOptionsFiller("startupwindows"); - m_settingsManager->UnregisterSettingOptionsFiller("streamlanguages"); -@@ -835,6 +836,7 @@ void CSettings::InitializeOptionFillers() - m_settingsManager->RegisterSettingOptionsFiller("screens", CDisplaySettings::SettingOptionsScreensFiller); - m_settingsManager->RegisterSettingOptionsFiller("stereoscopicmodes", CDisplaySettings::SettingOptionsStereoscopicModesFiller); - m_settingsManager->RegisterSettingOptionsFiller("preferedstereoscopicviewmodes", CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller); -+ m_settingsManager->RegisterSettingOptionsFiller("monitors", CDisplaySettings::SettingOptionsMonitorsFiller); - m_settingsManager->RegisterSettingOptionsFiller("shutdownstates", CPowerManager::SettingOptionsShutdownStatesFiller); - m_settingsManager->RegisterSettingOptionsFiller("startupwindows", ADDON::CSkinInfo::SettingOptionsStartupWindowsFiller); - m_settingsManager->RegisterSettingOptionsFiller("streamlanguages", CLangInfo::SettingOptionsStreamLanguagesFiller); -@@ -868,6 +870,9 @@ void CSettings::InitializeConditions() - #ifdef HAS_GL - m_settingsManager->AddCondition("has_gl"); - #endif -+#ifdef HAS_GLX -+ m_settingsManager->AddCondition("has_glx"); -+#endif - #ifdef HAS_GLES - m_settingsManager->AddCondition("has_gles"); - #endif -@@ -1021,6 +1026,7 @@ void CSettings::InitializeISettingCallbacks() - settingSet.insert("videoscreen.resolution"); - settingSet.insert("videoscreen.screenmode"); - settingSet.insert("videoscreen.vsync"); -+ settingSet.insert("videoscreen.monitor"); - m_settingsManager->RegisterCallback(&CDisplaySettings::Get(), settingSet); - - settingSet.clear(); -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index d77cb2a..d98f12f 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -526,9 +526,16 @@ bool CWinEventsX11Imp::MessagePump() - break; - } - -+ case EnterNotify: -+ { -+ g_Windowing.NotifyMouseCoverage(true); -+ break; -+ } -+ - // lose mouse coverage - case LeaveNotify: - { -+ g_Windowing.NotifyMouseCoverage(false); - g_Mouse.SetActive(false); - break; - } -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 4257aeb..5e86772 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -36,6 +36,8 @@ - #include "cores/VideoRenderers/RenderManager.h" - #include "utils/TimeUtils.h" - #include "utils/StringUtils.h" -+#include "settings/Settings.h" -+#include "windowing/WindowingFactory.h" - - #if defined(HAS_XRANDR) - #include -@@ -57,6 +59,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase() - m_bIgnoreNextFocusMessage = false; - m_dpyLostTime = 0; - m_invisibleCursor = 0; -+ m_bIsInternalXrr = false; - - XSetErrorHandler(XErrorHandler); - } -@@ -69,7 +72,8 @@ bool CWinSystemX11::InitWindowSystem() - { - if ((m_dpy = XOpenDisplay(NULL))) - { -- return CWinSystemBase::InitWindowSystem(); -+ bool ret = CWinSystemBase::InitWindowSystem(); -+ return ret; - } - else - CLog::Log(LOGERROR, "GLX Error: No Display found"); -@@ -106,6 +110,8 @@ bool CWinSystemX11::DestroyWindowSystem() - - //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy - //so instead we just let m_dpy die on exit -+ // i have seen core dumps on ATI if the display is not closed here -+ XCloseDisplay(m_dpy); - } - - // m_SDLSurface is free()'d by SDL_Quit(). -@@ -128,7 +134,10 @@ bool CWinSystemX11::DestroyWindow() - return true; - - if (m_glContext) -+ { -+ glFinish(); - glXMakeCurrent(m_dpy, None, NULL); -+ } - - if (m_invisibleCursor) - { -@@ -158,7 +167,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - && m_nHeight == newHeight) - return true; - -- if (!SetWindow(newWidth, newHeight, false)) -+ if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor"))) - { - return false; - } -@@ -167,58 +176,11 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - m_nWidth = newWidth; - m_nHeight = newHeight; - m_bFullScreen = false; -+ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); - - return false; - } - --void CWinSystemX11::RefreshWindow() --{ -- if (!g_xrandr.Query(true)) -- { -- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -- return; -- } -- XOutput out = g_xrandr.GetCurrentOutput(); -- XMode mode = g_xrandr.GetCurrentMode(out.name); -- -- RotateResolutions(); -- -- // only overwrite desktop resolution, if we are not in fullscreen mode -- if (!g_graphicsContext.IsFullScreenVideo()) -- { -- CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -- if (!out.isRotated) -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -- else -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); -- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; -- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; -- } -- -- RESOLUTION_INFO res; -- unsigned int i; -- bool found(false); -- for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) -- { -- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) -- { -- found = true; -- break; -- } -- } -- -- if (!found) -- { -- CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -- return; -- } -- -- if (g_graphicsContext.IsFullScreenRoot()) -- g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -- else -- g_graphicsContext.SetVideoResolution(RES_WINDOW, true); --} -- - bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { - -@@ -243,8 +205,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - mode.id = CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId; - } - -- XOutput currout = g_xrandr.GetCurrentOutput(); -- XMode currmode = g_xrandr.GetCurrentMode(currout.name); -+ XMode currmode = g_xrandr.GetCurrentMode(out.name); - - // flip h/w when rotated - if (m_bIsRotated) -@@ -255,16 +216,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - - // only call xrandr if mode changes -- if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || -+ if (currmode.w != mode.w || currmode.h != mode.h || - currmode.hz != mode.hz || currmode.id != mode.id) - { - CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); - OnLostDevice(); -+ m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); - } - #endif - -- if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) -+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) - return false; - - RefreshGlxContext(); -@@ -272,6 +234,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_bFullScreen = fullScreen; -+ m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); - - return true; - } -@@ -280,19 +243,30 @@ void CWinSystemX11::UpdateResolutions() - { - CWinSystemBase::UpdateResolutions(); - -- - #if defined(HAS_XRANDR) -- if(g_xrandr.Query()) -- { -- XOutput out = g_xrandr.GetCurrentOutput(); -- XMode mode = g_xrandr.GetCurrentMode(out.name); -- m_bIsRotated = out.isRotated; -+ CStdString currentMonitor; -+ int numScreens = XScreenCount(m_dpy); -+ g_xrandr.SetNumScreens(numScreens); -+ if(g_xrandr.Query(true)) -+ { -+ currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); -+ // check if the monitor is connected -+ XOutput *out = g_xrandr.GetOutput(currentMonitor); -+ if (!out) -+ { -+ // choose first output -+ currentMonitor = g_xrandr.GetModes()[0].name; -+ out = g_xrandr.GetOutput(currentMonitor); -+ CSettings::Get().SetString("videoscreen.monitor", currentMonitor); -+ } -+ XMode mode = g_xrandr.GetCurrentMode(currentMonitor); -+ m_bIsRotated = out->isRotated; - if (!m_bIsRotated) -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz); - else -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz); - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; -- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = out.name; -+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; - } - else - #endif -@@ -303,23 +277,22 @@ void CWinSystemX11::UpdateResolutions() - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); - } - -- - #if defined(HAS_XRANDR) - -+ // erase previous stored modes -+ CDisplaySettings::Get().ClearCustomResolutions(); -+ - CLog::Log(LOGINFO, "Available videomodes (xrandr):"); -- vector::iterator outiter; -- vector outs; -- outs = g_xrandr.GetModes(); -- CLog::Log(LOGINFO, "Number of connected outputs: %"PRIdS"", outs.size()); -+ -+ XOutput *out = g_xrandr.GetOutput(currentMonitor); - string modename = ""; - -- for (outiter = outs.begin() ; outiter != outs.end() ; outiter++) -+ if (out != NULL) - { -- XOutput out = *outiter; - vector::iterator modeiter; -- CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out.name.c_str(), out.modes.size()); -+ CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out->name.c_str(), out->modes.size()); - -- for (modeiter = out.modes.begin() ; modeiter!=out.modes.end() ; modeiter++) -+ for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++) - { - XMode mode = *modeiter; - CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", -@@ -339,8 +312,8 @@ void CWinSystemX11::UpdateResolutions() - res.iWidth = mode.h; - res.iHeight = mode.w; - } -- if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) -- res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); -+ if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0) -+ res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h)); - else - res.fPixelRatio = 1.0f; - -@@ -366,28 +339,19 @@ void CWinSystemX11::UpdateResolutions() - - } - --void CWinSystemX11::RotateResolutions() -+void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) - { --#if defined(HAS_XRANDR) -- XOutput out = g_xrandr.GetCurrentOutput(); -- if (out.isRotated == m_bIsRotated) -- return; -- -- for (unsigned int i = 0; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) -+ vector outs; -+ outs = g_xrandr.GetModes(); -+ for(unsigned int i=0; ipush_back(outs[i].name); - } -- // update desktop resolution --// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; --// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; --// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; --// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); -- -- m_bIsRotated = out.isRotated; -+} - --#endif -+bool CWinSystemX11::IsCurrentOutput(CStdString output) -+{ -+ return m_currentOutput.Equals(output); - } - - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) -@@ -417,8 +381,11 @@ bool CWinSystemX11::RefreshGlxContext() - if (m_glContext) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); -+ glFinish(); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -+ XSync(m_dpy, FALSE); -+ g_Windowing.ResetVSync(); - return true; - } - -@@ -484,6 +451,8 @@ bool CWinSystemX11::RefreshGlxContext() - { - // make this context current - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -+ g_Windowing.ResetVSync(); -+ XSync(m_dpy, False); - retVal = true; - } - else -@@ -525,24 +494,53 @@ void CWinSystemX11::ResetOSScreensaver() - - void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - { -- if (bActivated && m_bWasFullScreenBeforeMinimize && !g_graphicsContext.IsFullScreenRoot()) -+ if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) -+ { - g_graphicsContext.ToggleFullScreenRoot(); - -+ m_bWasFullScreenBeforeMinimize = false; -+ } - m_minimized = !bActivated; - } - - void CWinSystemX11::NotifyAppFocusChange(bool bGaining) - { - if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && -- !g_graphicsContext.IsFullScreenRoot()) -+ !m_bFullScreen) -+ { -+ m_bWasFullScreenBeforeMinimize = false; - g_graphicsContext.ToggleFullScreenRoot(); -+ m_minimized = false; -+ } - if (!bGaining) - m_bIgnoreNextFocusMessage = false; - } - -+void CWinSystemX11::NotifyMouseCoverage(bool covered) -+{ -+ if (!m_bFullScreen) -+ return; -+ -+ if (covered) -+ { -+ int result = -1; -+ while (result != GrabSuccess && result != AlreadyGrabbed) -+ { -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -+ XbmcThreads::ThreadSleep(100); -+ } -+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ } -+ else -+ { -+ XUngrabKeyboard(m_dpy, CurrentTime); -+ XUngrabPointer(m_dpy, CurrentTime); -+ } -+} -+ - bool CWinSystemX11::Minimize() - { -- m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); -+ m_bWasFullScreenBeforeMinimize = m_bFullScreen; - if (m_bWasFullScreenBeforeMinimize) - { - m_bIgnoreNextFocusMessage = true; -@@ -608,13 +606,46 @@ void CWinSystemX11::CheckDisplayEvents() - void CWinSystemX11::NotifyXRREvent() - { - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -- RefreshWindow(); -+ m_windowDirty = true; - -- CSingleLock lock(m_resourceSection); -+ // if external event update resolutions -+ if (!m_bIsInternalXrr) -+ { -+ UpdateResolutions(); -+ } -+ else if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } -+ m_bIsInternalXrr = false; - -- // tell any shared resources -- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -- (*i)->OnResetDevice(); -+ CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); -+ XOutput *out = g_xrandr.GetOutput(currentOutput); -+ XMode mode = g_xrandr.GetCurrentMode(currentOutput); -+ -+ RESOLUTION_INFO res; -+ unsigned int i; -+ bool found(false); -+ for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) -+ { -+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) -+ { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -+ i = RES_DESKTOP; -+ } -+ -+ if (g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -+ else -+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); - - } - -@@ -667,14 +698,14 @@ bool CWinSystemX11::EnableFrameLimiter() - return m_minimized; - } - --bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) -+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) - { - bool changeWindow = false; - bool changeSize = false; - bool mouseActive = false; - float mouseX, mouseY; - -- if (m_glWindow && (m_bFullScreen != fullscreen)) -+ if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) - { - mouseActive = g_Mouse.IsActive(); - if (mouseActive) -@@ -696,6 +727,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - else - mouseActive = false; - } -+ OnLostDevice(); - DestroyWindow(); - } - -@@ -717,7 +749,11 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - XSetWindowAttributes swa; - XVisualInfo *vi; - -- vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); -+ XOutput *out = g_xrandr.GetOutput(output); -+ if (!out) -+ out = g_xrandr.GetOutput(m_currentOutput); -+ m_nScreen = out->screen; -+ vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -@@ -733,7 +769,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; - - m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -- 0, 0, width, height, 0, vi->depth, -+ out->x, out->y, width, height, 0, vi->depth, - InputOutput, vi->visual, - mask, &swa); - -@@ -804,14 +840,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - if (fullscreen) - { - int result = -1; -- while (result != GrabSuccess) -+ while (result != GrabSuccess && result != AlreadyGrabbed) - { -- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - XbmcThreads::ThreadSleep(100); - } - XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -- - } -+ CSingleLock lock(m_resourceSection); -+ // tell any shared resources -+ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -+ (*i)->OnResetDevice(); -+ -+ m_windowDirty = false; - } - return true; - } -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 4175aab..94584ab 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -67,15 +67,16 @@ public: - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -- void RefreshWindow(); - void NotifyXRREvent(); -+ void GetConnectedOutputs(std::vector *outputs); -+ bool IsCurrentOutput(CStdString output); -+ void NotifyMouseCoverage(bool covered); - - protected: - bool RefreshGlxContext(); - void CheckDisplayEvents(); - void OnLostDevice(); -- bool SetWindow(int width, int height, bool fullscreen); -- void RotateResolutions(); -+ bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); - - Window m_glWindow; - GLXContext m_glContext; -@@ -90,6 +91,9 @@ protected: - CCriticalSection m_resourceSection; - std::vector m_resources; - uint64_t m_dpyLostTime; -+ CStdString m_currentOutput; -+ bool m_windowDirty; -+ bool m_bIsInternalXrr; - - private: - bool IsSuitableVisual(XVisualInfo *vInfo); --- -1.9.1 - - -From 42b6e1775d61778a57119471091900998ddf6d37 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 17/96] X11: remove all DefaultScreen and RootWindow macros - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- - xbmc/windowing/X11/WinSystemX11.h | 1 + - xbmc/windowing/X11/WinSystemX11GL.cpp | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 5e86772..c4fa17c 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -271,7 +271,7 @@ void CWinSystemX11::UpdateResolutions() - else - #endif - { -- int x11screen = DefaultScreen(m_dpy); -+ int x11screen = m_nScreen; - int w = DisplayWidth(m_dpy, x11screen); - int h = DisplayHeight(m_dpy, x11screen); - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); -@@ -393,7 +393,7 @@ bool CWinSystemX11::RefreshGlxContext() - XVisualInfo *visuals; - XVisualInfo *vInfo = NULL; - int availableVisuals = 0; -- vMask.screen = DefaultScreen(m_dpy); -+ vMask.screen = m_nScreen; - XWindowAttributes winAttr; - - /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() -@@ -547,7 +547,7 @@ bool CWinSystemX11::Minimize() - g_graphicsContext.ToggleFullScreenRoot(); - } - -- XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); -+ XIconifyWindow(m_dpy, m_glWindow, m_nScreen); - - m_minimized = true; - return true; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 94584ab..2bcaf52 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -49,6 +49,7 @@ public: - virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays); - virtual void UpdateResolutions(); - virtual int GetNumScreens() { return 1; } -+ virtual int GetCurrentScreen() { return m_nScreen; } - virtual void ShowOSMouse(bool show); - virtual void ResetOSScreensaver(); - virtual bool EnableFrameLimiter(); -diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp -index 6383754..21e7dc5 100644 ---- a/xbmc/windowing/X11/WinSystemX11GL.cpp -+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp -@@ -167,7 +167,7 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R - return false; - - m_glxext = " "; -- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy)); -+ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_nScreen); - m_glxext += " "; - - CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str()); --- -1.9.1 - - -From 227a92bca30d905570f4827cef6102b0ba5f1022 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 18/96] X11: remove all DefaultScreen and RootWindow macros - (VideoRefClock) - -Note this is on a separate display connection. ---- - xbmc/video/VideoReferenceClock.cpp | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 0b3950a..ca43b5a 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -271,7 +271,7 @@ bool CVideoReferenceClock::SetupGLX() - } - - bool ExtensionFound = false; -- istringstream Extensions(glXQueryExtensionsString(m_Dpy, DefaultScreen(m_Dpy))); -+ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); - string ExtensionStr; - - while (!ExtensionFound) -@@ -297,7 +297,7 @@ bool CVideoReferenceClock::SetupGLX() - m_bIsATI = true; - } - -- m_vInfo = glXChooseVisual(m_Dpy, DefaultScreen(m_Dpy), singleBufferAttributes); -+ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); - if (!m_vInfo) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); -@@ -308,15 +308,16 @@ bool CVideoReferenceClock::SetupGLX() - { - Swa.border_pixel = 0; - Swa.event_mask = StructureNotifyMask; -- Swa.colormap = XCreateColormap(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), m_vInfo->visual, AllocNone ); -+ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); - SwaMask = CWBorderPixel | CWColormap | CWEventMask; - -- m_Window = XCreateWindow(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), 0, 0, 256, 256, 0, -+ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, - m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); - } - else - { -- m_pixmap = XCreatePixmap(m_Dpy, DefaultRootWindow(m_Dpy), 256, 256, m_vInfo->depth); -+ Window window = g_Windowing.GetWindow(); -+ m_pixmap = XCreatePixmap(m_Dpy, window, 256, 256, m_vInfo->depth); - if (!m_pixmap) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: unable to create pixmap"); -@@ -383,7 +384,7 @@ bool CVideoReferenceClock::SetupGLX() - - //set up receiving of RandR events, we'll get one when the refreshrate changes - XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); -- XRRSelectInput(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), RRScreenChangeNotifyMask); -+ XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); - - UpdateRefreshrate(true); //forced refreshrate update - m_MissedVblanks = 0; -@@ -518,7 +519,7 @@ int CVideoReferenceClock::GetRandRRate() - int RefreshRate; - XRRScreenConfiguration *CurrInfo; - -- CurrInfo = XRRGetScreenInfo(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen)); -+ CurrInfo = XRRGetScreenInfo(m_Dpy, g_Windowing.GetWindow()); - RefreshRate = XRRConfigCurrentRate(CurrInfo); - XRRFreeScreenConfigInfo(CurrInfo); - --- -1.9.1 - - -From 9244c0ac286705cc5e8577138b219a25db3bdda3 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 19/96] X11: recreate gl context after output has changed - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++---------- - xbmc/windowing/X11/WinSystemX11.h | 1 + - xbmc/windowing/X11/WinSystemX11GL.cpp | 9 +++++++++ - 3 files changed, 24 insertions(+), 10 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c4fa17c..f2fd18d 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -172,7 +172,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - return false; - } - -- RefreshGlxContext(); - m_nWidth = newWidth; - m_nHeight = newHeight; - m_bFullScreen = false; -@@ -223,14 +222,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - OnLostDevice(); - m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); -+ return true; - } - #endif - - if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) - return false; - -- RefreshGlxContext(); -- - m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_bFullScreen = fullScreen; -@@ -381,11 +379,8 @@ bool CWinSystemX11::RefreshGlxContext() - if (m_glContext) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); -- glFinish(); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -- XSync(m_dpy, FALSE); -- g_Windowing.ResetVSync(); - return true; - } - -@@ -445,14 +440,14 @@ bool CWinSystemX11::RefreshGlxContext() - { - glXMakeCurrent(m_dpy, None, NULL); - glXDestroyContext(m_dpy, m_glContext); -+ XSync(m_dpy, FALSE); -+ m_newGlContext = true; - } - - if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True))) - { - // make this context current - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -- g_Windowing.ResetVSync(); -- XSync(m_dpy, False); - retVal = true; - } - else -@@ -729,6 +724,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - OnLostDevice(); - DestroyWindow(); -+ m_windowDirty = true; - } - - // create main window -@@ -847,13 +843,21 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } -+ -+ CDirtyRegionList dr; -+ RefreshGlxContext(); -+ XSync(m_dpy, FALSE); -+ g_graphicsContext.Clear(0); -+ g_graphicsContext.Flip(dr); -+ g_Windowing.ResetVSync(); -+ m_windowDirty = false; -+ - CSingleLock lock(m_resourceSection); - // tell any shared resources - for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) - (*i)->OnResetDevice(); -- -- m_windowDirty = false; - } -+ - return true; - } - -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 2bcaf52..9666cc3 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -95,6 +95,7 @@ protected: - CStdString m_currentOutput; - bool m_windowDirty; - bool m_bIsInternalXrr; -+ bool m_newGlContext; - - private: - bool IsSuitableVisual(XVisualInfo *vInfo); -diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp -index 21e7dc5..8e68d5d 100644 ---- a/xbmc/windowing/X11/WinSystemX11GL.cpp -+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp -@@ -24,6 +24,7 @@ - #include "WinSystemX11GL.h" - #include "utils/log.h" - #include "utils/StringUtils.h" -+#include "Application.h" - - CWinSystemX11GL::CWinSystemX11GL() - { -@@ -197,17 +198,25 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R - - bool CWinSystemX11GL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) - { -+ m_newGlContext = false; - CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop); - CRenderSystemGL::ResetRenderSystem(newWidth, newHeight, false, 0); - -+ if (m_newGlContext) -+ g_application.ReloadSkin(); -+ - return true; - } - - bool CWinSystemX11GL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { -+ m_newGlContext = false; - CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays); - CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate); - -+ if (m_newGlContext) -+ g_application.ReloadSkin(); -+ - return true; - } - --- -1.9.1 - - -From b3587cc41599e6bd73bd54a58f59118d1edfced4 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 20/96] X11: hook video reference clock in windowing - ---- - xbmc/video/VideoReferenceClock.cpp | 71 +++++++++++++++++++++++++++----------- - xbmc/video/VideoReferenceClock.h | 13 ++++++- - 2 files changed, 63 insertions(+), 21 deletions(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index ca43b5a..0ddf102 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -136,12 +136,23 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") - m_Context = NULL; - m_pixmap = None; - m_glPixmap = None; -- m_RREventBase = 0; - m_UseNvSettings = true; - m_bIsATI = false; - #endif - } - -+CVideoReferenceClock::~CVideoReferenceClock() -+{ -+#if defined(HAS_GLX) -+ // some ATI voodoo, if we don't close the display, we crash on exit -+ if (m_Dpy) -+ { -+ XCloseDisplay(m_Dpy); -+ m_Dpy = NULL; -+ } -+#endif -+} -+ - void CVideoReferenceClock::Process() - { - bool SetupSuccess = false; -@@ -152,6 +163,10 @@ void CVideoReferenceClock::Process() - m_D3dCallback.Reset(); - g_Windowing.Register(&m_D3dCallback); - #endif -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ g_Windowing.Register(this); -+ m_xrrEvent = false; -+#endif - - while(!m_bStop) - { -@@ -212,6 +227,16 @@ void CVideoReferenceClock::Process() - //clean up the vblank clock - #if defined(HAS_GLX) && defined(HAS_XRANDR) - CleanupGLX(); -+ if (m_xrrEvent) -+ { -+ m_releaseEvent.Set(); -+ while (!m_bStop) -+ { -+ if (m_resetEvent.WaitMSec(100)) -+ break; -+ } -+ m_xrrEvent = false; -+ } - #elif defined(TARGET_WINDOWS) && defined(HAS_DX) - CleanupD3D(); - #elif defined(TARGET_DARWIN) -@@ -223,6 +248,9 @@ void CVideoReferenceClock::Process() - #if defined(TARGET_WINDOWS) && defined(HAS_DX) - g_Windowing.Unregister(&m_D3dCallback); - #endif -+#if defined(HAS_GLX) -+ g_Windowing.Unregister(this); -+#endif - } - - bool CVideoReferenceClock::WaitStarted(int MSecs) -@@ -232,6 +260,24 @@ bool CVideoReferenceClock::WaitStarted(int MSecs) - } - - #if defined(HAS_GLX) && defined(HAS_XRANDR) -+ -+void CVideoReferenceClock::OnLostDevice() -+{ -+ if (!m_xrrEvent) -+ { -+ m_releaseEvent.Reset(); -+ m_resetEvent.Reset(); -+ m_xrrEvent = true; -+ m_releaseEvent.Wait(); -+ } -+} -+ -+void CVideoReferenceClock::OnResetDevice() -+{ -+ m_xrrEvent = false; -+ m_resetEvent.Set(); -+} -+ - bool CVideoReferenceClock::SetupGLX() - { - int singleBufferAttributes[] = { -@@ -382,10 +428,6 @@ bool CVideoReferenceClock::SetupGLX() - return false; - } - -- //set up receiving of RandR events, we'll get one when the refreshrate changes -- XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); -- XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); -- - UpdateRefreshrate(true); //forced refreshrate update - m_MissedVblanks = 0; - -@@ -586,6 +628,9 @@ void CVideoReferenceClock::RunGLX() - - while(!m_bStop) - { -+ if (m_xrrEvent) -+ return; -+ - //wait for the next vblank - if (!m_bIsATI) - { -@@ -649,7 +694,6 @@ void CVideoReferenceClock::RunGLX() - UpdateClock((int)(VblankCount - PrevVblankCount), true); - SingleLock.Leave(); - SendVblankSignal(); -- UpdateRefreshrate(); - IsReset = false; - } - else if (!m_bStop) -@@ -1186,23 +1230,10 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) - - #if defined(HAS_GLX) && defined(HAS_XRANDR) - -- //check for RandR events -- bool GotEvent = Forced || m_RefreshChanged == 2; -- XEvent Event; -- while (XCheckTypedEvent(m_Dpy, m_RREventBase + RRScreenChangeNotify, &Event)) -- { -- if (Event.type == m_RREventBase + RRScreenChangeNotify) -- { -- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Received RandR event %i", Event.type); -- GotEvent = true; -- } -- XRRUpdateConfiguration(&Event); -- } -- - if (!Forced) - m_RefreshChanged = 0; - -- if (!GotEvent) //refreshrate did not change -+ if (!Forced) //refreshrate did not change - return false; - - //the refreshrate can be wrong on nvidia drivers, so read it from nvidia-settings when it's available -diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h -index dd65a1b..afd71fc 100644 ---- a/xbmc/video/VideoReferenceClock.h -+++ b/xbmc/video/VideoReferenceClock.h -@@ -30,6 +30,7 @@ - #include - #include - #include -+ #include "guilib/DispResource.h" - #elif defined(TARGET_WINDOWS) && defined(HAS_DX) - #include - #include "guilib/D3DResource.h" -@@ -56,9 +57,13 @@ class CD3DCallback : public ID3DResource - #endif - - class CVideoReferenceClock : public CThread -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ ,public IDispResource -+#endif - { - public: - CVideoReferenceClock(); -+ virtual ~CVideoReferenceClock(); - - int64_t GetTime(bool interpolated = true); - int64_t GetFrequency(); -@@ -75,6 +80,11 @@ class CVideoReferenceClock : public CThread - void VblankHandler(int64_t nowtime, double fps); - #endif - -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ virtual void OnLostDevice(); -+ virtual void OnResetDevice(); -+#endif -+ - private: - void Process(); - bool UpdateRefreshrate(bool Forced = false); -@@ -121,7 +131,8 @@ class CVideoReferenceClock : public CThread - GLXContext m_Context; - Pixmap m_pixmap; - GLXPixmap m_glPixmap; -- int m_RREventBase; -+ bool m_xrrEvent; -+ CEvent m_releaseEvent, m_resetEvent; - - bool m_UseNvSettings; - bool m_bIsATI; --- -1.9.1 - - -From e9fe9c2f0dae615075a9173e5c4a0c6ef6700097 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 21/96] X11: fix video calibrations - ---- - xbmc/windowing/WinSystem.h | 1 + - xbmc/windowing/X11/WinSystemX11.cpp | 36 +++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 3 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h -index 00a2d24..c0db210 100644 ---- a/xbmc/windowing/WinSystem.h -+++ b/xbmc/windowing/WinSystem.h -@@ -103,6 +103,7 @@ public: - std::vector ScreenResolutions(int screen, float refreshrate); - std::vector RefreshRates(int screen, int width, int height, uint32_t dwFlags); - REFRESHRATE DefaultRefreshRate(int screen, std::vector rates); -+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo) { return true; }; - - // text input interface - virtual void EnableTextInput(bool bEnable) {} -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index f2fd18d..c4152c8 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -320,7 +320,7 @@ void CWinSystemX11::UpdateResolutions() - res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); - res.strOutput = out.name; - res.strId = mode.id; -- res.iSubtitles = (int)(0.95*mode.h); -+ res.iSubtitles = (int)(0.965*mode.h); - res.fRefreshRate = mode.hz; - res.bFullScreen = true; - -@@ -333,8 +333,42 @@ void CWinSystemX11::UpdateResolutions() - CDisplaySettings::Get().AddResolutionInfo(res); - } - } -+ CDisplaySettings::Get().ApplyCalibrations(); - #endif -+} -+ -+bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) -+{ -+ XOutput *out = g_xrandr.GetOutput(m_currentOutput); -+ -+ // keep calibrations done on a not connected output -+ if (!out->name.Equals(resInfo.strOutput)) -+ return true; -+ -+ // keep calibrations not updated with resolution data -+ if (resInfo.iWidth == 0) -+ return true; -+ -+ float fPixRatio; -+ if (resInfo.iHeight>0 && resInfo.iWidth>0 && out->hmm>0 && out->wmm>0) -+ fPixRatio = ((float)out->wmm/(float)resInfo.iWidth) / (((float)out->hmm/(float)resInfo.iHeight)); -+ else -+ fPixRatio = 1.0f; - -+ if (resInfo.Overscan.left != 0) -+ return true; -+ if (resInfo.Overscan.top != 0) -+ return true; -+ if (resInfo.Overscan.right != resInfo.iWidth) -+ return true; -+ if (resInfo.Overscan.bottom != resInfo.iHeight) -+ return true; -+ if (resInfo.fPixelRatio != fPixRatio) -+ return true; -+ if (resInfo.iSubtitles != (int)(0.965*resInfo.iHeight)) -+ return true; -+ -+ return false; - } - - void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 9666cc3..5b52d6c 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -63,6 +63,7 @@ public: - virtual bool Show(bool raise = true); - virtual void Register(IDispResource *resource); - virtual void Unregister(IDispResource *resource); -+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo); - - // Local to WinSystemX11 only - Display* GetDisplay() { return m_dpy; } --- -1.9.1 - - -From 1d80e75563853da38393b91d38c1c3b449db0bd9 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 22/96] X11: deactivate screen saver on startup - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++ - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 30 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c4152c8..b76b229 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -521,6 +521,33 @@ void CWinSystemX11::ResetOSScreensaver() - } - } - -+void CWinSystemX11::EnableSystemScreenSaver(bool bEnable) -+{ -+ if (!m_dpy) -+ return; -+ -+ if (bEnable) -+ XForceScreenSaver(m_dpy, ScreenSaverActive); -+ else -+ { -+ Window root_return, child_return; -+ int root_x_return, root_y_return; -+ int win_x_return, win_y_return; -+ unsigned int mask_return; -+ bool isInWin = XQueryPointer(m_dpy, RootWindow(m_dpy, m_nScreen), &root_return, &child_return, -+ &root_x_return, &root_y_return, -+ &win_x_return, &win_y_return, -+ &mask_return); -+ -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return+300, root_y_return+300); -+ XSync(m_dpy, FALSE); -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, 0, 0); -+ XSync(m_dpy, FALSE); -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return, root_y_return); -+ XSync(m_dpy, FALSE); -+ } -+} -+ - void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - { - if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) -@@ -764,6 +791,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - // create main window - if (!m_glWindow) - { -+ EnableSystemScreenSaver(false); -+ - GLint att[] = - { - GLX_RGBA, -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 5b52d6c..b2bd5a0 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -53,6 +53,7 @@ public: - virtual void ShowOSMouse(bool show); - virtual void ResetOSScreensaver(); - virtual bool EnableFrameLimiter(); -+ virtual void EnableSystemScreenSaver(bool bEnable); - - virtual void NotifyAppActiveChange(bool bActivated); - virtual void NotifyAppFocusChange(bool bGaining); --- -1.9.1 - - -From 2cd34f3f2ac582f71a042902d777b890234c7f93 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 23/96] X11: change method of going full-screen - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index b76b229..869baa8 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -38,6 +38,7 @@ - #include "utils/StringUtils.h" - #include "settings/Settings.h" - #include "windowing/WindowingFactory.h" -+#include - - #if defined(HAS_XRANDR) - #include -@@ -816,7 +817,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -- swa.override_redirect = fullscreen ? True : False; -+ swa.override_redirect = False; - swa.border_pixel = fullscreen ? 0 : 5; - swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.colormap = cmap; -@@ -832,6 +833,12 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - InputOutput, vi->visual, - mask, &swa); - -+ if (fullscreen) -+ { -+ Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); -+ XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); -+ } -+ - // define invisible cursor - Pixmap bitmapNoData; - XColor black; --- -1.9.1 - - -From 7ea6a5a0a6040f2277a510fc8752d7ca134e1f07 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 24/96] X11: reset key repeat and key modifier on focus lost - and gain - ---- - xbmc/windowing/WinEventsX11.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index d98f12f..743aca9 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -368,6 +368,8 @@ bool CWinEventsX11Imp::MessagePump() - if (WinEvents->m_xic) - XSetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = true; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); -+ WinEvents->m_keymodState = 0; - if (serial == xevent.xfocus.serial) - break; - g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -@@ -379,6 +381,7 @@ bool CWinEventsX11Imp::MessagePump() - if (WinEvents->m_xic) - XUnsetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = false; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); - serial = xevent.xfocus.serial; - break; --- -1.9.1 - - -From d3c56229317ecf38e4b3957f82669281a722482f Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 25/96] X11: replace custom utf8 to unicode with charset - convertor (squash to x11 events) - ---- - xbmc/windowing/WinEventsX11.cpp | 119 ++++------------------------------------ - xbmc/windowing/WinEventsX11.h | 2 - - 2 files changed, 11 insertions(+), 110 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 743aca9..6b98e67 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -32,6 +32,7 @@ - #include "X11/keysymdef.h" - #include "X11/XF86keysym.h" - #include "utils/log.h" -+#include "utils/CharsetConverter.h" - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -@@ -170,7 +171,6 @@ CWinEventsX11Imp::CWinEventsX11Imp() - m_display = 0; - m_window = 0; - m_keybuf = 0; -- m_utf16buf = 0; - } - - CWinEventsX11Imp::~CWinEventsX11Imp() -@@ -181,12 +181,6 @@ CWinEventsX11Imp::~CWinEventsX11Imp() - m_keybuf = 0; - } - -- if (m_utf16buf) -- { -- free(m_utf16buf); -- m_utf16buf = 0; -- } -- - if (m_xic) - { - XUnsetICFocus(m_xic); -@@ -212,7 +206,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_display = dpy; - WinEvents->m_window = win; - WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -- WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -@@ -442,8 +435,6 @@ bool CWinEventsX11Imp::MessagePump() - } - - Status status; -- int utf16size; -- int utf16length; - int len; - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, - WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -@@ -462,36 +453,29 @@ bool CWinEventsX11Imp::MessagePump() - case XLookupChars: - case XLookupBoth: - { -- if (len == 0) -- break; -- utf16size = len * sizeof(uint16_t); -- if (utf16size > sizeof(WinEvents->m_utf16buf)) -- { -- WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); -- if (WinEvents->m_utf16buf == NULL) -- { -- break; -- } -- } -- utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); -- if (utf16length < 0) -+ CStdString data(WinEvents->m_keybuf, len); -+ CStdStringW keys; -+ g_charsetConverter.utf8ToW(data, keys, false); -+ -+ if (keys.length() == 0) - { - break; - } -- for (unsigned int i = 0; i < utf16length - 1; i++) -+ -+ for (unsigned int i = 0; i < keys.length() - 1; i++) - { - newEvent.key.keysym.sym = XBMCK_UNKNOWN; -- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; -+ newEvent.key.keysym.unicode = keys[i]; - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; - ret |= ProcessKey(newEvent, 500); - } -- if (utf16length > 0) -+ if (keys.length() > 0) - { - newEvent.key.keysym.scancode = xevent.xkey.keycode; - xkeysym = XLookupKeysym(&xevent.xkey, 0); - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; -+ newEvent.key.keysym.unicode = keys[keys.length() - 1]; - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; - -@@ -762,87 +746,6 @@ bool CWinEventsX11Imp::ProcessKeyRepeat() - return false; - } - --int CWinEventsX11Imp::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) --{ -- // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. -- uint16_t *p = utf16; -- uint16_t const *const maxPtr = utf16 + utf16MaxLength; -- -- // end_of_input points to the last byte of input as opposed to the next to the last byte. -- char const *const endOfInput = utf8 + utf8Length - 1; -- -- while (utf8 <= endOfInput) -- { -- unsigned char const c = *utf8; -- if (p >= maxPtr) -- { -- //No more output space. -- return -1; -- } -- if (c < 0x80) -- { -- //One byte ASCII. -- *p++ = c; -- utf8 += 1; -- } -- else if (c < 0xC0) -- { -- // Follower byte without preceding leader bytes. -- return -1; -- } -- // 11 bits -- else if (c < 0xE0) -- { -- // Two byte sequence. We need one follower byte. -- if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) -- { -- return -1; -- } -- *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); -- utf8 += 2; -- } -- // 16 bis -- else if (c < 0xF0) -- { -- // Three byte sequence. We need two follower byte. -- if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) -- { -- return -1; -- } -- *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); -- utf8 += 3; -- } -- // 21 bits -- else if (c < 0xF8) -- { -- int plane; -- // Four byte sequence. We need three follower bytes. -- if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || -- ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) -- { -- return -1; -- } -- uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + -- ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); -- utf8 += 4; -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- } -- // 26 bits -- else if (c < 0xFC) -- { -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- utf8 += 5; -- } -- // 31 bit -- else -- { -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- utf8 += 6; -- } -- } -- return p - utf16; --} -- - XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) - { - // try direct mapping first -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index a412f32..9a8a912 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -46,7 +46,6 @@ public: - static size_t GetQueueSize(); - - protected: -- static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); - static XBMCKey LookupXbmcKeySym(KeySym keysym); - static bool ProcessKey(XBMC_Event &event, int repeatDelay); - static bool ProcessKeyRepeat(); -@@ -56,7 +55,6 @@ protected: - Window m_window; - Atom m_wmDeleteMessage; - char *m_keybuf; -- uint16_t *m_utf16buf; - XIM m_xim; - XIC m_xic; - XBMC_Event m_lastKey; --- -1.9.1 - - -From 17f4e2e5c33d0574e944cba76a561e618051551a Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 26/96] X11: fixed invalid usage of sizeof() (squash into x11 - changes) - ---- - xbmc/windowing/WinEventsX11.cpp | 11 +++++++---- - xbmc/windowing/WinEventsX11.h | 1 + - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 6b98e67..a62521f 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -171,6 +171,7 @@ CWinEventsX11Imp::CWinEventsX11Imp() - m_display = 0; - m_window = 0; - m_keybuf = 0; -+ m_keybuf_len = 0; - } - - CWinEventsX11Imp::~CWinEventsX11Imp() -@@ -205,7 +206,8 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents = new CWinEventsX11Imp(); - WinEvents->m_display = dpy; - WinEvents->m_window = win; -- WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -+ WinEvents->m_keybuf_len = 32*sizeof(char); -+ WinEvents->m_keybuf = (char*)malloc(WinEvents->m_keybuf_len); - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -@@ -437,13 +439,14 @@ bool CWinEventsX11Imp::MessagePump() - Status status; - int len; - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ WinEvents->m_keybuf, WinEvents->m_keybuf_len, - &xkeysym, &status); - if (status == XBufferOverflow) - { -- WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); -+ WinEvents->m_keybuf_len = len; -+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, WinEvents->m_keybuf_len); - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ WinEvents->m_keybuf, WinEvents->m_keybuf_len, - &xkeysym, &status); - } - switch (status) -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 9a8a912..c69169c 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -55,6 +55,7 @@ protected: - Window m_window; - Atom m_wmDeleteMessage; - char *m_keybuf; -+ size_t m_keybuf_len; - XIM m_xim; - XIC m_xic; - XBMC_Event m_lastKey; --- -1.9.1 - - -From 90af49c63d9469c783629881e1846979594a8ff2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 27/96] add missing keys to xbmc keytable - ---- - xbmc/input/XBMC_keytable.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp -index d57f4d3..b807897 100644 ---- a/xbmc/input/XBMC_keytable.cpp -+++ b/xbmc/input/XBMC_keytable.cpp -@@ -180,6 +180,8 @@ static const XBMCKEYTABLE XBMCKeyTable[] = - , { XBMCK_LAUNCH_APP2, 0, 0, XBMCVK_LAUNCH_APP2, "launch_app2_pc_icon" } - , { XBMCK_LAUNCH_FILE_BROWSER, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER, "launch_file_browser" } - , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } -+, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } -+, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } - - // Function keys - , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} --- -1.9.1 - - -From 049f7e527bf12b7322c7343f01e6f08a2415fe8e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 28/96] videorefclock: temp deactivate of nv settings - ---- - xbmc/video/VideoReferenceClock.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 0ddf102..3ae7107 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -136,7 +136,7 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("VideoReferenceClock") - m_Context = NULL; - m_pixmap = None; - m_glPixmap = None; -- m_UseNvSettings = true; -+ m_UseNvSettings = false; - m_bIsATI = false; - #endif - } --- -1.9.1 - - -From 23b43d522cb691b21ef572f3ee003b152fea4b3a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 29/96] videorefclock: ask graphics context for refresh rate - ---- - xbmc/video/VideoReferenceClock.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 3ae7107..27bebde 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -31,6 +31,7 @@ - #include - #include - #include "windowing/WindowingFactory.h" -+ #include "guilib/GraphicContext.h" - #define NVSETTINGSCMD "nvidia-settings -nt -q RefreshRate3" - #elif defined(TARGET_DARWIN_OSX) - #include -@@ -1254,7 +1255,7 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) - } - - CSingleLock SingleLock(m_CritSection); -- m_RefreshRate = GetRandRRate(); -+ m_RefreshRate = MathUtils::round_int(g_graphicsContext.GetFPS()); - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", (int)m_RefreshRate); - --- -1.9.1 - - -From 263d964167a2eaf52713f513ef8cc4c912241e3b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 30/96] X11: fix icon texture after - cc5ed3c2474084ebc0373a3046410e6f766e03f4 - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 43 ++++++++++++++++++++++--------------- - 1 file changed, 26 insertions(+), 17 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 869baa8..bfe3797 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -874,22 +874,24 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - if (!fullscreen) - { - CreateIconPixmap(); -- XWMHints wm_hints; -- XClassHint class_hints; -+ XWMHints *wm_hints; - XTextProperty windowName, iconName; - std::string titleString = "XBMC Media Center"; - char *title = (char*)titleString.c_str(); - - XStringListToTextProperty(&title, 1, &windowName); - XStringListToTextProperty(&title, 1, &iconName); -- wm_hints.initial_state = NormalState; -- wm_hints.input = True; -- wm_hints.icon_pixmap = m_icon; -- wm_hints.flags = StateHint | IconPixmapHint | InputHint; - -+ wm_hints = XAllocWMHints(); -+ wm_hints->initial_state = NormalState; -+ wm_hints->icon_pixmap = m_icon; -+ wm_hints->flags = StateHint | IconPixmapHint; -+ -+ XSync(m_dpy,False); - XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -- NULL, 0, NULL, &wm_hints, -+ NULL, 0, NULL, wm_hints, - NULL); -+ XFree(wm_hints); - - // register interest in the delete window message - Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); -@@ -974,16 +976,21 @@ bool CWinSystemX11::CreateIconPixmap() - gRatio = vis->green_mask / 255.0; - bRatio = vis->blue_mask / 255.0; - -- CTexture iconTexture; -- iconTexture.LoadFromFile("special://xbmc/media/icon256x256.png"); -- buf = iconTexture.GetPixels(); -+ CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon256x256.png"); -+ -+ if (!iconTexture) -+ return false; - -- numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; -+ buf = iconTexture->GetPixels(); -+ -+ numBufBytes = iconTexture->GetWidth() * iconTexture->GetHeight() * 4; -+ int wid = iconTexture->GetWidth(); -+ int hi = iconTexture->GetHeight(); - - if (depth>=24) -- numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight())); - else -- numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight())); - - newBuf = (uint32_t*)malloc(numNewBufBytes); - if (!newBuf) -@@ -992,11 +999,11 @@ bool CWinSystemX11::CreateIconPixmap() - return false; - } - -- for (i=0; iGetHeight();++i) - { -- for (j=0; jGetWidth();++j) - { -- unsigned int pos = i*iconTexture.GetPitch()+j*4; -+ unsigned int pos = i*iconTexture->GetPitch()+j*4; - unsigned int r, g, b; - r = (buf[pos+2] * rRatio); - g = (buf[pos+1] * gRatio); -@@ -1009,7 +1016,7 @@ bool CWinSystemX11::CreateIconPixmap() - } - } - img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, -- iconTexture.GetWidth(), iconTexture.GetHeight(), -+ iconTexture->GetWidth(), iconTexture->GetHeight(), - (depth>=24)?32:16, 0); - if (!img) - { -@@ -1047,6 +1054,8 @@ bool CWinSystemX11::CreateIconPixmap() - XFreeGC(m_dpy, gc); - XDestroyImage(img); // this also frees newBuf - -+ delete iconTexture; -+ - return true; - } - --- -1.9.1 - - -From 648af86aa01874210d8ea6732cf7cef4f8e466e0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 31/96] X11: check for window manager - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 73 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index bfe3797..af82061 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -816,8 +816,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - -+ bool hasWM = HasWindowManager(); -+ - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -- swa.override_redirect = False; -+ swa.override_redirect = hasWM ? False : True; - swa.border_pixel = fullscreen ? 0 : 5; - swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.colormap = cmap; -@@ -833,7 +835,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - InputOutput, vi->visual, - mask, &swa); - -- if (fullscreen) -+ if (fullscreen && hasWM) - { - Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); - XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); -@@ -1059,4 +1061,72 @@ bool CWinSystemX11::CreateIconPixmap() - return true; - } - -+bool CWinSystemX11::HasWindowManager() -+{ -+ Window wm_check; -+ unsigned char *data; -+ int status, real_format; -+ Atom real_type, prop; -+ unsigned long items_read, items_left, i; -+ char req = 0; -+ -+ prop = XInternAtom(m_dpy, "_NET_SUPPORTING_WM_CHECK", True); -+ if (prop == None) -+ return false; -+ status = XGetWindowProperty(m_dpy, DefaultRootWindow(m_dpy), prop, -+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ if(status != Success || ! items_read) -+ { -+ if(status == Success) -+ XFree(data); -+ return false; -+ } -+ -+ wm_check = ((Window*)data)[0]; -+ XFree(data); -+ -+ status = XGetWindowProperty(m_dpy, wm_check, prop, -+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ -+ if(status != Success || !items_read) -+ { -+ if(status == Success) -+ XFree(data); -+ return false; -+ } -+ -+ if(wm_check != ((Window*)data)[0]) -+ { -+ XFree(data); -+ return false; -+ } -+ -+ XFree(data); -+ -+ prop = XInternAtom(m_dpy, "_NET_WM_NAME", True); -+ if (prop == None) -+ { -+ CLog::Log(LOGDEBUG,"Window Manager Name: "); -+ return true; -+ } -+ -+ status = XGetWindowProperty(m_dpy, wm_check, prop, -+ 0L, (~0L), False, AnyPropertyType, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ -+ if(status == Success && items_read) -+ { -+ CLog::Log(LOGDEBUG,"Window Manager Name: %s", data); -+ } -+ else -+ CLog::Log(LOGDEBUG,"Window Manager Name: "); -+ -+ if(status == Success) -+ XFree(data); -+ -+ return true; -+} -+ - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index b2bd5a0..3e62cd8 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -103,6 +103,7 @@ private: - bool IsSuitableVisual(XVisualInfo *vInfo); - static int XErrorHandler(Display* dpy, XErrorEvent* error); - bool CreateIconPixmap(); -+ bool HasWindowManager(); - - CStopWatch m_screensaverReset; - }; --- -1.9.1 - - -From f4ed19185a171a1967c30999e119abd661654102 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 32/96] X11: dont set window on xrandr if no mode available - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index af82061..4f33c68 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -665,16 +665,17 @@ void CWinSystemX11::NotifyXRREvent() - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); - m_windowDirty = true; - -+ if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } -+ - // if external event update resolutions - if (!m_bIsInternalXrr) - { - UpdateResolutions(); - } -- else if (!g_xrandr.Query(true)) -- { -- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -- return; -- } - m_bIsInternalXrr = false; - - CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); --- -1.9.1 - - -From d174bc51e0e31ec6666bdc0479a4c948efc5bd63 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 33/96] X11: fix crash after a resolution change on startup - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 4f33c68..bc4e963 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -223,7 +223,8 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - OnLostDevice(); - m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); -- return true; -+ if (m_glWindow) -+ return true; - } - #endif - --- -1.9.1 - - -From b685749adb461364ad288593d1e62e4927c439c8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 34/96] X11: lock graphics context in NotifyXRREvent - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index bc4e963..57a8d20 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -666,6 +666,8 @@ void CWinSystemX11::NotifyXRREvent() - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); - m_windowDirty = true; - -+ CSingleLock lock(g_graphicsContext); -+ - if (!g_xrandr.Query(true)) - { - CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); --- -1.9.1 - - -From 9ac337cb7338a191037bb3e05599ce1f9de3419b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 35/96] dvdplayer: observe pts counter overflow - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 197 ++++++++++++++++++++- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 4 + - 2 files changed, 200 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index 4ce1b87..afa3024 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -18,7 +18,6 @@ - * - */ - --#include "system.h" - #ifndef __STDC_CONSTANT_MACROS - #define __STDC_CONSTANT_MACROS - #endif -@@ -26,6 +25,7 @@ - #define __STDC_LIMIT_MACROS - #endif - #ifdef TARGET_POSIX -+#include "system.h" - #include "stdint.h" - #endif - #include "DVDDemuxFFmpeg.h" -@@ -489,6 +489,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) - - CreateStreams(); - -+ m_bPtsWrapChecked = false; -+ m_bPtsWrap = false; -+ - return true; - } - -@@ -634,6 +637,12 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) - if (pts == (int64_t)AV_NOPTS_VALUE) - return DVD_NOPTS_VALUE; - -+ if (m_bPtsWrap) -+ { -+ if (pts < m_iStartTime && pts < m_iEndTime) -+ pts += m_iMaxTime; -+ } -+ - // do calculations in floats as they can easily overflow otherwise - // we don't care for having a completly exact timestamp anyway - double timestamp = (double)pts * num / den; -@@ -773,6 +782,24 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() - m_pkt.pkt.pts = AV_NOPTS_VALUE; - } - -+ if (!m_bPtsWrapChecked && m_pFormatContext->iformat->flags & AVFMT_TS_DISCONT) -+ { -+ int defaultStream = av_find_default_stream_index(m_pFormatContext); -+ int64_t duration = m_pFormatContext->streams[defaultStream]->duration * 1.5; -+ m_iMaxTime = 1LL<streams[defaultStream]->pts_wrap_bits; -+ m_iStartTime = m_pFormatContext->streams[defaultStream]->start_time; -+ if (m_iStartTime != DVD_NOPTS_VALUE) -+ { -+ m_iEndTime = (m_iStartTime + duration) & ~m_iMaxTime; -+ if (m_iEndTime < m_iStartTime) -+ { -+ CLog::Log(LOGNOTICE,"CDVDDemuxFFmpeg::Read - file contains pts overflow"); -+ m_bPtsWrap = true; -+ } -+ } -+ m_bPtsWrapChecked = true; -+ } -+ - // copy contents into our own packet - pPacket->iSize = m_pkt.pkt.size; - -@@ -906,7 +933,16 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) - ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); - - if(ret >= 0) -+ { - UpdateCurrentPTS(); -+ -+ // seek may fail silently on streams which allow discontinuity -+ // if current timestamp is way off asume a pts overflow and try bisect seek -+ if (m_bPtsWrap && fabs(time - m_iCurrentPts/1000) > 10000) -+ { -+ ret = SeekTimeDiscont(seek_pts, backwords) ? 1 : -1; -+ } -+ } - } - - if(m_iCurrentPts == DVD_NOPTS_VALUE) -@@ -925,6 +961,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) - return (ret >= 0); - } - -+bool CDVDDemuxFFmpeg::SeekTimeDiscont(int64_t pts, bool backwards) -+{ -+ // this code is taken from ffmpeg function ff_gen_search -+ // it is modified to assume a pts overflow if timestamp < start_time -+ if (!m_pFormatContext->iformat->read_timestamp) -+ return false; -+ -+ int defaultStream = av_find_default_stream_index(m_pFormatContext); -+ -+ if (defaultStream < 0) -+ { -+ return false; -+ } -+ -+ // timestamp for default must be expressed in AV_TIME_BASE units -+ pts = av_rescale_rnd(pts, m_pFormatContext->streams[defaultStream]->time_base.den, -+ AV_TIME_BASE * (int64_t)m_pFormatContext->streams[defaultStream]->time_base.num, -+ AV_ROUND_NEAR_INF); -+ -+ int64_t pos, pos_min, pos_max, pos_limit, ts, ts_min, ts_max; -+ int64_t start_pos, filesize; -+ int no_change; -+ -+ pos_min = m_pFormatContext->data_offset; -+ ts_min = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos_min, INT64_MAX); -+ if (ts_min == AV_NOPTS_VALUE) -+ return false; -+ -+ if(ts_min >= pts) -+ { -+ pos = pos_min; -+ return true; -+ } -+ -+ int step= 1024; -+ filesize = m_pInput->GetLength(); -+ pos_max = filesize - 1; -+ do -+ { -+ pos_max -= step; -+ ts_max = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos_max, pos_max + step); -+ step += step; -+ }while (ts_max == AV_NOPTS_VALUE && pos_max >= step); -+ -+ if (ts_max == AV_NOPTS_VALUE) -+ return false; -+ -+ if (ts_max < m_iStartTime && ts_max < m_iEndTime) -+ ts_max += m_iMaxTime; -+ -+ for(;;) -+ { -+ int64_t tmp_pos = pos_max + 1; -+ int64_t tmp_ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &tmp_pos, INT64_MAX); -+ if(tmp_ts == AV_NOPTS_VALUE) -+ break; -+ -+ if (tmp_ts < m_iStartTime && tmp_ts < m_iEndTime) -+ tmp_ts += m_iMaxTime; -+ -+ ts_max = tmp_ts; -+ pos_max = tmp_pos; -+ if (tmp_pos >= filesize) -+ break; -+ } -+ pos_limit = pos_max; -+ -+ if(ts_max <= pts) -+ { -+ bool ret = SeekByte(pos_max); -+ if (ret) -+ { -+ m_iCurrentPts = ConvertTimestamp(ts_max, m_pFormatContext->streams[defaultStream]->time_base.den, -+ m_pFormatContext->streams[defaultStream]->time_base.num); -+ } -+ return ret; -+ } -+ -+ if(ts_min > ts_max) -+ { -+ return false; -+ } -+ else if (ts_min == ts_max) -+ { -+ pos_limit = pos_min; -+ } -+ -+ no_change=0; -+ while (pos_min < pos_limit) -+ { -+ if (no_change == 0) -+ { -+ int64_t approximate_keyframe_distance= pos_max - pos_limit; -+ // interpolate position (better than dichotomy) -+ pos = av_rescale_rnd(pts - ts_min, pos_max - pos_min, -+ ts_max - ts_min, AV_ROUND_NEAR_INF) -+ + pos_min - approximate_keyframe_distance; -+ } -+ else if (no_change == 1) -+ { -+ // bisection, if interpolation failed to change min or max pos last time -+ pos = (pos_min + pos_limit) >> 1; -+ } -+ else -+ { -+ /* linear search if bisection failed, can only happen if there -+ are very few or no keyframes between min/max */ -+ pos = pos_min; -+ } -+ if (pos <= pos_min) -+ pos= pos_min + 1; -+ else if (pos > pos_limit) -+ pos= pos_limit; -+ start_pos = pos; -+ -+ ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos, INT64_MAX); -+ if (pos == pos_max) -+ no_change++; -+ else -+ no_change=0; -+ -+ if (ts == AV_NOPTS_VALUE) -+ { -+ return false; -+ } -+ -+ if (ts < m_iStartTime && ts < m_iEndTime) -+ ts += m_iMaxTime; -+ -+ if (pts <= ts) -+ { -+ pos_limit = start_pos - 1; -+ pos_max = pos; -+ ts_max = ts; -+ } -+ if (pts >= ts) -+ { -+ pos_min = pos; -+ ts_min = ts; -+ } -+ } -+ -+ pos = (backwards) ? pos_min : pos_max; -+ ts = (backwards) ? ts_min : ts_max; -+ -+ bool ret = SeekByte(pos); -+ if (ret) -+ { -+ m_iCurrentPts = ConvertTimestamp(ts, m_pFormatContext->streams[defaultStream]->time_base.den, -+ m_pFormatContext->streams[defaultStream]->time_base.num); -+ } -+ -+ return ret; -+} -+ - bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) - { - CSingleLock lock(m_critSection); -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index aef5ab1..35abbdf 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -100,6 +100,7 @@ public: - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); -+ bool SeekTimeDiscont(int64_t pts, bool backwards); - bool SeekByte(int64_t pos); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); -@@ -158,5 +159,8 @@ protected: - AVPacket pkt; // packet ffmpeg returned - int result; // result from av_read_packet - }m_pkt; -+ -+ bool m_bPtsWrap, m_bPtsWrapChecked; -+ int64_t m_iStartTime, m_iMaxTime, m_iEndTime; - }; - --- -1.9.1 - - -From edec7054fd66168c26cb16d624139a85d0feeb82 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 36/96] dvdplayer: avoid short screen flicker caused by - unnecessary reconfigure of renderer - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 9c36bdb..322a581 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1054,13 +1054,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - - #ifdef HAS_VIDEO_PLAYBACK - double config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate; -+ double render_framerate = g_graphicsContext.GetFPS(); -+ if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") == ADJUST_REFRESHRATE_OFF) -+ render_framerate = config_framerate; - /* check so that our format or aspect has changed. if it has, reconfigure renderer */ - if (!g_renderManager.IsConfigured() - || ( m_output.width != pPicture->iWidth ) - || ( m_output.height != pPicture->iHeight ) - || ( m_output.dwidth != pPicture->iDisplayWidth ) - || ( m_output.dheight != pPicture->iDisplayHeight ) -- || ( m_output.framerate != config_framerate ) -+ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 && render_framerate != config_framerate) - || ( m_output.color_format != (unsigned int)pPicture->format ) - || ( m_output.extended_format != pPicture->extended_format ) - || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified --- -1.9.1 - - -From aea69ca48e5ae5888feec63cd9ce8f16c971f5cf Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 37/96] vdpau: advanced settings for auto deinterlacing - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++---- - xbmc/settings/AdvancedSettings.cpp | 4 ++++ - xbmc/settings/AdvancedSettings.h | 2 ++ - 3 files changed, 10 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index b4d2d38..cd72cc6 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1987,10 +1987,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) - if (method == VS_INTERLACEMETHOD_AUTO) - { - int deint = -1; --// if (m_config.outHeight >= 720) --// deint = g_advancedSettings.m_videoVDPAUdeintHD; --// else --// deint = g_advancedSettings.m_videoVDPAUdeintSD; -+ if (m_config.outHeight >= 720) -+ deint = g_advancedSettings.m_videoVDPAUdeintHD; -+ else -+ deint = g_advancedSettings.m_videoVDPAUdeintSD; - - if (deint != -1) - { -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index eff43dd..7532914 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -163,6 +163,8 @@ void CAdvancedSettings::Initialize() - m_videoAutoScaleMaxFps = 30.0f; - m_videoDisableBackgroundDeinterlace = false; - m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect -+ m_videoVDPAUdeintHD = -1; -+ m_videoVDPAUdeintSD = -1; - m_videoVDPAUtelecine = false; - m_videoVDPAUdeintSkipChromaHD = false; - m_DXVACheckCompatibility = false; -@@ -600,6 +602,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading); - XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); - XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); -+ XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD); -+ XMLUtils::GetInt(pElement,"vdpauSDdeint",m_videoVDPAUdeintSD); - XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine); - XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); - -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index 3995f35..c43351d 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -160,6 +160,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - int m_videoPercentSeekBackwardBig; - CStdString m_videoPPFFmpegDeint; - CStdString m_videoPPFFmpegPostProc; -+ int m_videoVDPAUdeintHD; -+ int m_videoVDPAUdeintSD; - bool m_videoVDPAUtelecine; - bool m_videoVDPAUdeintSkipChromaHD; - bool m_musicUseTimeSeeking; --- -1.9.1 - - -From 075908a1dae8d28b939fe754686105b2106a97d1 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 38/96] player: fix rewind - ---- - xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 30 +++++++++++++++++++----------- - xbmc/cores/dvdplayer/DVDPlayer.h | 7 ++++--- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 +++- - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 1 + - 5 files changed, 31 insertions(+), 16 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDMessage.h b/xbmc/cores/dvdplayer/DVDMessage.h -index 2ea8b8f..e8274f9 100644 ---- a/xbmc/cores/dvdplayer/DVDMessage.h -+++ b/xbmc/cores/dvdplayer/DVDMessage.h -@@ -220,7 +220,7 @@ private: - class CDVDMsgPlayerSeek : public CDVDMsg - { - public: -- CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false) -+ CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false, bool sync = true) - : CDVDMsg(PLAYER_SEEK) - , m_time(time) - , m_backward(backward) -@@ -228,6 +228,7 @@ public: - , m_accurate(accurate) - , m_restore(restore) - , m_trickplay(trickplay) -+ , m_sync(sync) - {} - int GetTime() { return m_time; } - bool GetBackward() { return m_backward; } -@@ -235,6 +236,7 @@ public: - bool GetAccurate() { return m_accurate; } - bool GetRestore() { return m_restore; } - bool GetTrickPlay() { return m_trickplay; } -+ bool GetSync() { return m_sync; } - private: - int m_time; - bool m_backward; -@@ -242,6 +244,7 @@ private: - bool m_accurate; - bool m_restore; // whether to restore any EDL cut time - bool m_trickplay; -+ bool m_sync; - }; - - class CDVDMsgPlayerSeekChapter : public CDVDMsg -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 15e490c..2474b39 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1634,11 +1634,13 @@ void CDVDPlayer::HandlePlaySpeed() - } - else if (m_CurrentVideo.id >= 0 - && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file -- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() -+ && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200)) -+ && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE) - && m_SpeedState.lasttime != GetTime()) - { - m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts(); - m_SpeedState.lasttime = GetTime(); -+ m_SpeedState.lastabstime = CDVDClock::GetAbsoluteClock(); - // check how much off clock video is when ff/rw:ing - // a problem here is that seeking isn't very accurate - // and since the clock will be resynced after seek -@@ -1657,7 +1659,7 @@ void CDVDPlayer::HandlePlaySpeed() - { - CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up"); - int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL); -- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true)); -+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true, false)); - } - } - } -@@ -2143,7 +2145,7 @@ void CDVDPlayer::HandleMessages() - else - m_StateInput.dts = start; - -- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate()); -+ FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync()); - } - else - CLog::Log(LOGWARNING, "error while seeking"); -@@ -2279,9 +2281,10 @@ void CDVDPlayer::HandleMessages() - double offset; - offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; - offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; -+ offset = DVD_TIME_TO_MSEC(offset); - if(offset > 1000) offset = 1000; - if(offset < -1000) offset = -1000; -- m_State.time += DVD_TIME_TO_MSEC(offset); -+ m_State.time += offset; - m_State.timestamp = CDVDClock::GetAbsoluteClock(); - } - -@@ -2297,7 +2300,8 @@ void CDVDPlayer::HandleMessages() - // do a seek after rewind, clock is not in sync with current pts - if (m_playSpeed < 0 && speed >= 0) - { -- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset); -+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true)); - } - - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE -@@ -3294,7 +3298,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) - return true; - } - --void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) -+void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync) - { - double startpts; - if(accurate) -@@ -3306,19 +3310,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) - if(startpts != DVD_NOPTS_VALUE) - startpts -= m_offset_pts; - -- m_CurrentAudio.inited = false; -+ if (sync) -+ { -+ m_CurrentAudio.inited = false; -+ m_CurrentVideo.inited = false; -+ m_CurrentSubtitle.inited = false; -+ m_CurrentTeletext.inited = false; -+ } -+ - m_CurrentAudio.dts = DVD_NOPTS_VALUE; - m_CurrentAudio.startpts = startpts; - -- m_CurrentVideo.inited = false; - m_CurrentVideo.dts = DVD_NOPTS_VALUE; - m_CurrentVideo.startpts = startpts; - -- m_CurrentSubtitle.inited = false; - m_CurrentSubtitle.dts = DVD_NOPTS_VALUE; - m_CurrentSubtitle.startpts = startpts; - -- m_CurrentTeletext.inited = false; - m_CurrentTeletext.dts = DVD_NOPTS_VALUE; - m_CurrentTeletext.startpts = startpts; - -@@ -3362,7 +3370,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) - m_CurrentTeletext.started = false; - } - -- if(pts != DVD_NOPTS_VALUE) -+ if(pts != DVD_NOPTS_VALUE && sync) - m_clock.Discontinuity(pts); - UpdatePlayState(0); - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index e2a836b..6ecaf3f 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -308,7 +308,7 @@ protected: - bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset); - - -- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true); -+ void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true); - - void HandleMessages(); - void HandlePlaySpeed(); -@@ -357,8 +357,9 @@ protected: - int m_playSpeed; - struct SSpeedState - { -- double lastpts; // holds last display pts during ff/rw operations -- double lasttime; -+ double lastpts; // holds last display pts during ff/rw operations -+ int64_t lasttime; -+ double lastabstime; - } m_SpeedState; - - int m_errorCount; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 322a581..9c5469b 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1470,7 +1470,7 @@ double CDVDPlayerVideo::GetCurrentPts() - - if( m_stalled ) - iRenderPts = DVD_NOPTS_VALUE; -- else -+ else if ( m_speed == DVD_PLAYSPEED_NORMAL) - iRenderPts = iRenderPts - max(0.0, iSleepTime); - - return iRenderPts; -@@ -1570,6 +1570,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - int iSkippedDeint = 0; - int iBufferLevel; - -+ m_droppingStats.m_lastPts = pts; -+ - // get decoder stats - if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) - iDecoderPts = pts; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index 59c7f09..65dea76 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -50,6 +50,7 @@ public: - double m_totalGain; - double m_lastDecoderPts; - double m_lastRenderPts; -+ double m_lastPts; - unsigned int m_lateFrames; - unsigned int m_dropRequests; - }; --- -1.9.1 - - -From 7070e0502de0d996e39c2a379dea650f773e220e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 39/96] xrandr: fix query for multiple screens - ---- - xbmc/windowing/X11/XRandR.cpp | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 4685413..e610150 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -58,12 +58,14 @@ bool CXRandR::Query(bool force) - - m_outputs.clear(); - // query all screens -+ // we are happy if at least one screen returns results -+ bool success = false; - for(unsigned int screennum=0; screennum -Date: Sun, 2 Dec 2012 15:46:55 +0100 -Subject: [PATCH 40/96] X11: add debug log to print out refresh after xrr event - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 57a8d20..a237dc0 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -685,6 +685,12 @@ void CWinSystemX11::NotifyXRREvent() - XOutput *out = g_xrandr.GetOutput(currentOutput); - XMode mode = g_xrandr.GetCurrentMode(currentOutput); - -+ if (out) -+ CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ -+ , out->name.c_str(), mode.id.c_str(), mode.hz); -+ else -+ CLog::Log(LOGWARNING, "%s - output name not set", __FUNCTION__); -+ - RESOLUTION_INFO res; - unsigned int i; - bool found(false); --- -1.9.1 - - -From 0b610b8e1040605b28907f72866a2be58b963a13 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 41/96] X11: dont call XCloseDisplay on shutdown, it crashes - when powered doen by cec on ATI - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index a237dc0..ab660b1 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -112,7 +112,8 @@ bool CWinSystemX11::DestroyWindowSystem() - //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy - //so instead we just let m_dpy die on exit - // i have seen core dumps on ATI if the display is not closed here -- XCloseDisplay(m_dpy); -+ // crashes when shutting down via cec -+// XCloseDisplay(m_dpy); - } - - // m_SDLSurface is free()'d by SDL_Quit(). --- -1.9.1 - - -From 1501643dfcda4e8e1c46feade3370964f8f344b9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Gr=C3=A9gory=20Coutant?= -Date: Wed, 12 Dec 2012 19:49:47 +0100 -Subject: [PATCH 42/96] x11: support for multiple x screens - ---- - xbmc/windowing/X11/XRandR.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index e610150..5c53574 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -93,7 +93,7 @@ bool CXRandR::Query(bool force, int screennum) - pclose(file); - - TiXmlElement *pRootElement = xmlDoc.RootElement(); -- if (strcasecmp(pRootElement->Value(), "screen") != screennum) -+ if (atoi(pRootElement->Attribute("id")) != screennum) - { - // TODO ERROR - return false; --- -1.9.1 - - -From 00c856df34e3941787d98d871b9b6d8905717d76 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 43/96] pvr: increase changes counter of stream on stream - change, cosmetics after dd307930d39d92f145a01a16600cd00e01ec39be - ---- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -index 7d0a732..d066610 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -@@ -339,9 +339,7 @@ void CDVDDemuxPVRClient::RequestStreams() - if (stm) - { - st = dynamic_cast(stm); -- if (!st -- || (st->codec != (AVCodecID)props.stream[i].iCodecId) -- || (st->iChannels != props.stream[i].iChannels)) -+ if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) -@@ -358,6 +356,7 @@ void CDVDDemuxPVRClient::RequestStreams() - st->iBitsPerSample = props.stream[i].iBitsPerSample; - m_streams[i] = st; - st->m_parser_split = true; -+ st->changes++; - } - else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_VIDEO) - { --- -1.9.1 - - -From 3021decc0764c58d5aa8e1d668106527f076343e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 44/96] X11: add keymapping for XF86XK_Sleep - ---- - xbmc/windowing/WinEventsX11.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index a62521f..263cb5a 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -143,6 +143,7 @@ static uint32_t SymMappingsX11[][2] = - , {XK_Break, XBMCK_BREAK} - , {XK_Menu, XBMCK_MENU} - , {XF86XK_PowerOff, XBMCK_POWER} -+, {XF86XK_Sleep, XBMCK_SLEEP} - , {XK_EcuSign, XBMCK_EURO} - , {XK_Undo, XBMCK_UNDO} - /* Media keys */ --- -1.9.1 - - -From 3064c39cb89bc411e235fd4fdc0d82f795c894f7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 45/96] X11: remove toggle full screen after resume - ---- - xbmc/powermanagement/PowerManager.cpp | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp -index 590a887..35b5a21 100644 ---- a/xbmc/powermanagement/PowerManager.cpp -+++ b/xbmc/powermanagement/PowerManager.cpp -@@ -268,11 +268,6 @@ void CPowerManager::OnWake() - #if defined(TARGET_WINDOWS) - ShowWindow(g_hWnd,SW_RESTORE); - SetForegroundWindow(g_hWnd); --#elif !defined(TARGET_DARWIN_OSX) -- // Hack to reclaim focus, thus rehiding system mouse pointer. -- // Surely there's a better way? -- g_graphicsContext.ToggleFullScreenRoot(); -- g_graphicsContext.ToggleFullScreenRoot(); - #endif - } - g_application.ResetScreenSaver(); --- -1.9.1 - - -From ad652ac8add735a9796acf9545eceba8c1e4d2fe Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 46/96] xrandr: set screen on mode change command - ---- - xbmc/windowing/X11/XRandR.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 5c53574..4355ef7 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -246,7 +246,7 @@ bool CXRandR::SetMode(XOutput output, XMode mode) - m_currentMode = modeFound.id; - char cmd[255]; - if (getenv("XBMC_BIN_HOME")) -- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str()); -+ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); - else - return false; - CLog::Log(LOGINFO, "XRANDR: %s", cmd); --- -1.9.1 - - -From 10b7c59751e8b809a2fdf5e0c0edd01a2acbc5f7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 47/96] X11: recreate glx context when output changes - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- - xbmc/windowing/X11/WinSystemX11.h | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index ab660b1..4329a22 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -409,11 +409,11 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - return true; - } - --bool CWinSystemX11::RefreshGlxContext() -+bool CWinSystemX11::RefreshGlxContext(bool force) - { - bool retVal = false; - -- if (m_glContext) -+ if (m_glContext && !force) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); - glXMakeCurrent(m_dpy, None, NULL); -@@ -930,7 +930,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - - CDirtyRegionList dr; -- RefreshGlxContext(); -+ RefreshGlxContext(!m_currentOutput.Equals(output)); - XSync(m_dpy, FALSE); - g_graphicsContext.Clear(0); - g_graphicsContext.Flip(dr); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 3e62cd8..2a1fb41 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -76,7 +76,7 @@ public: - void NotifyMouseCoverage(bool covered); - - protected: -- bool RefreshGlxContext(); -+ bool RefreshGlxContext(bool force); - void CheckDisplayEvents(); - void OnLostDevice(); - bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); --- -1.9.1 - - -From 353c653d504a568b28cf3e90380c8aeff0629c75 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 14 Dec 2012 14:19:15 +0100 -Subject: [PATCH 48/96] pvr: do not show selection dialog for a single menu - hook - ---- - xbmc/pvr/addons/PVRClients.cpp | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp -index 14c9cde..57b18a5 100644 ---- a/xbmc/pvr/addons/PVRClients.cpp -+++ b/xbmc/pvr/addons/PVRClients.cpp -@@ -733,6 +733,7 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF - { - hooks = client->GetMenuHooks(); - std::vector hookIDs; -+ int selection = 0; - - CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - pDialog->Reset(); -@@ -743,9 +744,11 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CF - pDialog->Add(client->GetString(hooks->at(i).iLocalizedStringId)); - hookIDs.push_back(i); - } -- pDialog->DoModal(); -- -- int selection = pDialog->GetSelectedLabel(); -+ if (hookIDs.size() > 1) -+ { -+ pDialog->DoModal(); -+ selection = pDialog->GetSelectedLabel(); -+ } - if (selection >= 0) - client->CallMenuHook(hooks->at(hookIDs.at(selection)), item); - } --- -1.9.1 - - -From 3f1eb64980be5bf9c5676c93e3a99bf107824c25 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 3 Feb 2013 08:17:16 +0100 -Subject: [PATCH 49/96] X11: use default screen parameters if no output - connected - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 55 ++++++++++++++++++++++--------------- - 1 file changed, 33 insertions(+), 22 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 4329a22..2adf8a0 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -207,25 +207,27 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - - XMode currmode = g_xrandr.GetCurrentMode(out.name); -- -- // flip h/w when rotated -- if (m_bIsRotated) -+ if (!currmode.name.empty()) - { -- int w = mode.w; -- mode.w = mode.h; -- mode.h = w; -- } -+ // flip h/w when rotated -+ if (m_bIsRotated) -+ { -+ int w = mode.w; -+ mode.w = mode.h; -+ mode.h = w; -+ } - -- // only call xrandr if mode changes -- if (currmode.w != mode.w || currmode.h != mode.h || -- currmode.hz != mode.hz || currmode.id != mode.id) -- { -- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); -- OnLostDevice(); -- m_bIsInternalXrr = true; -- g_xrandr.SetMode(out, mode); -- if (m_glWindow) -- return true; -+ // only call xrandr if mode changes -+ if (currmode.w != mode.w || currmode.h != mode.h || -+ currmode.hz != mode.hz || currmode.id != mode.id) -+ { -+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); -+ OnLostDevice(); -+ m_bIsInternalXrr = true; -+ g_xrandr.SetMode(out, mode); -+ if (m_glWindow) -+ return true; -+ } - } - #endif - -@@ -272,9 +274,10 @@ void CWinSystemX11::UpdateResolutions() - else - #endif - { -- int x11screen = m_nScreen; -- int w = DisplayWidth(m_dpy, x11screen); -- int h = DisplayHeight(m_dpy, x11screen); -+ CSettings::Get().SetString("videoscreen.monitor", "Default"); -+ m_nScreen = DefaultScreen(m_dpy); -+ int w = DisplayWidth(m_dpy, m_nScreen); -+ int h = DisplayHeight(m_dpy, m_nScreen); - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); - } - -@@ -819,11 +822,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - Colormap cmap; - XSetWindowAttributes swa; - XVisualInfo *vi; -+ int x0 = 0; -+ int y0 = 0; - - XOutput *out = g_xrandr.GetOutput(output); - if (!out) - out = g_xrandr.GetOutput(m_currentOutput); -- m_nScreen = out->screen; -+ if (out) -+ { -+ m_nScreen = out->screen; -+ x0 = out->x; -+ y0 = out->y; -+ } -+ - vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - -@@ -842,7 +853,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; - - m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -- out->x, out->y, width, height, 0, vi->depth, -+ x0, y0, width, height, 0, vi->depth, - InputOutput, vi->visual, - mask, &swa); - --- -1.9.1 - - -From aaeedaed5098ef4771c643a8d61b5d641e20c8ae Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 23 Mar 2013 15:13:32 +0100 -Subject: [PATCH 50/96] X11: create parent window - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 69 +++++++++++++++++++++++-------------- - xbmc/windowing/X11/WinSystemX11.h | 2 +- - 2 files changed, 44 insertions(+), 27 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 2adf8a0..07f3f3d 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -55,6 +55,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase() - m_glContext = NULL; - m_dpy = NULL; - m_glWindow = 0; -+ m_mainWindow = 0; - m_bWasFullScreenBeforeMinimize = false; - m_minimized = false; - m_bIgnoreNextFocusMessage = false; -@@ -132,7 +133,7 @@ bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RES - - bool CWinSystemX11::DestroyWindow() - { -- if (!m_glWindow) -+ if (!m_mainWindow) - return true; - - if (m_glContext) -@@ -143,19 +144,21 @@ bool CWinSystemX11::DestroyWindow() - - if (m_invisibleCursor) - { -- XUndefineCursor(m_dpy, m_glWindow); -+ XUndefineCursor(m_dpy, m_mainWindow); - XFreeCursor(m_dpy, m_invisibleCursor); - m_invisibleCursor = 0; - } - - CWinEventsX11Imp::Quit(); - -- XUnmapWindow(m_dpy, m_glWindow); -+ XUnmapWindow(m_dpy, m_mainWindow); - XSync(m_dpy,TRUE); - XUngrabKeyboard(m_dpy, CurrentTime); - XUngrabPointer(m_dpy, CurrentTime); - XDestroyWindow(m_dpy, m_glWindow); -+ XDestroyWindow(m_dpy, m_mainWindow); - m_glWindow = 0; -+ m_mainWindow = 0; - - if (m_icon) - XFreePixmap(m_dpy, m_icon); -@@ -225,7 +228,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - OnLostDevice(); - m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); -- if (m_glWindow) -+ if (m_mainWindow) - return true; - } - } -@@ -503,9 +506,9 @@ bool CWinSystemX11::RefreshGlxContext(bool force) - void CWinSystemX11::ShowOSMouse(bool show) - { - if (show) -- XUndefineCursor(m_dpy,m_glWindow); -+ XUndefineCursor(m_dpy,m_mainWindow); - else if (m_invisibleCursor) -- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); -+ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); - } - - void CWinSystemX11::ResetOSScreensaver() -@@ -588,10 +591,10 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered) - int result = -1; - while (result != GrabSuccess && result != AlreadyGrabbed) - { -- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -+ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - XbmcThreads::ThreadSleep(100); - } -- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } - else - { -@@ -609,7 +612,7 @@ bool CWinSystemX11::Minimize() - g_graphicsContext.ToggleFullScreenRoot(); - } - -- XIconifyWindow(m_dpy, m_glWindow, m_nScreen); -+ XIconifyWindow(m_dpy, m_mainWindow, m_nScreen); - - m_minimized = true; - return true; -@@ -620,13 +623,13 @@ bool CWinSystemX11::Restore() - } - bool CWinSystemX11::Hide() - { -- XUnmapWindow(m_dpy, m_glWindow); -+ XUnmapWindow(m_dpy, m_mainWindow); - XSync(m_dpy, False); - return true; - } - bool CWinSystemX11::Show(bool raise) - { -- XMapWindow(m_dpy, m_glWindow); -+ XMapWindow(m_dpy, m_mainWindow); - XSync(m_dpy, False); - m_minimized = false; - return true; -@@ -776,7 +779,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - bool mouseActive = false; - float mouseX, mouseY; - -- if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) -+ if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) - { - mouseActive = g_Mouse.IsActive(); - if (mouseActive) -@@ -785,7 +788,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - int root_x_return, root_y_return; - int win_x_return, win_y_return; - unsigned int mask_return; -- bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, -+ bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return, - &root_x_return, &root_y_return, - &win_x_return, &win_y_return, - &mask_return); -@@ -804,7 +807,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - - // create main window -- if (!m_glWindow) -+ if (!m_mainWindow) - { - EnableSystemScreenSaver(false); - -@@ -845,22 +848,31 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - swa.border_pixel = fullscreen ? 0 : 5; - swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.colormap = cmap; -- swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | - ButtonPressMask | ButtonReleaseMask | PointerMotionMask | - PropertyChangeMask | StructureNotifyMask | KeymapStateMask | - EnterWindowMask | LeaveWindowMask | ExposureMask; - unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; - -- m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -+ m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), - x0, y0, width, height, 0, vi->depth, - InputOutput, vi->visual, - mask, &swa); - -+ swa.override_redirect = False; -+ swa.border_pixel = 0; -+ swa.event_mask = 0; -+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap; -+ -+ m_glWindow = XCreateWindow(m_dpy, m_mainWindow, -+ 0, 0, width, height, 0, vi->depth, -+ InputOutput, vi->visual, -+ mask, &swa); -+ - if (fullscreen && hasWM) - { - Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); -- XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); -+ XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); - } - - // define invisible cursor -@@ -869,14 +881,14 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - static char noData[] = { 0,0,0,0,0,0,0,0 }; - black.red = black.green = black.blue = 0; - -- bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); -+ bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8); - m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, - &black, &black, 0, 0); - XFreePixmap(m_dpy, bitmapNoData); -- XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); -+ XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); - - //init X11 events -- CWinEventsX11Imp::Init(m_dpy, m_glWindow); -+ CWinEventsX11Imp::Init(m_dpy, m_mainWindow); - - changeWindow = true; - changeSize = true; -@@ -889,13 +901,17 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - - if (changeSize || changeWindow) - { -+ XResizeWindow(m_dpy, m_mainWindow, width, height); -+ } -+ -+ if ((width != m_nWidth) || (height != m_nHeight) || changeWindow) -+ { - XResizeWindow(m_dpy, m_glWindow, width, height); - } - - if (changeWindow) - { - m_icon = None; -- if (!fullscreen) - { - CreateIconPixmap(); - XWMHints *wm_hints; -@@ -912,21 +928,22 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - wm_hints->flags = StateHint | IconPixmapHint; - - XSync(m_dpy,False); -- XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -+ XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, - NULL, 0, NULL, wm_hints, - NULL); - XFree(wm_hints); - - // register interest in the delete window message - Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); -- XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); -+ XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1); - } - XMapRaised(m_dpy, m_glWindow); -+ XMapRaised(m_dpy, m_mainWindow); - XSync(m_dpy,TRUE); - - if (changeWindow && mouseActive) - { -- XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); -+ XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); - } - - if (fullscreen) -@@ -934,10 +951,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - int result = -1; - while (result != GrabSuccess && result != AlreadyGrabbed) - { -- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -+ result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - XbmcThreads::ThreadSleep(100); - } -- XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } - - CDirtyRegionList dr; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 2a1fb41..e8993f1 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -81,7 +81,7 @@ protected: - void OnLostDevice(); - bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); - -- Window m_glWindow; -+ Window m_glWindow, m_mainWindow; - GLXContext m_glContext; - Display* m_dpy; - Cursor m_invisibleCursor; --- -1.9.1 - - -From 085ec3cdb8b45b3885a7fc0cec7355ca211c055f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Mar 2013 12:30:12 +0100 -Subject: [PATCH 51/96] X11: use system key repeat rate instead of hardcoded - one, taken from 58fd64b194e38b73b5f3132744bab35e994e7441 - ---- - xbmc/windowing/WinEventsX11.cpp | 58 +++++++++++++---------------------------- - xbmc/windowing/WinEventsX11.h | 5 +--- - 2 files changed, 19 insertions(+), 44 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 263cb5a..09f56ff 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; - WinEvents->m_xrrEventPending = false; -- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - - // open input method - char *old_locale = NULL, *old_modifiers = NULL; -@@ -328,20 +327,6 @@ bool CWinEventsX11Imp::MessagePump() - memset(&xevent, 0, sizeof (XEvent)); - XNextEvent(WinEvents->m_display, &xevent); - -- // ignore events generated by auto-repeat -- if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) -- { -- XEvent peekevent; -- XPeekEvent(WinEvents->m_display, &peekevent); -- if ((peekevent.type == KeyPress) && -- (peekevent.xkey.keycode == xevent.xkey.keycode) && -- ((peekevent.xkey.time - xevent.xkey.time) < 2)) -- { -- XNextEvent(WinEvents->m_display, &peekevent); -- continue; -- } -- } -- - if (XFilterEvent(&xevent, None)) - continue; - -@@ -364,7 +349,6 @@ bool CWinEventsX11Imp::MessagePump() - if (WinEvents->m_xic) - XSetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = true; -- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - WinEvents->m_keymodState = 0; - if (serial == xevent.xfocus.serial) - break; -@@ -377,7 +361,6 @@ bool CWinEventsX11Imp::MessagePump() - if (WinEvents->m_xic) - XUnsetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = false; -- memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); - serial = xevent.xfocus.serial; - break; -@@ -433,7 +416,7 @@ bool CWinEventsX11Imp::MessagePump() - { - newEvent.key.keysym.unicode = keybuf[0]; - } -- ret |= ProcessKey(newEvent, 500); -+ ret |= ProcessKey(newEvent); - break; - } - -@@ -472,7 +455,7 @@ bool CWinEventsX11Imp::MessagePump() - newEvent.key.keysym.unicode = keys[i]; - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; -- ret |= ProcessKey(newEvent, 500); -+ ret |= ProcessKey(newEvent); - } - if (keys.length() > 0) - { -@@ -483,7 +466,7 @@ bool CWinEventsX11Imp::MessagePump() - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; - -- ret |= ProcessKey(newEvent, 500); -+ ret |= ProcessKey(newEvent); - } - break; - } -@@ -494,7 +477,7 @@ bool CWinEventsX11Imp::MessagePump() - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; -- ret |= ProcessKey(newEvent, 500); -+ ret |= ProcessKey(newEvent); - break; - } - -@@ -504,6 +487,18 @@ bool CWinEventsX11Imp::MessagePump() - - case KeyRelease: - { -+ // if we have a queued press directly after, this is a repeat -+ if( XEventsQueued( WinEvents->m_display, QueuedAfterReading ) ) -+ { -+ XEvent next_event; -+ XPeekEvent( WinEvents->m_display, &next_event ); -+ if(next_event.type == KeyPress -+ && next_event.xkey.window == xevent.xkey.window -+ && next_event.xkey.keycode == xevent.xkey.keycode -+ && (next_event.xkey.time - xevent.xkey.time < 2) ) -+ continue; -+ } -+ - XBMC_Event newEvent; - KeySym xkeysym; - memset(&newEvent, 0, sizeof(newEvent)); -@@ -513,7 +508,7 @@ bool CWinEventsX11Imp::MessagePump() - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; -- ret |= ProcessKey(newEvent, 0); -+ ret |= ProcessKey(newEvent); - break; - } - -@@ -589,8 +584,6 @@ bool CWinEventsX11Imp::MessagePump() - - }// while - -- ret |= ProcessKeyRepeat(); -- - #if defined(HAS_XRANDR) - if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) - { -@@ -635,7 +628,7 @@ size_t CWinEventsX11Imp::GetQueueSize() - return ret; - } - --bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) -+bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) - { - if (event.type == XBMC_KEYDOWN) - { -@@ -673,8 +666,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) - break; - } - event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -- memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); -- WinEvents->m_repeatKeyTimeout.Set(repeatDelay); - - bool ret = ProcessShortcuts(event); - if (ret) -@@ -715,7 +706,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event, int repeatDelay) - break; - } - event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -- memset(&(WinEvents->m_lastKey), 0, sizeof(event)); - } - - return g_application.OnEvent(event); -@@ -738,18 +728,6 @@ bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) - return false; - } - --bool CWinEventsX11Imp::ProcessKeyRepeat() --{ -- if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) -- { -- if (WinEvents->m_repeatKeyTimeout.IsTimePast()) -- { -- return ProcessKey(WinEvents->m_lastKey, 10); -- } -- } -- return false; --} -- - XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) - { - // try direct mapping first -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index c69169c..6429291 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -47,8 +47,7 @@ public: - - protected: - static XBMCKey LookupXbmcKeySym(KeySym keysym); -- static bool ProcessKey(XBMC_Event &event, int repeatDelay); -- static bool ProcessKeyRepeat(); -+ static bool ProcessKey(XBMC_Event &event); - static bool ProcessShortcuts(XBMC_Event& event); - static CWinEventsX11Imp *WinEvents; - Display *m_display; -@@ -58,8 +57,6 @@ protected: - size_t m_keybuf_len; - XIM m_xim; - XIC m_xic; -- XBMC_Event m_lastKey; -- XbmcThreads::EndTime m_repeatKeyTimeout; - std::map m_symLookupTable; - int m_keymodState; - bool m_structureChanged; --- -1.9.1 - - -From dcb0640d4f41cc444f6b212799505d1d122170a7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Mar 2013 16:04:48 +0100 -Subject: [PATCH 52/96] linux: use CLOCK_MONOTONIC_RAW as this is not subject - to NTP - ---- - xbmc/threads/SystemClock.cpp | 2 +- - xbmc/utils/TimeUtils.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/threads/SystemClock.cpp b/xbmc/threads/SystemClock.cpp -index 657a154..35e3abf 100644 ---- a/xbmc/threads/SystemClock.cpp -+++ b/xbmc/threads/SystemClock.cpp -@@ -43,7 +43,7 @@ namespace XbmcThreads - now_time = (uint64_t)timeGetTime(); - #else - struct timespec ts = {}; -- clock_gettime(CLOCK_MONOTONIC, &ts); -+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - now_time = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); - #endif - if (!start_time_set) -diff --git a/xbmc/utils/TimeUtils.cpp b/xbmc/utils/TimeUtils.cpp -index c06b8c5..4390d2e 100644 ---- a/xbmc/utils/TimeUtils.cpp -+++ b/xbmc/utils/TimeUtils.cpp -@@ -43,7 +43,7 @@ int64_t CurrentHostCounter(void) - return( (int64_t)PerformanceCount.QuadPart ); - #else - struct timespec now; -- clock_gettime(CLOCK_MONOTONIC, &now); -+ clock_gettime(CLOCK_MONOTONIC_RAW, &now); - return( ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec ); - #endif - } --- -1.9.1 - - -From feb8150d84f4b83dbba365cad5eafa8831914654 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Mar 2013 15:18:53 +0100 -Subject: [PATCH 53/96] OMXPlayer: some caching fixes for pvr - ---- - xbmc/cores/omxplayer/OMXPlayer.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index 0b80be5..8eab2fd 100644 ---- a/xbmc/cores/omxplayer/OMXPlayer.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp -@@ -2548,7 +2548,8 @@ void COMXPlayer::HandleMessages() - m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true)); - - m_playSpeed = speed; -- m_caching = CACHESTATE_DONE; -+ if (m_caching != CACHESTATE_PVR && m_playSpeed != DVD_PLAYSPEED_NORMAL) -+ m_caching = CACHESTATE_DONE; - m_clock.SetSpeed(speed); - m_av_clock.OMXSetSpeed(speed); - m_av_clock.OMXPause(); --- -1.9.1 - - -From c66609611e7e6da48d14069e0a047bca7ea1b694 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Mar 2013 20:50:59 +0100 -Subject: [PATCH 54/96] fix incorrect display of fps when dr kicks in - ---- - xbmc/Application.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 5a24ffb..a0ca53a 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2320,10 +2320,11 @@ void CApplication::Render() - if (frameTime < singleFrameTime) - Sleep(singleFrameTime - frameTime); - } -- m_lastFrameTime = XbmcThreads::SystemClockMillis(); - - if (flip) - g_graphicsContext.Flip(dirtyRegions); -+ -+ m_lastFrameTime = XbmcThreads::SystemClockMillis(); - CTimeUtils::UpdateFrameTime(flip); - - g_renderManager.UpdateResolution(); --- -1.9.1 - - -From 33ee35d980ddf952da1d577903154e19f8bad525 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 13 Apr 2013 08:32:06 +0200 -Subject: [PATCH 55/96] X11: fix mouse coverage - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++++--- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 07f3f3d..2acb36d 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -583,10 +583,10 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining) - - void CWinSystemX11::NotifyMouseCoverage(bool covered) - { -- if (!m_bFullScreen) -+ if (!m_bFullScreen || !m_mainWindow) - return; - -- if (covered) -+ if (covered && !m_bIsGrabbed) - { - int result = -1; - while (result != GrabSuccess && result != AlreadyGrabbed) -@@ -595,11 +595,13 @@ void CWinSystemX11::NotifyMouseCoverage(bool covered) - XbmcThreads::ThreadSleep(100); - } - XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ m_bIsGrabbed = true; - } -- else -+ else if (!covered && m_bIsGrabbed) - { - XUngrabKeyboard(m_dpy, CurrentTime); - XUngrabPointer(m_dpy, CurrentTime); -+ m_bIsGrabbed = false; - } - } - -@@ -955,7 +957,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - XbmcThreads::ThreadSleep(100); - } - XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ m_bIsGrabbed = true; - } -+ else -+ m_bIsGrabbed = false; - - CDirtyRegionList dr; - RefreshGlxContext(!m_currentOutput.Equals(output)); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index e8993f1..5cccfb7 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -90,6 +90,7 @@ protected: - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -+ bool m_bIsGrabbed; - int m_RREventBase; - CCriticalSection m_resourceSection; - std::vector m_resources; --- -1.9.1 - - -From 6b23cb08d6e6b72909750bd69630be1a4b381895 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 8 May 2013 13:14:58 +0200 -Subject: [PATCH 56/96] X11: fix incorrectly used screen num in desktop - resolution - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 2acb36d..101ba98 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -268,9 +268,9 @@ void CWinSystemX11::UpdateResolutions() - XMode mode = g_xrandr.GetCurrentMode(currentMonitor); - m_bIsRotated = out->isRotated; - if (!m_bIsRotated) -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.w, mode.h, mode.hz); -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); - else -- UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), out->screen, mode.h, mode.w, mode.hz); -+ UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; - } -@@ -305,6 +305,7 @@ void CWinSystemX11::UpdateResolutions() - CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", - mode.id.c_str(), mode.name.c_str(), mode.hz, mode.w, mode.h); - RESOLUTION_INFO res; -+ res.iScreen = 0; // not used by X11 - res.iWidth = mode.w; - res.iHeight = mode.h; - res.iScreenWidth = mode.w; --- -1.9.1 - - -From 30326f85a2b363432abe0979d09f5eadd8520db1 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 9 May 2013 12:07:09 +0200 -Subject: [PATCH 57/96] X11: do not overwrite user selected monitor with - fallback - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 31 ++++++++++++++----------------- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 15 insertions(+), 17 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 101ba98..c614c9b 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -172,7 +172,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - && m_nHeight == newHeight) - return true; - -- if (!SetWindow(newWidth, newHeight, false, CSettings::Get().GetString("videoscreen.monitor"))) -+ if (!SetWindow(newWidth, newHeight, false, m_userOutput)) - { - return false; - } -@@ -180,7 +180,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - m_nWidth = newWidth; - m_nHeight = newHeight; - m_bFullScreen = false; -- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); -+ m_currentOutput = m_userOutput; - - return false; - } -@@ -234,13 +234,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - #endif - -- if (!SetWindow(res.iWidth, res.iHeight, fullScreen, CSettings::Get().GetString("videoscreen.monitor"))) -+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, m_userOutput)) - return false; - - m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_bFullScreen = fullScreen; -- m_currentOutput = CSettings::Get().GetString("videoscreen.monitor"); -+ m_currentOutput = m_userOutput; - - return true; - } -@@ -250,34 +250,32 @@ void CWinSystemX11::UpdateResolutions() - CWinSystemBase::UpdateResolutions(); - - #if defined(HAS_XRANDR) -- CStdString currentMonitor; - int numScreens = XScreenCount(m_dpy); - g_xrandr.SetNumScreens(numScreens); - if(g_xrandr.Query(true)) - { -- currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); -+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); - // check if the monitor is connected -- XOutput *out = g_xrandr.GetOutput(currentMonitor); -+ XOutput *out = g_xrandr.GetOutput(m_userOutput); - if (!out) - { - // choose first output -- currentMonitor = g_xrandr.GetModes()[0].name; -- out = g_xrandr.GetOutput(currentMonitor); -- CSettings::Get().SetString("videoscreen.monitor", currentMonitor); -+ m_userOutput = g_xrandr.GetModes()[0].name; -+ out = g_xrandr.GetOutput(m_userOutput); - } -- XMode mode = g_xrandr.GetCurrentMode(currentMonitor); -+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); - m_bIsRotated = out->isRotated; - if (!m_bIsRotated) - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); - else - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); - CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strId = mode.id; -- CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = currentMonitor; -+ CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP).strOutput = m_userOutput; - } - else - #endif - { -- CSettings::Get().SetString("videoscreen.monitor", "Default"); -+ m_userOutput = "No Output"; - m_nScreen = DefaultScreen(m_dpy); - int w = DisplayWidth(m_dpy, m_nScreen); - int h = DisplayHeight(m_dpy, m_nScreen); -@@ -291,7 +289,7 @@ void CWinSystemX11::UpdateResolutions() - - CLog::Log(LOGINFO, "Available videomodes (xrandr):"); - -- XOutput *out = g_xrandr.GetOutput(currentMonitor); -+ XOutput *out = g_xrandr.GetOutput(m_userOutput); - string modename = ""; - - if (out != NULL) -@@ -691,9 +689,8 @@ void CWinSystemX11::NotifyXRREvent() - } - m_bIsInternalXrr = false; - -- CStdString currentOutput = CSettings::Get().GetString("videoscreen.monitor"); -- XOutput *out = g_xrandr.GetOutput(currentOutput); -- XMode mode = g_xrandr.GetCurrentMode(currentOutput); -+ XOutput *out = g_xrandr.GetOutput(m_userOutput); -+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); - - if (out) - CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 5cccfb7..1b658e2 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -96,6 +96,7 @@ protected: - std::vector m_resources; - uint64_t m_dpyLostTime; - CStdString m_currentOutput; -+ CStdString m_userOutput; - bool m_windowDirty; - bool m_bIsInternalXrr; - bool m_newGlContext; --- -1.9.1 - - -From 640834140bad33d23f0d0228ac4a6f022405f276 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 12 May 2013 10:50:30 +0200 -Subject: [PATCH 58/96] xrandr: add turn on/off to wrapper - ---- - xbmc/windowing/X11/XRandR.cpp | 78 +++++++++++++++++++++++++++++++++++++++---- - xbmc/windowing/X11/XRandR.h | 6 ++-- - 2 files changed, 75 insertions(+), 9 deletions(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 4355ef7..223472c 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -29,6 +29,7 @@ - #include "utils/XBMCTinyXML.h" - #include "utils/StringUtils.h" - #include "../xbmc/utils/log.h" -+#include "threads/SystemClock.h" - - #if defined(TARGET_FREEBSD) - #include -@@ -45,7 +46,7 @@ CXRandR::CXRandR(bool query) - Query(); - } - --bool CXRandR::Query(bool force) -+bool CXRandR::Query(bool force, bool ignoreoff) - { - if (!force) - if (m_bInit) -@@ -62,13 +63,13 @@ bool CXRandR::Query(bool force) - bool success = false; - for(unsigned int screennum=0; screennumAttribute("current"), "true") == 0); - xoutput.modes.push_back(xmode); - if (xmode.isCurrent) -- { - hascurrent = true; -- } - } -- if (hascurrent) -+ if (hascurrent || !ignoreoff) - m_outputs.push_back(xoutput); - else - CLog::Log(LOGWARNING, "CXRandR::Query - output %s has no current mode, assuming disconnected", xoutput.name.c_str()); -@@ -148,6 +147,71 @@ bool CXRandR::Query(bool force, int screennum) - return m_outputs.size() > 0; - } - -+bool CXRandR::TurnOffOutput(CStdString name) -+{ -+ CStdString cmd; -+ cmd = getenv("XBMC_BIN_HOME"); -+ cmd += "/xbmc-xrandr"; -+ cmd.AppendFormat(" --output %s --off", name.c_str()); -+ -+ int status = system(cmd.c_str()); -+ if (status == -1) -+ return false; -+ -+ if (WEXITSTATUS(status) != 0) -+ return false; -+ -+ return true; -+} -+ -+bool CXRandR::TurnOnOutput(CStdString name) -+{ -+ XOutput *output = GetOutput(name); -+ if (!output) -+ return false; -+ -+ XMode mode = GetCurrentMode(output->name); -+ if (mode.isCurrent) -+ return true; -+ -+ // get preferred mode -+ for (unsigned int j = 0; j < m_outputs.size(); j++) -+ { -+ if (m_outputs[j].name == output->name) -+ { -+ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++) -+ { -+ if (m_outputs[j].modes[i].isPreferred) -+ { -+ mode = m_outputs[j].modes[i]; -+ break; -+ } -+ } -+ } -+ } -+ -+ if (!mode.isPreferred) -+ return false; -+ -+ if (!SetMode(*output, mode)) -+ return false; -+ -+ XbmcThreads::EndTime timeout(5000); -+ while (!timeout.IsTimePast()) -+ { -+ if (!Query(true)) -+ return false; -+ -+ output = GetOutput(name); -+ if (output && output->h > 0) -+ return true; -+ -+ Sleep(200); -+ } -+ -+ return false; -+} -+ - std::vector CXRandR::GetModes(void) - { - Query(); -@@ -161,7 +225,7 @@ void CXRandR::SaveState() - - bool CXRandR::SetMode(XOutput output, XMode mode) - { -- if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) -+ if ((output.name == "" && mode.id == "")) - return true; - - Query(); -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index d37838a..059062f 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -94,8 +94,8 @@ class CXRandR - { - public: - CXRandR(bool query=false); -- bool Query(bool force=false); -- bool Query(bool force, int screennum); -+ bool Query(bool force=false, bool ignoreoff=true); -+ bool Query(bool force, int screennum, bool ignoreoff=true); - std::vector GetModes(void); - XMode GetCurrentMode(CStdString outputName); - XOutput *GetOutput(CStdString outputName); -@@ -104,6 +104,8 @@ public: - void SaveState(); - void SetNumScreens(unsigned int num); - bool IsOutputConnected(CStdString name); -+ bool TurnOffOutput(CStdString name); -+ bool TurnOnOutput(CStdString name); - //bool Has1080i(); - //bool Has1080p(); - //bool Has720p(); --- -1.9.1 - - -From eb767b125450fc14c15cfe05dec4b696e1439bbe Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 19 May 2013 12:55:35 +0200 -Subject: [PATCH 59/96] xrandr: add GetPreferredMode to wrapper - ---- - xbmc/windowing/X11/XRandR.cpp | 23 +++++++++++++++++++++++ - xbmc/windowing/X11/XRandR.h | 1 + - 2 files changed, 24 insertions(+) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 223472c..62003f5 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -347,6 +347,29 @@ XMode CXRandR::GetCurrentMode(CStdString outputName) - return result; - } - -+XMode CXRandR::GetPreferredMode(CStdString outputName) -+{ -+ Query(); -+ XMode result; -+ -+ for (unsigned int j = 0; j < m_outputs.size(); j++) -+ { -+ if (m_outputs[j].name == outputName || outputName == "") -+ { -+ for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++) -+ { -+ if (m_outputs[j].modes[i].isPreferred) -+ { -+ result = m_outputs[j].modes[i]; -+ break; -+ } -+ } -+ } -+ } -+ -+ return result; -+} -+ - void CXRandR::LoadCustomModeLinesToAllOutputs(void) - { - Query(); -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 059062f..ab7cc63 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -98,6 +98,7 @@ public: - bool Query(bool force, int screennum, bool ignoreoff=true); - std::vector GetModes(void); - XMode GetCurrentMode(CStdString outputName); -+ XMode GetPreferredMode(CStdString outputName); - XOutput *GetOutput(CStdString outputName); - bool SetMode(XOutput output, XMode mode); - void LoadCustomModeLinesToAllOutputs(void); --- -1.9.1 - - -From 24471c2dd68d3bf52d1a5204d73fb48ac6b4d189 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 11 May 2013 17:12:12 +0200 -Subject: [PATCH 60/96] X11: multi-head improvement - poll for desired output - if we do not get an xrr event - ---- - language/English/strings.po | 9 +++- - system/settings/settings.xml | 8 +++- - xbmc/settings/DisplaySettings.cpp | 4 ++ - xbmc/windowing/WinEventsX11.cpp | 6 +++ - xbmc/windowing/WinEventsX11.h | 1 + - xbmc/windowing/X11/WinSystemX11.cpp | 83 +++++++++++++++++++++++++++++++++---- - xbmc/windowing/X11/WinSystemX11.h | 2 +- - xbmc/windowing/X11/XRandR.cpp | 6 ++- - 8 files changed, 106 insertions(+), 13 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 685847c..9cc2090 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -6558,7 +6558,7 @@ msgctxt "#14071" - msgid "Allow file renaming and deletion" - msgstr "" - --#empty strings from id 14072 to 14073 -+#empty strings from id 14073 to 14073 - - msgctxt "#14074" - msgid "Set timezone" -@@ -6696,7 +6696,12 @@ msgctxt "#14101" - msgid "Acceleration" - msgstr "" - --#empty strings from id 14102 to 15011 -+#: xbmc/settings/settings.xml -+msgctxt "#14102" -+msgid "Switch off other Monitor" -+msgstr "" -+ -+#empty strings from id 14103 to 15011 - - #: xbmc/video/VideoDatabase.cpp - msgctxt "#15012" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index fba4561..798be52 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2252,7 +2252,7 @@ - - - -- HAS_GLX -+ HAS_GLX - 0 - Default - -@@ -2260,6 +2260,11 @@ - - - -+ -+ HAS_GLX -+ 0 -+ false -+ - - 0 - 0 -@@ -2312,6 +2317,7 @@ - - - -+ !HAS_GLX - 1 - false - -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index db2f667..efb6cb1 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -274,6 +274,10 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - m_resolutionChangeAborted = false; - } - } -+ else if (settingId == "videoscreen.monitorsingle") -+ { -+ g_Windowing.UpdateResolutions(); -+ } - - return true; - } -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 09f56ff..908c8b6 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -213,6 +213,7 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; - WinEvents->m_xrrEventPending = false; -+ WinEvents->m_xrrPollTimer.Set(3000); - - // open input method - char *old_locale = NULL, *old_modifiers = NULL; -@@ -591,6 +592,11 @@ bool CWinEventsX11Imp::MessagePump() - g_Windowing.NotifyXRREvent(); - WinEvents->m_xrrEventPending = false; - } -+ else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast()) -+ { -+ g_Windowing.NotifyXRREvent(true); -+ WinEvents->m_xrrPollTimer.Set(3000); -+ } - #endif - - #ifdef HAS_SDL_JOYSTICK -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 6429291..91a604f 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -62,5 +62,6 @@ protected: - bool m_structureChanged; - int m_RREventBase; - XbmcThreads::EndTime m_xrrFailSafeTimer; -+ XbmcThreads::EndTime m_xrrPollTimer; - bool m_xrrEventPending; - }; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c614c9b..b3fe510 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -252,18 +252,62 @@ void CWinSystemX11::UpdateResolutions() - #if defined(HAS_XRANDR) - int numScreens = XScreenCount(m_dpy); - g_xrandr.SetNumScreens(numScreens); -- if(g_xrandr.Query(true)) -+ -+ bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle"); -+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); -+ if (m_userOutput.Equals("Default")) -+ switchOnOff = false; -+ -+ if(g_xrandr.Query(true, !switchOnOff)) - { -- m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); - // check if the monitor is connected -- XOutput *out = g_xrandr.GetOutput(m_userOutput); -+ // might take a while when connected to a receiver -+ XbmcThreads::EndTime timeout(3000); -+ XOutput *out = NULL; -+ while (!m_userOutput.Equals("Default") && !timeout.IsTimePast()) -+ { -+ out = g_xrandr.GetOutput(m_userOutput); -+ if (out) -+ { -+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); -+ if (mode.isCurrent || switchOnOff) -+ break; -+ else -+ { -+ out = NULL; -+ break; -+ } -+ } -+ -+ Sleep(500); -+ if (!g_xrandr.Query(true, !switchOnOff)) -+ break; -+ } - if (!out) - { -- // choose first output - m_userOutput = g_xrandr.GetModes()[0].name; - out = g_xrandr.GetOutput(m_userOutput); - } -+ -+ // switch on output -+ if(switchOnOff) -+ g_xrandr.TurnOnOutput(m_userOutput); -+ -+ // switch off other outputs if desired -+ if (switchOnOff) -+ { -+ std::vector outputs = g_xrandr.GetModes(); -+ for (int i=0; iisRotated; - if (!m_bIsRotated) - UpdateDesktopResolution(CDisplaySettings::Get().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); -@@ -382,7 +426,9 @@ bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) - void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) - { - vector outs; -+ g_xrandr.Query(true); - outs = g_xrandr.GetModes(); -+ outputs->push_back("Default"); - for(unsigned int i=0; ipush_back(outs[i].name); -@@ -669,14 +715,34 @@ void CWinSystemX11::CheckDisplayEvents() - #endif - } - --void CWinSystemX11::NotifyXRREvent() -+void CWinSystemX11::NotifyXRREvent(bool poll) - { -- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -+ // we may not get an event if desired monitor becomes available -+ // hence we need to poll -+ if (poll) -+ { -+ CStdString output = CSettings::Get().GetString("videoscreen.monitor"); -+ if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default")) -+ return; -+ -+ int numScreens = XScreenCount(m_dpy); -+ g_xrandr.SetNumScreens(numScreens); -+ g_xrandr.Query(true); -+ if (!g_xrandr.IsOutputConnected(output)) -+ return; -+ -+ // if output is turned off by user, respect it -+ XMode mode = g_xrandr.GetCurrentMode(output); -+ if (!mode.isCurrent) -+ return; -+ } -+ -+ CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll); - m_windowDirty = true; - - CSingleLock lock(g_graphicsContext); - -- if (!g_xrandr.Query(true)) -+ if (!g_xrandr.Query(!poll)) - { - CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); - return; -@@ -703,7 +769,8 @@ void CWinSystemX11::NotifyXRREvent() - bool found(false); - for (i = RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); ++i) - { -- if (CDisplaySettings::Get().GetResolutionInfo(i).strId == mode.id) -+ res = CDisplaySettings::Get().GetResolutionInfo(i); -+ if (CDisplaySettings::Get().GetResolutionInfo(i).strId.Equals(mode.id)) - { - found = true; - break; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 1b658e2..7ec5be4 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -70,7 +70,7 @@ public: - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -- void NotifyXRREvent(); -+ void NotifyXRREvent(bool poll = false); - void GetConnectedOutputs(std::vector *outputs); - bool IsCurrentOutput(CStdString output); - void NotifyMouseCoverage(bool covered); -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 62003f5..8525ede 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -149,10 +149,14 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) - - bool CXRandR::TurnOffOutput(CStdString name) - { -+ XOutput *output = GetOutput(name); -+ if (!output) -+ return false; -+ - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; -- cmd.AppendFormat(" --output %s --off", name.c_str()); -+ cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str()); - - int status = system(cmd.c_str()); - if (status == -1) --- -1.9.1 - - -From ca045d99ebbe5f35ea3d39a8f2356f53533a7269 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 15 May 2013 09:14:34 +0200 -Subject: [PATCH 61/96] X11: ignore mouse move event form other windows - ---- - xbmc/windowing/WinEventsX11.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 908c8b6..938ad26 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -328,7 +328,7 @@ bool CWinEventsX11Imp::MessagePump() - memset(&xevent, 0, sizeof (XEvent)); - XNextEvent(WinEvents->m_display, &xevent); - -- if (XFilterEvent(&xevent, None)) -+ if (XFilterEvent(&xevent, WinEvents->m_window)) - continue; - - switch (xevent.type) -@@ -529,6 +529,8 @@ bool CWinEventsX11Imp::MessagePump() - - case MotionNotify: - { -+ if (xevent.xmotion.window != WinEvents->m_window) -+ break; - XBMC_Event newEvent; - memset(&newEvent, 0, sizeof(newEvent)); - newEvent.type = XBMC_MOUSEMOTION; --- -1.9.1 - - -From 13b504eb4cb6bd21a6c1a3b658a9ddc05a18e252 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 11 Jun 2013 16:20:29 +0200 -Subject: [PATCH 62/96] renderer: allow some lateness within vblank interval - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++-- - xbmc/cores/VideoRenderers/RenderManager.h | 1 + - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 9e2c055..8dc8a91 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -378,6 +378,8 @@ void CXBMCRenderManager::FrameFinish() - if(g_graphicsContext.IsFullScreenVideo()) - WaitPresentTime(m.timestamp); - -+ m_clock_framefinish = GetPresentTime(); -+ - { CSingleLock lock(m_presentlock); - - if(m_presentstep == PRESENT_FRAME) -@@ -1030,6 +1032,12 @@ void CXBMCRenderManager::PrepareNextRender() - - double clocktime = GetPresentTime(); - double frametime = 1.0 / GetMaximumFPS(); -+ double correction = 0.0; -+ int fps = g_VideoReferenceClock.GetRefreshRate(); -+ if((fps > 0) && g_graphicsContext.IsFullScreenVideo() && (clocktime != m_clock_framefinish)) -+ { -+ correction = frametime; -+ } - - /* see if any future queued frames are already due */ - std::deque::reverse_iterator curr, prev; -@@ -1038,8 +1046,8 @@ void CXBMCRenderManager::PrepareNextRender() - ++prev; - while (prev != m_queued.rend()) - { -- if(clocktime > m_Queue[*prev].timestamp /* previous frame is late */ -- && clocktime > m_Queue[*curr].timestamp - frametime) /* selected frame is close to it's display time */ -+ if(clocktime > m_Queue[*prev].timestamp + correction /* previous frame is late */ -+ && clocktime > m_Queue[*curr].timestamp - frametime + correction) /* selected frame is close to it's display time */ - break; - ++curr; - ++prev; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 949c652..d84ff6c 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -252,6 +252,7 @@ protected: - XbmcThreads::ConditionVariable m_presentevent; - CCriticalSection m_presentlock; - CEvent m_flushEvent; -+ double m_clock_framefinish; - - - OVERLAY::CRenderer m_overlays; --- -1.9.1 - - -From e7fb60e0d020111598f477e775c5c2aaac7f7aa5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 16 Jun 2013 13:22:58 +0200 -Subject: [PATCH 63/96] X11: another fix for mouse coverage - ---- - xbmc/windowing/WinEventsX11.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 938ad26..e4ca56d 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -515,14 +515,16 @@ bool CWinEventsX11Imp::MessagePump() - - case EnterNotify: - { -- g_Windowing.NotifyMouseCoverage(true); -+ if (xevent.xcrossing.mode == NotifyNormal) -+ g_Windowing.NotifyMouseCoverage(true); - break; - } - - // lose mouse coverage - case LeaveNotify: - { -- g_Windowing.NotifyMouseCoverage(false); -+ if (xevent.xcrossing.mode == NotifyNormal) -+ g_Windowing.NotifyMouseCoverage(false); - g_Mouse.SetActive(false); - break; - } --- -1.9.1 - - -From 96d631b30b33312b8041ece09a5660740e9bade3 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 5 Jul 2013 12:14:00 +0200 -Subject: [PATCH 64/96] X11: set windows class name - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index b3fe510..df5fe9b 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -982,8 +982,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - { - CreateIconPixmap(); - XWMHints *wm_hints; -+ XClassHint *class_hints; - XTextProperty windowName, iconName; - std::string titleString = "XBMC Media Center"; -+ std::string classString = "xbmc.bin"; - char *title = (char*)titleString.c_str(); - - XStringListToTextProperty(&title, 1, &windowName); -@@ -994,10 +996,15 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - wm_hints->icon_pixmap = m_icon; - wm_hints->flags = StateHint | IconPixmapHint; - -+ class_hints = XAllocClassHint(); -+ class_hints->res_class = (char*)classString.c_str(); -+ class_hints->res_name = (char*)classString.c_str(); -+ - XSync(m_dpy,False); - XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, - NULL, 0, NULL, wm_hints, -- NULL); -+ class_hints); -+ XFree(class_hints); - XFree(wm_hints); - - // register interest in the delete window message --- -1.9.1 - - -From 2594e2e409853924926bc3330d3bee0280c2c298 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 25 Jul 2013 17:18:13 +0200 -Subject: [PATCH 65/96] ActiveAE: slightly reduce buffer size - ---- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 3b7dbe1..6c5acfb 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -30,8 +30,8 @@ using namespace ActiveAE; - #include "settings/AdvancedSettings.h" - #include "windowing/WindowingFactory.h" - --#define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds --#define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds -+#define MAX_CACHE_LEVEL 0.4 // total cache time of stream in seconds -+#define MAX_WATER_LEVEL 0.2 // buffered time after stream stages in seconds - #define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds - - void CEngineStats::Reset(unsigned int sampleRate) --- -1.9.1 - - -From fd891b820c51301bda8391b1b599d4b10a44648f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 4 Aug 2013 10:11:16 +0200 -Subject: [PATCH 66/96] Revert "vdpau: comment some features that will be added - later" - -This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf. ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index cd72cc6..351586a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1117,8 +1117,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) - m_bufferStats.IncDecoded(); - m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - -- //TODO -- // m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); -+ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); - } - - int retval = 0; -@@ -2311,8 +2310,7 @@ void CMixer::InitCycle() - int flags; - uint64_t latency; - m_config.stats->GetParams(latency, flags); -- // TODO -- if (0) //flags & DVP_FLAG_NO_POSTPROC) -+ if (flags & DVP_FLAG_NO_POSTPROC) - SetPostProcFeatures(false); - else - SetPostProcFeatures(true); -@@ -2324,8 +2322,7 @@ void CMixer::InitCycle() - bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; - m_SeenInterlaceFlag |= interlaced; - -- // TODO -- if (//!(flags & DVP_FLAG_NO_POSTPROC) && -+ if (!(flags & DVP_FLAG_NO_POSTPROC) && - (mode == VS_DEINTERLACEMODE_FORCE || - (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) - { -@@ -2347,8 +2344,7 @@ void CMixer::InitCycle() - m_config.stats->SetCanSkipDeint(true); - } - -- // TODO -- if (0) //m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) -+ if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) - { - m_mixersteps = 1; - } --- -1.9.1 - - -From 86b169528568416e4fe5a1dc718021d06ff78d26 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 9 Aug 2013 18:01:40 +0200 -Subject: [PATCH 67/96] X11: fix keysyms - ---- - xbmc/windowing/WinEventsX11.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index e4ca56d..b20130c 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -461,7 +461,7 @@ bool CWinEventsX11Imp::MessagePump() - if (keys.length() > 0) - { - newEvent.key.keysym.scancode = xevent.xkey.keycode; -- xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL); - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); - newEvent.key.keysym.unicode = keys[keys.length() - 1]; - newEvent.key.state = xevent.xkey.state; --- -1.9.1 - - -From c7461145c0659e131b23fcc129739a1b06da1495 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 9 Aug 2013 18:42:36 +0200 -Subject: [PATCH 68/96] X11: fix keysym for non-IM - ---- - xbmc/windowing/WinEventsX11.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index b20130c..a38890c 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -408,7 +408,7 @@ bool CWinEventsX11Imp::MessagePump() - { - static XComposeStatus state; - char keybuf[32]; -- xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ XLookupString(&xevent.xkey, NULL, 0, &xkeysym, NULL); - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); - newEvent.key.keysym.scancode = xevent.xkey.keycode; - newEvent.key.state = xevent.xkey.state; --- -1.9.1 - - -From ea94f4df86043896ad7ae622411aba08bfb1b80d Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 10 Aug 2013 11:18:16 +0200 -Subject: [PATCH] add some missing multi media keys - ---- - system/keymaps/keyboard.xml | 3 +++ - xbmc/input/XBMC_keytable.cpp | 4 ++++ - xbmc/input/XBMC_vkeys.h | 1 + - 3 files changed, 8 insertions(+) - -diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml -index 45682a2..01f7904 100644 ---- a/system/keymaps/keyboard.xml -+++ b/system/keymaps/keyboard.xml -@@ -119,6 +119,9 @@ - SkipPrevious - Stop - Pause -+ FastForward -+ Rewind -+ - - XBMC.ActivateWindow(MyMusic) - ActivateWindow(MyPrograms) -diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp -index 53b9dce..834cccb 100644 ---- a/xbmc/input/XBMC_keytable.cpp -+++ b/xbmc/input/XBMC_keytable.cpp -@@ -184,6 +184,10 @@ static const XBMCKEYTABLE XBMCKeyTable[] = - , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } - , { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } - , { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } -+, { XBMCK_REWIND, 0, 0, XBMCVK_MEDIA_REWIND, "rewind" } -+, { XBMCK_FASTFORWARD, 0, 0, XBMCVK_MEDIA_FASTFORWARD, "fastforward" } -+, { XBMCK_RECORD, 0, 0, XBMCVK_MEDIA_RECORD, "record" } -+ - - // Function keys - , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} -diff --git a/xbmc/input/XBMC_vkeys.h b/xbmc/input/XBMC_vkeys.h -index 00437db..981c62a 100644 ---- a/xbmc/input/XBMC_vkeys.h -+++ b/xbmc/input/XBMC_vkeys.h -@@ -190,6 +190,7 @@ typedef enum { - XBMCVK_LAUNCH_MEDIA_CENTER = 0xC3, - XBMCVK_MEDIA_REWIND = 0xC4, - XBMCVK_MEDIA_FASTFORWARD = 0xC5, -+ XBMCVK_MEDIA_RECORD = 0xC6, - - XBMCVK_LCONTROL = 0xD0, - XBMCVK_RCONTROL = 0xD1, --- -1.9.1 - - -From 0112e8256276aa87c5587cd53914eb3b84b3e53a Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 10 Aug 2013 15:53:45 +0200 -Subject: [PATCH 70/96] X11: squash multi - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index df5fe9b..d8e04d6 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -437,7 +437,7 @@ void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) - - bool CWinSystemX11::IsCurrentOutput(CStdString output) - { -- return m_currentOutput.Equals(output); -+ return output.Equals("Default") || m_currentOutput.Equals(output); - } - - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) --- -1.9.1 - - -From 60af8bad18fc0b752ff179039d0410401fdbcad2 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 3 Sep 2013 20:46:17 +0200 -Subject: [PATCH 71/96] X11: do not poll default monitor - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index d8e04d6..01f5272 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -722,7 +722,7 @@ void CWinSystemX11::NotifyXRREvent(bool poll) - if (poll) - { - CStdString output = CSettings::Get().GetString("videoscreen.monitor"); -- if (output.Equals(m_currentOutput) || m_userOutput.Equals("Default")) -+ if (output.Equals(m_currentOutput) || output.Equals("Default")) - return; - - int numScreens = XScreenCount(m_dpy); --- -1.9.1 - - -From 0a2561c6afe499cea97e6f806db3a0be47eba77e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 29 Oct 2013 20:57:28 +0100 -Subject: [PATCH 72/96] X11: fix broken monitor switching - ---- - system/settings/settings.xml | 1 - - xbmc/settings/DisplaySettings.cpp | 40 ++++++++++++++++++++++++++------------- - 2 files changed, 27 insertions(+), 14 deletions(-) - -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 798be52..890bb10 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2304,7 +2304,6 @@ - -1 - - -- - - - -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index efb6cb1..da5873f 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -219,8 +219,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - - const std::string &settingId = setting->GetId(); - if (settingId == "videoscreen.resolution" || -- settingId == "videoscreen.screen" || -- settingId == "videoscreen.monitor") -+ settingId == "videoscreen.screen") - { - RESOLUTION newRes = RES_DESKTOP; - if (settingId == "videoscreen.resolution") -@@ -236,11 +235,6 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - // get desktop resolution for screen - newRes = GetResolutionForScreen(); - } -- else if (settingId == "videoscreen.monitor") -- { -- g_Windowing.UpdateResolutions(); -- newRes = GetResolutionForScreen(); -- } - - string screenmode = GetStringFromResolution(newRes); - CSettings::Get().SetString("videoscreen.screenmode", screenmode); -@@ -251,11 +245,7 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - RESOLUTION newRes = GetResolutionFromString(((CSettingString*)setting)->GetValue()); - - SetCurrentResolution(newRes, false); -- bool outputChanged = false; --#if defined(HAS_GLX) -- outputChanged = !g_Windowing.IsCurrentOutput(CSettings::Get().GetString("videoscreen.monitor")); --#endif -- g_graphicsContext.SetVideoResolution(newRes, outputChanged); -+ g_graphicsContext.SetVideoResolution(newRes); - - // check if the old or the new resolution was/is windowed - // in which case we don't show any prompt to the user -@@ -274,6 +264,28 @@ bool CDisplaySettings::OnSettingChanging(const CSetting *setting) - m_resolutionChangeAborted = false; - } - } -+ else if (settingId == "videoscreen.monitor") -+ { -+ g_Windowing.UpdateResolutions(); -+ RESOLUTION newRes = GetResolutionForScreen(); -+ -+ SetCurrentResolution(newRes, false); -+ g_graphicsContext.SetVideoResolution(newRes, true); -+ -+ if (!m_resolutionChangeAborted) -+ { -+ bool cancelled = false; -+ if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000)) -+ { -+ m_resolutionChangeAborted = true; -+ return false; -+ } -+ } -+ else -+ m_resolutionChangeAborted = false; -+ -+ return true; -+ } - else if (settingId == "videoscreen.monitorsingle") - { - g_Windowing.UpdateResolutions(); -@@ -708,9 +720,11 @@ void CDisplaySettings::SettingOptionsMonitorsFiller(const CSetting *setting, std - #if defined(HAS_GLX) - std::vector monitors; - g_Windowing.GetConnectedOutputs(&monitors); -+ std::string currentMonitor = CSettings::Get().GetString("videoscreen.monitor"); - for (unsigned int i=0; i -Date: Tue, 29 Oct 2013 20:57:59 +0100 -Subject: [PATCH 73/96] X11: remove polling for connected outputs, use xrr - events - ---- - xbmc/windowing/WinEventsX11.cpp | 44 +++++++++++---------- - xbmc/windowing/WinEventsX11.h | 1 - - xbmc/windowing/X11/WinSystemX11.cpp | 76 ++++++++++++++----------------------- - xbmc/windowing/X11/WinSystemX11.h | 8 ++-- - 4 files changed, 58 insertions(+), 71 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index a38890c..fe91a2b 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -213,7 +213,6 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; - WinEvents->m_xrrEventPending = false; -- WinEvents->m_xrrPollTimer.Set(3000); - - // open input method - char *old_locale = NULL, *old_modifiers = NULL; -@@ -280,7 +279,11 @@ bool CWinEventsX11Imp::Init(Display *dpy, Window win) - #if defined(HAS_XRANDR) - int iReturn; - XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); -- XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); -+ int numScreens = XScreenCount(WinEvents->m_display); -+ for (int i = 0; i < numScreens; i++) -+ { -+ XRRSelectInput(WinEvents->m_display, RootWindow(WinEvents->m_display, i), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask); -+ } - #endif - - return true; -@@ -328,6 +331,26 @@ bool CWinEventsX11Imp::MessagePump() - memset(&xevent, 0, sizeof (XEvent)); - XNextEvent(WinEvents->m_display, &xevent); - -+#if defined(HAS_XRANDR) -+ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) -+ { -+ XRRUpdateConfiguration(&xevent); -+ if (xevent.xgeneric.serial != serial) -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ serial = xevent.xgeneric.serial; -+ continue; -+ } -+ else if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRNotify)) -+ { -+ if (xevent.xgeneric.serial != serial) -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ serial = xevent.xgeneric.serial; -+ continue; -+ } -+#endif -+ - if (XFilterEvent(&xevent, WinEvents->m_window)) - continue; - -@@ -575,18 +598,6 @@ bool CWinEventsX11Imp::MessagePump() - break; - } - }// switch event.type -- --#if defined(HAS_XRANDR) -- if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) -- { -- XRRUpdateConfiguration(&xevent); -- if (xevent.xgeneric.serial != serial) -- g_Windowing.NotifyXRREvent(); -- WinEvents->m_xrrEventPending = false; -- serial = xevent.xgeneric.serial; -- } --#endif -- - }// while - - #if defined(HAS_XRANDR) -@@ -596,11 +607,6 @@ bool CWinEventsX11Imp::MessagePump() - g_Windowing.NotifyXRREvent(); - WinEvents->m_xrrEventPending = false; - } -- else if (!g_application.m_pPlayer->IsPlaying() && WinEvents && WinEvents->m_xrrPollTimer.IsTimePast()) -- { -- g_Windowing.NotifyXRREvent(true); -- WinEvents->m_xrrPollTimer.Set(3000); -- } - #endif - - #ifdef HAS_SDL_JOYSTICK -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 91a604f..6429291 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -62,6 +62,5 @@ protected: - bool m_structureChanged; - int m_RREventBase; - XbmcThreads::EndTime m_xrrFailSafeTimer; -- XbmcThreads::EndTime m_xrrPollTimer; - bool m_xrrEventPending; - }; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 01f5272..442efa6 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -168,8 +168,21 @@ bool CWinSystemX11::DestroyWindow() - - bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) - { -+ m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); -+ if (m_userOutput.compare("Default") == 0) -+ { -+ std::vector outputs = g_xrandr.GetModes(); -+ if (outputs.size() > 0) -+ { -+ m_userOutput = outputs[0].name; -+ } -+ } -+ -+ m_userOutput = g_xrandr.GetModes()[0].name; -+ - if(m_nWidth == newWidth -- && m_nHeight == newHeight) -+ && m_nHeight == newHeight -+ && m_userOutput.compare(m_currentOutput) == 0) - return true; - - if (!SetWindow(newWidth, newHeight, false, m_userOutput)) -@@ -255,33 +268,23 @@ void CWinSystemX11::UpdateResolutions() - - bool switchOnOff = CSettings::Get().GetBool("videoscreen.monitorsingle"); - m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); -- if (m_userOutput.Equals("Default")) -+ if (m_userOutput.compare("Default") == 0) - switchOnOff = false; - - if(g_xrandr.Query(true, !switchOnOff)) - { -- // check if the monitor is connected -- // might take a while when connected to a receiver -- XbmcThreads::EndTime timeout(3000); - XOutput *out = NULL; -- while (!m_userOutput.Equals("Default") && !timeout.IsTimePast()) -+ if (m_userOutput.compare("Default") != 0) - { - out = g_xrandr.GetOutput(m_userOutput); - if (out) - { - XMode mode = g_xrandr.GetCurrentMode(m_userOutput); -- if (mode.isCurrent || switchOnOff) -- break; -- else -+ if (!mode.isCurrent && !switchOnOff) - { - out = NULL; -- break; - } - } -- -- Sleep(500); -- if (!g_xrandr.Query(true, !switchOnOff)) -- break; - } - if (!out) - { -@@ -289,17 +292,16 @@ void CWinSystemX11::UpdateResolutions() - out = g_xrandr.GetOutput(m_userOutput); - } - -- // switch on output -- if(switchOnOff) -- g_xrandr.TurnOnOutput(m_userOutput); -- -- // switch off other outputs if desired - if (switchOnOff) - { -+ // switch on output -+ g_xrandr.TurnOnOutput(m_userOutput); -+ -+ // switch off other outputs - std::vector outputs = g_xrandr.GetModes(); - for (int i=0; i *outputs) - - bool CWinSystemX11::IsCurrentOutput(CStdString output) - { -- return output.Equals("Default") || m_currentOutput.Equals(output); -+ return (output.Equals("Default")) || (m_currentOutput.compare(output) == 0); - } - - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) -@@ -715,34 +717,14 @@ void CWinSystemX11::CheckDisplayEvents() - #endif - } - --void CWinSystemX11::NotifyXRREvent(bool poll) -+void CWinSystemX11::NotifyXRREvent() - { -- // we may not get an event if desired monitor becomes available -- // hence we need to poll -- if (poll) -- { -- CStdString output = CSettings::Get().GetString("videoscreen.monitor"); -- if (output.Equals(m_currentOutput) || output.Equals("Default")) -- return; -- -- int numScreens = XScreenCount(m_dpy); -- g_xrandr.SetNumScreens(numScreens); -- g_xrandr.Query(true); -- if (!g_xrandr.IsOutputConnected(output)) -- return; -- -- // if output is turned off by user, respect it -- XMode mode = g_xrandr.GetCurrentMode(output); -- if (!mode.isCurrent) -- return; -- } -- -- CLog::Log(LOGDEBUG, "%s - notify display reset event, poll: %d", __FUNCTION__, poll); -+ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); - m_windowDirty = true; - - CSingleLock lock(g_graphicsContext); - -- if (!g_xrandr.Query(!poll)) -+ if (!g_xrandr.Query(true)) - { - CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); - return; -@@ -839,14 +821,14 @@ bool CWinSystemX11::EnableFrameLimiter() - return m_minimized; - } - --bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) -+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output) - { - bool changeWindow = false; - bool changeSize = false; - bool mouseActive = false; - float mouseX, mouseY; - -- if (m_mainWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) -+ if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty)) - { - mouseActive = g_Mouse.IsActive(); - if (mouseActive) -@@ -1035,7 +1017,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - m_bIsGrabbed = false; - - CDirtyRegionList dr; -- RefreshGlxContext(!m_currentOutput.Equals(output)); -+ RefreshGlxContext(m_currentOutput.compare(output) != 0); - XSync(m_dpy, FALSE); - g_graphicsContext.Clear(0); - g_graphicsContext.Flip(dr); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 7ec5be4..14622cb 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -70,7 +70,7 @@ public: - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -- void NotifyXRREvent(bool poll = false); -+ void NotifyXRREvent(); - void GetConnectedOutputs(std::vector *outputs); - bool IsCurrentOutput(CStdString output); - void NotifyMouseCoverage(bool covered); -@@ -79,7 +79,7 @@ protected: - bool RefreshGlxContext(bool force); - void CheckDisplayEvents(); - void OnLostDevice(); -- bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); -+ bool SetWindow(int width, int height, bool fullscreen, const std::string &output); - - Window m_glWindow, m_mainWindow; - GLXContext m_glContext; -@@ -95,8 +95,8 @@ protected: - CCriticalSection m_resourceSection; - std::vector m_resources; - uint64_t m_dpyLostTime; -- CStdString m_currentOutput; -- CStdString m_userOutput; -+ std::string m_currentOutput; -+ std::string m_userOutput; - bool m_windowDirty; - bool m_bIsInternalXrr; - bool m_newGlContext; --- -1.9.1 - - -From e84bb7507d0ed31b25ab3a2124b57b44e768e3d3 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 09:37:13 +0100 -Subject: [PATCH 74/96] X11: remove grabbing of keyboard and mouse - ---- - xbmc/windowing/WinEventsX11.cpp | 4 ---- - xbmc/windowing/X11/WinSystemX11.cpp | 40 ------------------------------------- - xbmc/windowing/X11/WinSystemX11.h | 2 -- - 3 files changed, 46 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index fe91a2b..550c84d 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -538,16 +538,12 @@ bool CWinEventsX11Imp::MessagePump() - - case EnterNotify: - { -- if (xevent.xcrossing.mode == NotifyNormal) -- g_Windowing.NotifyMouseCoverage(true); - break; - } - - // lose mouse coverage - case LeaveNotify: - { -- if (xevent.xcrossing.mode == NotifyNormal) -- g_Windowing.NotifyMouseCoverage(false); - g_Mouse.SetActive(false); - break; - } -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 442efa6..695b352 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -153,8 +153,6 @@ bool CWinSystemX11::DestroyWindow() - - XUnmapWindow(m_dpy, m_mainWindow); - XSync(m_dpy,TRUE); -- XUngrabKeyboard(m_dpy, CurrentTime); -- XUngrabPointer(m_dpy, CurrentTime); - XDestroyWindow(m_dpy, m_glWindow); - XDestroyWindow(m_dpy, m_mainWindow); - m_glWindow = 0; -@@ -628,30 +626,6 @@ void CWinSystemX11::NotifyAppFocusChange(bool bGaining) - m_bIgnoreNextFocusMessage = false; - } - --void CWinSystemX11::NotifyMouseCoverage(bool covered) --{ -- if (!m_bFullScreen || !m_mainWindow) -- return; -- -- if (covered && !m_bIsGrabbed) -- { -- int result = -1; -- while (result != GrabSuccess && result != AlreadyGrabbed) -- { -- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -- XbmcThreads::ThreadSleep(100); -- } -- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -- m_bIsGrabbed = true; -- } -- else if (!covered && m_bIsGrabbed) -- { -- XUngrabKeyboard(m_dpy, CurrentTime); -- XUngrabPointer(m_dpy, CurrentTime); -- m_bIsGrabbed = false; -- } --} -- - bool CWinSystemX11::Minimize() - { - m_bWasFullScreenBeforeMinimize = m_bFullScreen; -@@ -1002,20 +976,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: - XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); - } - -- if (fullscreen) -- { -- int result = -1; -- while (result != GrabSuccess && result != AlreadyGrabbed) -- { -- result = XGrabPointer(m_dpy, m_mainWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -- XbmcThreads::ThreadSleep(100); -- } -- XGrabKeyboard(m_dpy, m_mainWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -- m_bIsGrabbed = true; -- } -- else -- m_bIsGrabbed = false; -- - CDirtyRegionList dr; - RefreshGlxContext(m_currentOutput.compare(output) != 0); - XSync(m_dpy, FALSE); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 14622cb..d1c8729 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -73,7 +73,6 @@ public: - void NotifyXRREvent(); - void GetConnectedOutputs(std::vector *outputs); - bool IsCurrentOutput(CStdString output); -- void NotifyMouseCoverage(bool covered); - - protected: - bool RefreshGlxContext(bool force); -@@ -90,7 +89,6 @@ protected: - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -- bool m_bIsGrabbed; - int m_RREventBase; - CCriticalSection m_resourceSection; - std::vector m_resources; --- -1.9.1 - - -From 3ead8999a2b3509f552b4a0f6be22df4f7b3954f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 10:46:40 +0100 -Subject: [PATCH 75/96] X11: set ExposureMask on gl window, fixes not updated - areas - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 695b352..e55583c 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -884,8 +884,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: - - swa.override_redirect = False; - swa.border_pixel = 0; -- swa.event_mask = 0; -- mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap; -+ swa.event_mask = ExposureMask; -+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask; - - m_glWindow = XCreateWindow(m_dpy, m_mainWindow, - 0, 0, width, height, 0, vi->depth, --- -1.9.1 - - -From 56dcd536fd8135ec06ef4cf317db86858ead89c8 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 11:25:19 +0100 -Subject: [PATCH 76/96] X11: drop shortcuts, have WM do this - ---- - xbmc/windowing/WinEventsX11.cpp | 21 --------------------- - xbmc/windowing/WinEventsX11.h | 1 - - 2 files changed, 22 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 550c84d..a5b4ba2 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -678,10 +678,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) - break; - } - event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -- -- bool ret = ProcessShortcuts(event); -- if (ret) -- return ret; - } - else if (event.type == XBMC_KEYUP) - { -@@ -723,23 +719,6 @@ bool CWinEventsX11Imp::ProcessKey(XBMC_Event &event) - return g_application.OnEvent(event); - } - --bool CWinEventsX11Imp::ProcessShortcuts(XBMC_Event& event) --{ -- if (event.key.keysym.mod & XBMCKMOD_ALT) -- { -- switch(event.key.keysym.sym) -- { -- case XBMCK_TAB: // ALT+TAB to minimize/hide -- g_application.Minimize(); -- return true; -- -- default: -- return false; -- } -- } -- return false; --} -- - XBMCKey CWinEventsX11Imp::LookupXbmcKeySym(KeySym keysym) - { - // try direct mapping first -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 6429291..4334d21 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -48,7 +48,6 @@ public: - protected: - static XBMCKey LookupXbmcKeySym(KeySym keysym); - static bool ProcessKey(XBMC_Event &event); -- static bool ProcessShortcuts(XBMC_Event& event); - static CWinEventsX11Imp *WinEvents; - Display *m_display; - Window m_window; --- -1.9.1 - - -From 7c7bd83bede5ceaaca6e153486bef8d66662c4c5 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 7 Nov 2013 15:02:00 +0100 -Subject: [PATCH 77/96] X11: adapt to new settings - ---- - system/settings/settings.xml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 890bb10..124a14d 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2264,6 +2264,7 @@ - HAS_GLX - 0 - false -+ - - - 0 --- -1.9.1 - - -From 97bc3eb5a047e69019c70221d35e478c4b66a363 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 14 Nov 2013 09:28:24 +0100 -Subject: [PATCH 78/96] X11: adapt to changes in cstdstring - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 4 ++-- - xbmc/windowing/X11/XRandR.cpp | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index e55583c..9962f08 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -369,8 +369,8 @@ void CWinSystemX11::UpdateResolutions() - - CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio); - -- res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); -- res.strOutput = out.name; -+ res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); -+ res.strOutput = out->name; - res.strId = mode.id; - res.iSubtitles = (int)(0.965*mode.h); - res.fRefreshRate = mode.hz; -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 8525ede..c94f2e3 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -74,7 +74,7 @@ bool CXRandR::Query(bool force, int screennum, bool ignoreoff) - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; -- cmd.AppendFormat(" -q --screen %d", screennum); -+ cmd = StringUtils::Format("%s -q --screen %d", cmd.c_str(), screennum); - - FILE* file = popen(cmd.c_str(),"r"); - if (!file) -@@ -156,7 +156,7 @@ bool CXRandR::TurnOffOutput(CStdString name) - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; -- cmd.AppendFormat(" --screen %d --output %s --off", output->screen, name.c_str()); -+ cmd = StringUtils::Format("%s --screen %d --output %s --off", cmd.c_str(), output->screen, name.c_str()); - - int status = system(cmd.c_str()); - if (status == -1) --- -1.9.1 - - -From 2ec9169c90eb33866d139a09b38ff04018cae905 Mon Sep 17 00:00:00 2001 -From: Marcel Groothuis -Date: Thu, 5 Dec 2013 22:02:50 +0100 -Subject: [PATCH 80/96] ffmpeg demuxer: faster channel change for PVR addons - without internal demuxing (such as MediaPortal, ArgusTV, MythTV, NextPVR) - Credits: FernetMenta, Davilla, Popcornmix, Whaupt - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 143 ++++++++++++++++++--- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 5 +- - .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 13 +- - 3 files changed, 139 insertions(+), 22 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index afa3024..3409b67 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -51,6 +51,8 @@ - #include "utils/StringUtils.h" - #include "URL.h" - -+#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) -+ - void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) - { - if(!m_stream) return; -@@ -217,6 +219,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() - m_program = UINT_MAX; - m_pkt.result = -1; - memset(&m_pkt.pkt, 0, sizeof(AVPacket)); -+ m_streaminfo = true; /* set to true if we want to look for streams before playback */ - } - - CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() -@@ -237,10 +240,11 @@ bool CDVDDemuxFFmpeg::Aborted() - return false; - } - --bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) -+bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) - { - AVInputFormat* iformat = NULL; - std::string strFile; -+ m_streaminfo = streaminfo; - m_iCurrentPts = DVD_NOPTS_VALUE; - m_speed = DVD_PLAYSPEED_NORMAL; - m_program = UINT_MAX; -@@ -259,8 +263,6 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) - m_pInput = pInput; - strFile = m_pInput->GetFileName(); - -- bool streaminfo = true; /* set to true if we want to look for streams before playback*/ -- - if( m_pInput->GetContent().length() > 0 ) - { - std::string content = m_pInput->GetContent(); -@@ -450,13 +452,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) - m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" - m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; - -- if (streaminfo) -+ if (m_streaminfo) - { -- /* too speed up dvd switches, only analyse very short */ -+ /* to speed up dvd switches, only analyse very short */ - if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - m_pFormatContext->max_analyze_duration = 500000; - -- - CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__); - int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL); - if (iErr < 0) -@@ -476,6 +477,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) - } - CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); - } -+ else -+ m_program = 0; -+ - // reset any timeout - m_timeout.SetInfinite(); - -@@ -533,7 +537,7 @@ void CDVDDemuxFFmpeg::Reset() - { - CDVDInputStream* pInputStream = m_pInput; - Dispose(); -- Open(pInputStream); -+ Open(pInputStream, m_streaminfo); - } - - void CDVDDemuxFFmpeg::Flush() -@@ -728,25 +732,32 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() - } - else - { -+ ParsePacket(&m_pkt.pkt); -+ - AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index]; - -- if (m_program != UINT_MAX) -+ if (IsVideoReady()) - { -- /* check so packet belongs to selected program */ -- for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) -+ if (m_program != UINT_MAX) - { -- if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) -+ /* check so packet belongs to selected program */ -+ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { -- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); -- break; -+ if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) -+ { -+ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); -+ break; -+ } - } -- } - -- if (!pPacket) -- bReturnEmpty = true; -+ if (!pPacket) -+ bReturnEmpty = true; -+ } -+ else -+ pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); - } - else -- pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); -+ bReturnEmpty = true; - - if (pPacket) - { -@@ -1684,3 +1695,101 @@ bool CDVDDemuxFFmpeg::IsProgramChange() - } - return false; - } -+ -+void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) -+{ -+ AVStream *st = m_pFormatContext->streams[pkt->stream_index]; -+ CDemuxStream *stream = GetStreamInternal(pkt->stream_index); -+ -+ // if the stream is new, tell ffmpeg to parse the stream -+ if (!stream && !st->parser) -+ { -+ st->need_parsing = AVSTREAM_PARSE_FULL; -+ } -+ -+ // split extradata -+ if(st->parser && st->parser->parser->split && !st->codec->extradata) -+ { -+ int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); -+ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) -+ { -+ // Found extradata, fill it in. This will cause -+ // a new stream to be created and used. -+ st->codec->extradata_size = i; -+ st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); -+ if (st->codec->extradata) -+ { -+ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size); -+ memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); -+ memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); -+ } -+ else -+ { -+ st->codec->extradata_size = 0; -+ } -+ } -+ } -+ -+ // for video we need a decoder to get desired information into codec context -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) -+ { -+ // open a decoder, it will be cleared down by ffmpeg on closing the stream -+ if (!st->codec->codec) -+ { -+ const AVCodec* codec; -+ AVDictionary *thread_opt = NULL; -+ codec = avcodec_find_decoder(st->codec->codec_id); -+ // Force thread count to 1 since the h264 decoder will not extract -+ // SPS and PPS to extradata during multi-threaded decoding -+ av_dict_set(&thread_opt, "threads", "1", 0); -+ avcodec_open2(st->codec, codec, &thread_opt); -+ -+ av_dict_free(&thread_opt); -+ } -+ -+ // We don't need to actually decode here -+ // we just want to transport SPS data into codec context -+ st->codec->skip_idct = AVDISCARD_ALL; -+ st->codec->skip_frame = AVDISCARD_ALL; -+ st->codec->skip_loop_filter = AVDISCARD_ALL; -+ -+ // We are looking for an IDR frame -+ AVFrame picture; -+ memset(&picture, 0, sizeof(AVFrame)); -+ picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE; -+ picture.pkt_pos = -1; -+ picture.key_frame = 1; -+ picture.format = -1; -+ -+ int got_picture = 0; -+ avcodec_decode_video2(st->codec, &picture, &got_picture, pkt); -+ } -+} -+ -+bool CDVDDemuxFFmpeg::IsVideoReady() -+{ -+ AVStream *st; -+ if(m_program != UINT_MAX) -+ { -+ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) -+ { -+ int idx = m_pFormatContext->programs[m_program]->stream_index[i]; -+ st = m_pFormatContext->streams[idx]; -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) -+ return false; -+ } -+ } -+ else -+ { -+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) -+ { -+ st = m_pFormatContext->streams[i]; -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) -+ return false; -+ } -+ } -+ return true; -+} -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index 35abbdf..acde9a8 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -89,7 +89,7 @@ public: - CDVDDemuxFFmpeg(); - virtual ~CDVDDemuxFFmpeg(); - -- bool Open(CDVDInputStream* pInput); -+ bool Open(CDVDInputStream* pInput, bool streaminfo = true); - void Dispose(); - void Reset(); - void Flush(); -@@ -128,6 +128,8 @@ protected: - CDemuxStream* GetStreamInternal(int iStreamId); - void CreateStreams(unsigned int program = UINT_MAX); - void DisposeStreams(); -+ void ParsePacket(AVPacket *pkt); -+ bool IsVideoReady(); - - AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); - double ConvertTimestamp(int64_t pts, int den, int num); -@@ -162,5 +164,6 @@ protected: - - bool m_bPtsWrap, m_bPtsWrapChecked; - int64_t m_iStartTime, m_iMaxTime, m_iEndTime; -+ bool m_streaminfo; - }; - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -index ca689d0..f383563 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -@@ -99,26 +99,31 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) - } - #endif - -+ bool streaminfo = true; /* Look for streams before playback */ - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) - { - CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; - CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); -+ -+ /* Don't parse the streaminfo for live streams to reduce the channel switch time */ -+ bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels"); -+ streaminfo = !liveStream; -+ - if(pOtherStream) - { - /* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */ - if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - auto_ptr demuxer(new CDVDDemuxFFmpeg()); -- if(demuxer->Open(pOtherStream)) -+ if(demuxer->Open(pOtherStream, streaminfo)) - return demuxer.release(); - else - return NULL; - } - } - -- std::string filename = pInputStream->GetFileName(); - /* Use PVR demuxer only for live streams */ -- if (filename.substr(0, 14) == "pvr://channels") -+ if (liveStream) - { - boost::shared_ptr client; - if (g_PVRClients->GetPlayingClient(client) && -@@ -134,7 +139,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) - } - - auto_ptr demuxer(new CDVDDemuxFFmpeg()); -- if(demuxer->Open(pInputStream)) -+ if(demuxer->Open(pInputStream, streaminfo)) - return demuxer.release(); - else - return NULL; --- -1.9.1 - - -From 1c6901d50fc7b5d499e423fd2d5721da1913c203 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 14 Nov 2013 20:35:04 +0100 -Subject: [PATCH 81/96] ffmpeg demuxer: make sure we start mpegts video with an - i-frame - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 31 +++++++++++++++++++++- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 + - 2 files changed, 31 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index 3409b67..d5da14b 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -448,6 +448,13 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) - if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) - m_pFormatContext->max_analyze_duration = 500000; - -+ bool short_analyze = false; -+ if (iformat && (strcmp(iformat->name, "mpegts") == 0)) -+ { -+ m_pFormatContext->max_analyze_duration = 500000; -+ short_analyze = true; -+ } -+ - // we need to know if this is matroska or avi later - m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" - m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; -@@ -476,6 +483,12 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) - } - } - CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); -+ -+ if (short_analyze) -+ { -+ // make sure we start video with an i-frame -+ ResetVideoStreams(); -+ } - } - else - m_program = 0; -@@ -1731,7 +1744,7 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) - } - - // for video we need a decoder to get desired information into codec context -- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata && - (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) - { - // open a decoder, it will be cleared down by ffmpeg on closing the stream -@@ -1793,3 +1806,19 @@ bool CDVDDemuxFFmpeg::IsVideoReady() - } - return true; - } -+ -+void CDVDDemuxFFmpeg::ResetVideoStreams() -+{ -+ AVStream *st; -+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) -+ { -+ st = m_pFormatContext->streams[i]; -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) -+ { -+ if (st->codec->extradata) -+ m_dllAvUtil.av_free(st->codec->extradata); -+ st->codec->extradata = NULL; -+ st->codec->width = 0; -+ } -+ } -+} -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index acde9a8..9ec0877 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -130,6 +130,7 @@ protected: - void DisposeStreams(); - void ParsePacket(AVPacket *pkt); - bool IsVideoReady(); -+ void ResetVideoStreams(); - - AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); - double ConvertTimestamp(int64_t pts, int den, int num); --- -1.9.1 - - -From 75043ecb88a683165524d49f5cdd6809af3443fd Mon Sep 17 00:00:00 2001 -From: Wolfgang Haupt -Date: Thu, 5 Dec 2013 22:11:57 +0100 -Subject: [PATCH 82/96] DVDFactoryDemuxer: skip streaminfo for udp tcp and - pvr-channels - ---- - .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 14 ++++++--- - xbmc/utils/URIUtils.cpp | 35 ++++++++++++++++++++++ - xbmc/utils/URIUtils.h | 4 +++ - 3 files changed, 49 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -index f383563..d6580fd 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp -@@ -105,9 +105,9 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) - CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; - CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); - -- /* Don't parse the streaminfo for live streams to reduce the channel switch time */ -- bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels"); -- streaminfo = !liveStream; -+ /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */ -+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); -+ streaminfo = !useFastswitch; - - if(pOtherStream) - { -@@ -123,7 +123,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) - } - - /* Use PVR demuxer only for live streams */ -- if (liveStream) -+ if (URIUtils::IsPVRChannel(pInputStream->GetFileName())) - { - boost::shared_ptr client; - if (g_PVRClients->GetPlayingClient(client) && -@@ -138,6 +138,12 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream) - } - } - -+ if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) -+ { -+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); -+ streaminfo = !useFastswitch; -+ } -+ - auto_ptr demuxer(new CDVDDemuxFFmpeg()); - if(demuxer->Open(pInputStream, streaminfo)) - return demuxer.release(); -diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp -index fd2eb5a..22932b7 100644 ---- a/xbmc/utils/URIUtils.cpp -+++ b/xbmc/utils/URIUtils.cpp -@@ -788,6 +788,36 @@ bool URIUtils::IsFTP(const CStdString& strFile) - StringUtils::StartsWithNoCase(strFile2, "ftps:"); - } - -+bool URIUtils::IsUDP(const CStdString& strFile) -+{ -+ CStdString strFile2(strFile); -+ -+ if (IsStack(strFile)) -+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); -+ -+ return StringUtils::StartsWithNoCase(strFile2, "udp:"); -+} -+ -+bool URIUtils::IsTCP(const CStdString& strFile) -+{ -+ CStdString strFile2(strFile); -+ -+ if (IsStack(strFile)) -+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); -+ -+ return StringUtils::StartsWithNoCase(strFile2, "tcp:"); -+} -+ -+bool URIUtils::IsPVRChannel(const CStdString& strFile) -+{ -+ CStdString strFile2(strFile); -+ -+ if (IsStack(strFile)) -+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile); -+ -+ return StringUtils::StartsWithNoCase(strFile2, "pvr://channels"); -+} -+ - bool URIUtils::IsDAV(const CStdString& strFile) - { - CStdString strFile2(strFile); -@@ -1284,3 +1314,8 @@ bool URIUtils::UpdateUrlEncoding(std::string &strFilename) - strFilename = newFilename; - return true; - } -+ -+bool URIUtils::IsUsingFastSwitch(const CStdString& strFile) -+{ -+ return IsUDP(strFile) || IsTCP(strFile) || IsPVRChannel(strFile); -+} -diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h -index b94e94c..b45630f 100644 ---- a/xbmc/utils/URIUtils.h -+++ b/xbmc/utils/URIUtils.h -@@ -88,6 +88,8 @@ public: - static bool IsDOSPath(const CStdString &path); - static bool IsDVD(const CStdString& strFile); - static bool IsFTP(const CStdString& strFile); -+ static bool IsUDP(const CStdString& strFile); -+ static bool IsTCP(const CStdString& strFile); - static bool IsHD(const CStdString& strFileName); - static bool IsHDHomeRun(const CStdString& strFile); - static bool IsSlingbox(const CStdString& strFile); -@@ -127,6 +129,8 @@ public: - static bool IsAndroidApp(const CStdString& strFile); - static bool IsLibraryFolder(const CStdString& strFile); - static bool IsLibraryContent(const std::string& strFile); -+ static bool IsPVRChannel(const CStdString& strFile); -+ static bool IsUsingFastSwitch(const CStdString& strFile); - - static void AddSlashAtEnd(std::string& strFolder); - static bool HasSlashAtEnd(const std::string& strFile, bool checkURL = false); --- -1.9.1 - - -From 3041272619e91e0b028462b53c59bd0cf620e1f9 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 28 Jan 2014 08:43:29 +0100 -Subject: [PATCH 83/96] squash fast switch - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 23 ++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index d5da14b..f4ba29c 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -1783,15 +1783,19 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) - bool CDVDDemuxFFmpeg::IsVideoReady() - { - AVStream *st; -+ bool hasVideo = false; - if(m_program != UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - int idx = m_pFormatContext->programs[m_program]->stream_index[i]; - st = m_pFormatContext->streams[idx]; -- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) -- return false; -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) -+ { -+ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) -+ return true; -+ hasVideo = true; -+ } - } - } - else -@@ -1799,12 +1803,15 @@ bool CDVDDemuxFFmpeg::IsVideoReady() - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - st = m_pFormatContext->streams[i]; -- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && -- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) -- return false; -+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) -+ { -+ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) -+ return true; -+ hasVideo = true; -+ } - } - } -- return true; -+ return !hasVideo; - } - - void CDVDDemuxFFmpeg::ResetVideoStreams() -@@ -1816,7 +1823,7 @@ void CDVDDemuxFFmpeg::ResetVideoStreams() - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->extradata) -- m_dllAvUtil.av_free(st->codec->extradata); -+ av_free(st->codec->extradata); - st->codec->extradata = NULL; - st->codec->width = 0; - } --- -1.9.1 - - -From c70b0943cb55465cde76dde9a2dbcf4db1ced09b Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 22 Dec 2013 14:52:29 +0100 -Subject: [PATCH 84/96] linux: add shared lib for sse4 operations - ---- - Makefile.in | 8 ++- - configure.in | 18 +++++++ - xbmc/DllPaths_generated.h.in | 3 ++ - xbmc/linux/sse4/CopyFrame.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ - xbmc/linux/sse4/DllLibSSE4.h | 43 ++++++++++++++++ - xbmc/linux/sse4/Makefile.in | 20 ++++++++ - 6 files changed, 206 insertions(+), 1 deletion(-) - create mode 100644 xbmc/linux/sse4/CopyFrame.cpp - create mode 100644 xbmc/linux/sse4/DllLibSSE4.h - create mode 100644 xbmc/linux/sse4/Makefile.in - -diff --git a/Makefile.in b/Makefile.in -index 6f689cf..a79adc7 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -316,6 +316,12 @@ CHECK_LIBADD=@WAYLAND_TEST_LIBS@ - endif - endif - -+ifeq (@USE_SSE4@,1) -+LIBSSE4+=sse4 -+sse4 : force -+ $(MAKE) -C xbmc/linux/sse4 -+endif -+ - CHECK_PROGRAMS = xbmc-test - - CLEAN_FILES += $(CHECK_PROGRAMS) $(CHECK_EXTENSIONS) -@@ -444,7 +450,7 @@ endif - - codecs: papcodecs dvdpcodecs dvdpextcodecs - --libs: libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH) -+libs: $(LIBSSE4) libhdhomerun imagelib libexif system/libcpluff-@ARCH@.so $(CMYTH) - - externals: codecs libs visualizations screensavers libaddon pvraddons - -diff --git a/configure.in b/configure.in -index d0775a9..6cf2a44 100644 ---- a/configure.in -+++ b/configure.in -@@ -883,6 +883,19 @@ if test "$use_static_ffmpeg" = "yes"; then - VORBISENC_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc` - fi - -+use_sse4=no -+if test "$ARCH" = "x86_64-linux" || test "$ARCH" = "i486-linux"; then -+ SAVE_CFLAGS="$CFLAGS" -+ CFLAGS="-msse4.1" -+ AC_COMPILE_IFELSE( -+ [AC_LANG_SOURCE([int foo;])], -+ [ use_sse4=yes -+ USE_SSE4=1], -+ [ use_sse=no -+ USE_SSE4=0]) -+ CFLAGS="$SAVE_CFLAGS" -+fi -+ - # Checks for library functions. - AC_FUNC_ALLOCA - AC_FUNC_CHOWN -@@ -2590,6 +2603,10 @@ if test "$use_codec_libstagefright" = "yes"; then - OUTPUT_FILES="$OUTPUT_FILES xbmc/cores/dvdplayer/DVDCodecs/Video/libstagefrightICS/Makefile" - fi - -+if test "$use_sse4" = "yes"; then -+OUTPUT_FILES="$OUTPUT_FILES xbmc/linux/sse4/Makefile" -+fi -+ - OUTPUT_FILES="$OUTPUT_FILES \ - xbmc/interfaces/python/Makefile \ - xbmc/interfaces/python/test/Makefile" -@@ -2668,6 +2685,7 @@ AC_SUBST(USE_DOXYGEN) - AC_SUBST(USE_PVR_ADDONS) - AC_SUBST(GNUTLS_ALL_LIBS) - AC_SUBST(VORBISENC_ALL_LIBS) -+AC_SUBST(USE_SSE4) - - # pushd and popd are not available in other shells besides bash, so implement - # our own pushd/popd functions -diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in -index 4953236..e42344c 100644 ---- a/xbmc/DllPaths_generated.h.in -+++ b/xbmc/DllPaths_generated.h.in -@@ -103,4 +103,7 @@ - /* xkbcommon */ - #define DLL_PATH_XKBCOMMON "@XKBCOMMON_LIBRARY_SONAME@" - -+/* sse4 */ -+#define DLL_PATH_LIBSSE4 "special://xbmcbin/system/libsse4-@ARCH@.so" -+ - #endif -diff --git a/xbmc/linux/sse4/CopyFrame.cpp b/xbmc/linux/sse4/CopyFrame.cpp -new file mode 100644 -index 0000000..6d23d83 ---- /dev/null -+++ b/xbmc/linux/sse4/CopyFrame.cpp -@@ -0,0 +1,115 @@ -+/* -+ * Copyright (C) 2005-2013 Team XBMC -+ * http://xbmc.org -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "smmintrin.h" -+ -+#define CACHED_BUFFER_SIZE 4096 -+typedef unsigned int UINT; -+ -+extern "C" -+{ -+ -+/* -+ * http://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers -+ * COPIES VIDEO FRAMES FROM USWC MEMORY TO WB SYSTEM MEMORY VIA CACHED BUFFER -+ * ASSUMES PITCH IS A MULTIPLE OF 64B CACHE LINE SIZE, WIDTH MAY NOT BE -+ */ -+void copy_frame( void * pSrc, void * pDest, void * pCacheBlock, -+ UINT width, UINT height, UINT pitch ) -+{ -+ __m128i x0, x1, x2, x3; -+ __m128i *pLoad; -+ __m128i *pStore; -+ __m128i *pCache; -+ UINT x, y, yLoad, yStore; -+ UINT rowsPerBlock; -+ UINT width64; -+ UINT extraPitch; -+ -+ -+ rowsPerBlock = CACHED_BUFFER_SIZE / pitch; -+ width64 = (width + 63) & ~0x03f; -+ extraPitch = (pitch - width64) / 16; -+ -+ pLoad = (__m128i *)pSrc; -+ pStore = (__m128i *)pDest; -+ -+ // COPY THROUGH 4KB CACHED BUFFER -+ for( y = 0; y < height; y += rowsPerBlock ) -+ { -+ // ROWS LEFT TO COPY AT END -+ if( y + rowsPerBlock > height ) -+ rowsPerBlock = height - y; -+ -+ pCache = (__m128i *)pCacheBlock; -+ -+ _mm_mfence(); -+ -+ // LOAD ROWS OF PITCH WIDTH INTO CACHED BLOCK -+ for( yLoad = 0; yLoad < rowsPerBlock; yLoad++ ) -+ { -+ // COPY A ROW, CACHE LINE AT A TIME -+ for( x = 0; x < pitch; x +=64 ) -+ { -+ x0 = _mm_stream_load_si128( pLoad +0 ); -+ x1 = _mm_stream_load_si128( pLoad +1 ); -+ x2 = _mm_stream_load_si128( pLoad +2 ); -+ x3 = _mm_stream_load_si128( pLoad +3 ); -+ -+ _mm_store_si128( pCache +0, x0 ); -+ _mm_store_si128( pCache +1, x1 ); -+ _mm_store_si128( pCache +2, x2 ); -+ _mm_store_si128( pCache +3, x3 ); -+ -+ pCache += 4; -+ pLoad += 4; -+ } -+ } -+ -+ _mm_mfence(); -+ -+ pCache = (__m128i *)pCacheBlock; -+ -+ // STORE ROWS OF FRAME WIDTH FROM CACHED BLOCK -+ for( yStore = 0; yStore < rowsPerBlock; yStore++ ) -+ { -+ // copy a row, cache line at a time -+ for( x = 0; x < width64; x +=64 ) -+ { -+ x0 = _mm_load_si128( pCache ); -+ x1 = _mm_load_si128( pCache +1 ); -+ x2 = _mm_load_si128( pCache +2 ); -+ x3 = _mm_load_si128( pCache +3 ); -+ -+ _mm_stream_si128( pStore, x0 ); -+ _mm_stream_si128( pStore +1, x1 ); -+ _mm_stream_si128( pStore +2, x2 ); -+ _mm_stream_si128( pStore +3, x3 ); -+ -+ pCache += 4; -+ pStore += 4; -+ } -+ -+ pCache += extraPitch; -+ pStore += extraPitch; -+ } -+ } -+} -+} -diff --git a/xbmc/linux/sse4/DllLibSSE4.h b/xbmc/linux/sse4/DllLibSSE4.h -new file mode 100644 -index 0000000..01424ac ---- /dev/null -+++ b/xbmc/linux/sse4/DllLibSSE4.h -@@ -0,0 +1,43 @@ -+#pragma once -+/* -+ * Copyright (C) 2005-2013 Team XBMC -+ * http://xbmc.org -+ * -+ * This Program 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, or (at your option) -+ * any later version. -+ * -+ * This Program 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 XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "DynamicDll.h" -+ -+extern "C" { -+ -+} -+ -+class DllLibSSE4Interface -+{ -+public: -+ virtual ~DllLibSSE4Interface() {} -+ virtual void copy_frame(void * pSrc, void * pDest, void * pCacheBlock, UINT width, UINT height, UINT pitch) = 0; -+}; -+ -+class DllLibSSE4 : public DllDynamic, DllLibSSE4Interface -+{ -+ DECLARE_DLL_WRAPPER(DllLibSSE4, DLL_PATH_LIBSSE4) -+ DEFINE_METHOD6(void, copy_frame, (void *p1, void *p2, void *p3, UINT p4, UINT p5, UINT p6)) -+ -+ BEGIN_METHOD_RESOLVE() -+ RESOLVE_METHOD(copy_frame) -+ END_METHOD_RESOLVE() -+}; -diff --git a/xbmc/linux/sse4/Makefile.in b/xbmc/linux/sse4/Makefile.in -new file mode 100644 -index 0000000..45aa826 ---- /dev/null -+++ b/xbmc/linux/sse4/Makefile.in -@@ -0,0 +1,20 @@ -+ARCH=@ARCH@ -+DEFINES+= -+CXXFLAGS=-fPIC -msse4.1 -+LIBNAME=libsse4 -+OBJS=CopyFrame.o -+ -+LIB_SHARED=@abs_top_srcdir@/system/$(LIBNAME)-$(ARCH).so -+ -+all: $(LIB_SHARED) -+ -+$(LIB_SHARED): $(OBJS) -+ $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS) -+ -+CLEAN_FILES = \ -+ $(LIB_SHARED) \ -+ -+DISTCLEAN_FILES= \ -+ Makefile \ -+ -+include ../../../Makefile.include --- -1.9.1 - - -From d8669de8aeb2268b9ae0b91602215b4890366f15 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 19 Dec 2013 15:36:11 +0100 -Subject: [PATCH 85/96] vaapi: option to enable sw filters - ---- - language/English/strings.po | 17 ++- - system/settings/settings.xml | 15 ++ - xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +- - xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 1 + - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 76 ++++++++-- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 3 + - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 154 +++++++++++++++++++++ - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 34 +++++ - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 32 ++--- - 9 files changed, 295 insertions(+), 41 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 9cc2090..88b945e 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -6092,7 +6092,13 @@ msgctxt "#13456" - msgid "Hardware accelerated" - msgstr "" - --#empty strings from id 13457 to 13499 -+#. Option for video related setting #13454: sw filter -+#: system/settings/settings.xml -+msgctxt "#13457" -+msgid "Use SW Filter for VAAPI" -+msgstr "" -+ -+#empty strings from id 13458 to 13499 - - #: system/settings/settings.xml - msgctxt "#13500" -@@ -15177,7 +15183,14 @@ msgctxt "#36431" - msgid "Defines whether video decoding should be performed in software (requires more CPU) or with hardware acceleration where possible." - msgstr "" - --#empty strings from id 36432 to 36499 -+#. Description for video related setting #13457: vaapi sw filter -+#: system/settings/settings.xml -+msgctxt "#36432" -+msgid "This option enables the deinterlacing methods available for software decoding. It gives the possiblity to use high quality deinterlacers in combination with VAAPI." -+msgstr "" -+ -+#empty strings from id 36433 to 36499 -+ - #end reservation - - #: system/settings/settings.xml -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 124a14d..fdf5f41 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -715,6 +715,21 @@ - false - - -+ -+ HAVE_LIBVA -+ -+ -+ -+ true -+ 1 -+ -+ -+ true -+ -+ 3 -+ false -+ -+ - - HasDXVA2 - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 8dc8a91..c15f559 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -986,10 +986,10 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO - if (mInt == VS_INTERLACEMETHOD_NONE) - return VS_INTERLACEMETHOD_NONE; - -- if(!m_pRenderer->Supports(mInt)) -+ if(m_pRenderer && !m_pRenderer->Supports(mInt)) - mInt = VS_INTERLACEMETHOD_AUTO; - -- if (mInt == VS_INTERLACEMETHOD_AUTO) -+ if (m_pRenderer && mInt == VS_INTERLACEMETHOD_AUTO) - return m_pRenderer->AutoInterlaceMethod(); - - return mInt; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp -index 5443cb3..002c8e1 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp -@@ -456,6 +456,7 @@ static const EFormatMap g_format_map[] = { - , { PIX_FMT_YUV420P16, RENDER_FMT_YUV420P16 } - , { PIX_FMT_UYVY422, RENDER_FMT_UYVY422 } - , { PIX_FMT_YUYV422, RENDER_FMT_YUYV422 } -+, { PIX_FMT_NV12, RENDER_FMT_NV12 } - , { PIX_FMT_VAAPI_VLD, RENDER_FMT_VAAPI } - , { PIX_FMT_DXVA2_VLD, RENDER_FMT_DXVA } - , { PIX_FMT_NONE , RENDER_FMT_NONE } -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index b59c1ee..2df9de9 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -38,6 +38,7 @@ - #include "utils/log.h" - #include "boost/shared_ptr.hpp" - #include "threads/Atomics.h" -+#include "settings/MediaSettings.h" - - #ifndef TARGET_POSIX - #define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5))) -@@ -165,6 +166,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() - m_dts = DVD_NOPTS_VALUE; - m_started = false; - m_decoderPts = DVD_NOPTS_VALUE; -+ m_interlace = false; - } - - CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() -@@ -388,7 +390,7 @@ unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags) - { - m_filters_next.clear(); - -- if(m_pHardware) -+ if(m_pHardware && !m_pHardware->UseFilter()) - return 0; - - if(flags & FILTER_ROTATE) -@@ -462,10 +464,10 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - if(section) - lock = shared_ptr(new CSingleLock(*section)); - -- int result; -+ int result = 0; - if(pData) - result = m_pHardware->Check(m_pCodecContext); -- else -+ else if (!m_pHardware->UseFilter()) - result = m_pHardware->Decode(m_pCodecContext, NULL); - - if(result) -@@ -520,19 +522,60 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - || m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3) - m_started = true; - -- if(m_pHardware == NULL) -+ m_interlace = m_pFrame->interlaced_frame; -+ -+ if(m_pHardware == NULL || m_pHardware->UseFilter()) - { -+ if (m_pHardware) -+ { -+ m_pFrame->pkt_dts = pts_dtoi(m_dts); -+ int result = m_pHardware->Decode(m_pCodecContext, m_pFrame); -+ if (result == VC_BUFFER) -+ return result; -+ m_pHardware->MapFrame(m_pCodecContext, m_pFrame); -+ m_dts = pts_itod(m_pFrame->pkt_dts); -+ m_pFrame->pkt_dts = 0; -+ } -+ - bool need_scale = std::find( m_formats.begin() - , m_formats.end() -- , m_pCodecContext->pix_fmt) == m_formats.end(); -+ , m_pFrame->format) == m_formats.end(); - - bool need_reopen = false; -+ -+ -+ // ask codec to do deinterlacing if possible -+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -+ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); -+ -+ unsigned int mFilters = 0; -+ -+ if (mDeintMode != VS_DEINTERLACEMODE_OFF) -+ { -+ if (mDeintMode == VS_DEINTERLACEMODE_FORCE || -+ m_pFrame->interlaced_frame) -+ { -+ if (mInt == VS_INTERLACEMETHOD_DEINTERLACE) -+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY; -+ else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF) -+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED; -+ -+ if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters) -+ mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED; -+ } -+ } -+ -+ if (!g_renderManager.Supports(RENDERFEATURE_ROTATION)) -+ mFilters |= CDVDVideoCodec::FILTER_ROTATE; -+ -+ SetFilters(mFilters); -+ - if(!m_filters.Equals(m_filters_next)) - need_reopen = true; - - if(m_pFilterIn) - { -- if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt -+ if(m_pFilterIn->outputs[0]->format != m_pFrame->format - || m_pFilterIn->outputs[0]->w != m_pCodecContext->width - || m_pFilterIn->outputs[0]->h != m_pCodecContext->height) - need_reopen = true; -@@ -549,7 +592,7 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - } - - int result; -- if(m_pHardware) -+ if(m_pHardware && !m_pHardware->UseFilter()) - result = m_pHardware->Decode(m_pCodecContext, m_pFrame); - else if(m_pFilterGraph) - result = FilterProcess(m_pFrame); -@@ -645,6 +688,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location; - pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries; - pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc; -+ pDvdVideoPicture->color_matrix = m_pCodecContext->colorspace; - if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG - || m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P) - pDvdVideoPicture->color_range = 1; -@@ -668,7 +712,11 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN; - } - -- pDvdVideoPicture->dts = m_dts; -+ if (pDvdVideoPicture->iRepeatPicture) -+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; -+ else -+ pDvdVideoPicture->dts = m_dts; -+ - m_dts = DVD_NOPTS_VALUE; - if (m_pFrame->reordered_opaque) - pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque); -@@ -699,7 +747,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - - bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) - { -- if(m_pHardware) -+ if(m_pHardware && !m_pHardware->UseFilter()) - return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture); - - if(!GetPictureCommon(pDvdVideoPicture)) -@@ -724,6 +772,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) - pix_fmt = (PixelFormat)m_pFrame->format; - - pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt); -+ - return true; - } - -@@ -738,7 +787,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) - if (filters.empty() && !scale) - return 0; - -- if (m_pHardware) -+ if (m_pHardware && !m_pHardware->UseFilter()) - { - CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode"); - return 0; -@@ -756,7 +805,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) - CStdString args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d", - m_pCodecContext->width, - m_pCodecContext->height, -- m_pCodecContext->pix_fmt, -+ m_pFrame->format, - m_pCodecContext->time_base.num, - m_pCodecContext->time_base.den, - m_pCodecContext->sample_aspect_ratio.num, -@@ -955,10 +1004,7 @@ bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &in - { - pts = m_decoderPts; - skippedDeint = m_skippedDeint; -- if (m_pFrame) -- interlaced = m_pFrame->interlaced_frame; -- else -- interlaced = 0; -+ interlaced = m_interlace; - return true; - } - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index c0ce198..4f88532 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -48,6 +48,8 @@ public: - virtual bool CanSkipDeint() {return false; } - virtual const std::string Name() = 0; - virtual CCriticalSection* Section() { return NULL; } -+ virtual bool UseFilter() { return false; } -+ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame) { return false; } - }; - - CDVDVideoCodecFFmpeg(); -@@ -134,4 +136,5 @@ protected: - int m_skippedDeint; - bool m_requestSkipDeint; - int m_codecControlFlags; -+ bool m_interlace; - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index bfefc9d..51f9bed 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -24,6 +24,17 @@ - #include "DVDVideoCodec.h" - #include - #include -+#include "utils/log.h" -+#include "threads/SingleLock.h" -+#include "XMemUtils.h" -+#include "utils/CPUInfo.h" -+#include "settings/Settings.h" -+ -+extern "C" { -+#include "libavutil/avutil.h" -+} -+ -+#define CACHED_BUFFER_SIZE 4096 - - #define CHECK(a) \ - do { \ -@@ -166,12 +177,17 @@ CDecoder::CDecoder() - m_context = 0; - m_hwaccel = (vaapi_context*)calloc(1, sizeof(vaapi_context)); - memset(m_surfaces, 0, sizeof(*m_surfaces)); -+ m_frame_buffer = NULL; -+ m_cache = NULL; - } - - CDecoder::~CDecoder() - { - Close(); - free(m_hwaccel); -+ _aligned_free(m_frame_buffer); -+ _aligned_free(m_cache); -+ m_dllSSE4.Unload(); - } - - void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic) -@@ -388,6 +404,11 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su - if (!EnsureContext(avctx)) - return false; - -+ if (avctx->width <= 1920 && avctx->height <= 1088) -+ CheckUseFilter(); -+ else -+ m_use_filter = false; -+ - m_hwaccel->display = m_display->get(); - - avctx->hwaccel_context = m_hwaccel; -@@ -472,7 +493,35 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) - return status; - - if(frame) -+ { -+ if (m_use_filter) -+ { -+ VASurfaceID surface = GetSurfaceID(frame); -+ std::list::iterator it; -+ for(it = m_surfaces_used.begin(); it != m_surfaces_used.end(); ++it) -+ { -+ if((*it)->m_id == surface) -+ { -+ m_holder.surface = *it; -+ break; -+ } -+ } -+ if (it == m_surfaces_used.end()) -+ { -+ CLog::Log(LOGERROR, "VAAPI::Decode - surface not found"); -+ return VC_ERROR; -+ } -+ CProcPic pic; -+ memset(&pic.frame, 0, sizeof(AVFrame)); -+ av_frame_ref(&pic.frame, frame); -+ pic.surface = *it; -+ m_surfaces_proc.push_back(pic); -+ if (m_surfaces_proc.size() < m_renderbuffers_count) -+ return VC_BUFFER; -+ } -+ - return VC_BUFFER | VC_PICTURE; -+ } - else - return VC_BUFFER; - } -@@ -550,4 +599,109 @@ unsigned CDecoder::GetAllowedReferences() - return m_renderbuffers_count; - } - -+void CDecoder::Reset() -+{ -+ m_surfaces_proc.clear(); -+} -+ -+void CDecoder::CheckUseFilter() -+{ -+ m_use_filter = true; -+ _aligned_free(m_frame_buffer); -+ _aligned_free(m_cache); -+ if (CSettings::Get().GetBool("videoplayer.usevaapiswfilter")) -+ { -+ if (!(g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE4)) -+ { -+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter cpu does not support SSE4"); -+ m_use_filter = false; -+ return; -+ } -+ if (!m_dllSSE4.Load()) -+ { -+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter failed loading sse4 lib"); -+ m_use_filter = false; -+ return; -+ } -+ VAImage image; -+ VASurfaceID surface = m_surfaces_free.front()->m_id; -+ VAStatus status = vaDeriveImage(m_display->get(), surface, &image); -+ m_use_filter = true; -+ if (status != VA_STATUS_SUCCESS) -+ { -+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter vaDeriveImage not supported"); -+ m_use_filter = false; -+ } -+ if (image.format.fourcc != VA_FOURCC_NV12) -+ { -+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter image format not NV12"); -+ m_use_filter = false; -+ } -+ if ((image.pitches[0] % 64) || (image.pitches[1] % 64)) -+ { -+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter patches no multiple of 64"); -+ m_use_filter = false; -+ } -+ if (m_use_filter) -+ { -+ m_frame_buffer = (uint8_t*)_aligned_malloc(image.height*image.width*2 + 256, 64); -+ m_cache = (uint8_t*)_aligned_malloc(CACHED_BUFFER_SIZE, 64); -+ } -+ vaDestroyImage(m_display->get(),image.image_id); -+ } -+ else -+ { -+ m_use_filter = false; -+ } -+} -+ -+bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame) -+{ -+ if (m_surfaces_proc.empty()) -+ { -+ return false; -+ } -+ if(frame) -+ { -+ CProcPic pic = m_surfaces_proc.front(); -+ m_surfaces_proc.pop_front(); -+ VASurfaceID surface = pic.surface->m_id; -+ VASurfaceStatus surf_status; -+ VAImage image; -+ uint8_t *buf; -+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status)) -+ while (surf_status != VASurfaceReady) -+ { -+ Sleep(1); -+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status)) -+ } -+ CHECK(vaDeriveImage(m_display->get(), surface, &image)); -+ CHECK(vaMapBuffer(m_display->get(), image.buf, (void**)&buf)) -+ -+ uint8_t *src, *dst; -+ src = buf + image.offsets[0]; -+ dst = m_frame_buffer + image.offsets[0]; -+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height, image.pitches[0]); -+ src = buf + image.offsets[1]; -+ dst = m_frame_buffer + image.offsets[1]; -+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]); -+ -+ av_frame_unref(frame); -+ av_frame_move_ref(frame, &pic.frame); -+ -+ frame->format = AV_PIX_FMT_NV12; -+ frame->data[0] = m_frame_buffer + image.offsets[0]; -+ frame->linesize[0] = image.pitches[0]; -+ frame->data[1] = m_frame_buffer + image.offsets[1]; -+ frame->linesize[1] = image.pitches[1]; -+ frame->data[2] = NULL; -+ frame->data[3] = NULL; -+ frame->pkt_size = image.data_size; -+ -+ CHECK(vaUnmapBuffer(m_display->get(), image.buf)) -+ CHECK(vaDestroyImage(m_display->get(),image.image_id)) -+ } -+ return true; -+} -+ - #endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index a520e42..755c192 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -29,7 +29,12 @@ - #include - #include - #include -+#include "linux/sse4/DllLibSSE4.h" - -+extern "C" { -+#include "libavcodec/vaapi.h" -+#include "libavcodec/avcodec.h" -+} - - namespace VAAPI { - -@@ -101,11 +106,31 @@ struct CHolder - {} - }; - -+struct CProcPic -+{ -+ AVFrame frame; -+ CSurfacePtr surface; -+ CProcPic() -+ {} -+ CProcPic(const CProcPic &other) -+ { -+ memcpy(&this->frame, &other.frame, sizeof(AVFrame)); -+ surface = other.surface; -+ } -+ CProcPic & operator= (const CProcPic &other) -+ { -+ memcpy(&this->frame, &other.frame, sizeof(AVFrame)); -+ surface = other.surface; -+ return *this; -+ } -+}; -+ - class CDecoder - : public CDVDVideoCodecFFmpeg::IHardwareDecoder - { - bool EnsureContext(AVCodecContext *avctx); - bool EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count); -+ void CheckUseFilter(); - public: - CDecoder(); - ~CDecoder(); -@@ -114,9 +139,12 @@ public: - virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); - virtual int Check (AVCodecContext* avctx); - virtual void Close(); -+ virtual void Reset(); - virtual const std::string Name() { return "vaapi"; } - virtual CCriticalSection* Section() { if(m_display) return m_display.get(); else return NULL; } - virtual unsigned GetAllowedReferences(); -+ virtual bool UseFilter() { return m_use_filter; } -+ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame); - - int GetBuffer(AVCodecContext *avctx, AVFrame *pic); - void RelBuffer(AVCodecContext *avctx, AVFrame *pic); -@@ -132,14 +160,20 @@ protected: - int m_refs; - std::list m_surfaces_used; - std::list m_surfaces_free; -+ std::list m_surfaces_proc; - - CDisplayPtr m_display; - VAConfigID m_config; - VAContextID m_context; -+ bool m_use_filter; -+ uint8_t *m_frame_buffer; -+ uint8_t *m_cache; - - vaapi_context *m_hwaccel; - - CHolder m_holder; // silly struct to pass data to renderer -+ -+ DllLibSSE4 m_dllSSE4; - }; - - } -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 9c5469b..b30e450 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -554,28 +554,6 @@ void CDVDPlayerVideo::Process() - // decoder still needs to provide an empty image structure, with correct flags - m_pVideoCodec->SetDropState(bRequestDrop); - -- // ask codec to do deinterlacing if possible -- EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -- EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); -- -- unsigned int mFilters = 0; -- -- if (mDeintMode != VS_DEINTERLACEMODE_OFF) -- { -- if (mInt == VS_INTERLACEMETHOD_DEINTERLACE) -- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY; -- else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF) -- mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED; -- -- if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters) -- mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED; -- } -- -- if (!g_renderManager.Supports(RENDERFEATURE_ROTATION)) -- mFilters |= CDVDVideoCodec::FILTER_ROTATE; -- -- mFilters = m_pVideoCodec->SetFilters(mFilters); -- - int iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts); - - // buffer packets so we can recover should decoder flush for some reason -@@ -662,6 +640,8 @@ void CDVDPlayerVideo::Process() - - //Deinterlace if codec said format was interlaced or if we have selected we want to deinterlace - //this video -+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -+ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod); - if ((mDeintMode == VS_DEINTERLACEMODE_AUTO && (picture.iFlags & DVP_FLAG_INTERLACED)) || mDeintMode == VS_DEINTERLACEMODE_FORCE) - { - if(mInt == VS_INTERLACEMETHOD_SW_BLEND) -@@ -704,7 +684,15 @@ void CDVDPlayerVideo::Process() - } - - if (picture.iRepeatPicture) -+ { -+ double pts; -+ int skipped, deint; -+ m_pVideoCodec->GetCodecStats(pts, skipped, deint); -+ picture.iDuration = frametime; -+ if (deint && (frametime <= 0.02*DVD_TIME_BASE)) -+ picture.iDuration *= 2; - picture.iDuration *= picture.iRepeatPicture + 1; -+ } - - int iResult = OutputPicture(&picture, pts); - --- -1.9.1 - - -From a866228fc54a4e95423387a83c8de012e247efc3 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 3 Jan 2014 20:50:46 +0100 -Subject: [PATCH 86/96] X11: check for user output on resize window - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 9962f08..c95f4ec 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -167,7 +167,20 @@ bool CWinSystemX11::DestroyWindow() - bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) - { - m_userOutput = CSettings::Get().GetString("videoscreen.monitor"); -- if (m_userOutput.compare("Default") == 0) -+ XOutput *out = NULL; -+ if (m_userOutput.compare("Default") != 0) -+ { -+ out = g_xrandr.GetOutput(m_userOutput); -+ if (out) -+ { -+ XMode mode = g_xrandr.GetCurrentMode(m_userOutput); -+ if (!mode.isCurrent) -+ { -+ out = NULL; -+ } -+ } -+ } -+ if (!out) - { - std::vector outputs = g_xrandr.GetModes(); - if (outputs.size() > 0) -@@ -176,8 +189,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - } - } - -- m_userOutput = g_xrandr.GetModes()[0].name; -- - if(m_nWidth == newWidth - && m_nHeight == newHeight - && m_userOutput.compare(m_currentOutput) == 0) --- -1.9.1 - - -From a153c72c0b53c9cbad7fc545abb7730e8eecaf19 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 24 Jan 2014 18:29:33 +0100 -Subject: [PATCH 87/96] dvdplayer: flush ffmpeg after hw decoder returned an - error - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 2df9de9..f4c9929 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -471,7 +471,12 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - result = m_pHardware->Decode(m_pCodecContext, NULL); - - if(result) -+ { -+ if (result & VC_ERROR) -+ avcodec_flush_buffers(m_pCodecContext); -+ - return result; -+ } - } - - if(m_pFilterGraph) -@@ -593,7 +598,11 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - - int result; - if(m_pHardware && !m_pHardware->UseFilter()) -+ { - result = m_pHardware->Decode(m_pCodecContext, m_pFrame); -+ if (result & VC_ERROR) -+ avcodec_flush_buffers(m_pCodecContext); -+ } - else if(m_pFilterGraph) - result = FilterProcess(m_pFrame); - else --- -1.9.1 - - -From d4e3e0920e61b7115b1053010fc7a00e1631e04a Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 28 Jan 2014 10:05:26 +0100 -Subject: [PATCH 88/96] xbmc pr 3080 - ---- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index f4c9929..283af9e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -495,6 +495,14 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - m_dllAvCodec.av_init_packet(&avpkt); - avpkt.data = pData; - avpkt.size = iSize; -+#define SET_PKT_TS(ts) \ -+ if(ts != DVD_NOPTS_VALUE)\ -+ avpkt.ts = (ts / DVD_TIME_BASE) * AV_TIME_BASE;\ -+ else\ -+ avpkt.ts = AV_NOPTS_VALUE -+ SET_PKT_TS(pts); -+ SET_PKT_TS(dts); -+#undef SET_PKT_TS - /* We lie, but this flag is only used by pngdec.c. - * Setting it correctly would allow CorePNG decoding. */ - avpkt.flags = AV_PKT_FLAG_KEY; -@@ -727,8 +735,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - pDvdVideoPicture->dts = m_dts; - - m_dts = DVD_NOPTS_VALUE; -- if (m_pFrame->reordered_opaque) -- pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque); -+ -+ int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame); -+ if(bpts != AV_NOPTS_VALUE) -+ pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; - else - pDvdVideoPicture->pts = DVD_NOPTS_VALUE; - --- -1.9.1 - - -From 23e4b30e3463b01d5f9acf1287767ca96c88fdb0 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 28 Jan 2014 17:24:58 +0100 -Subject: [PATCH 89/96] set preatpicture if pts is equal to last frame - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 283af9e..ff18b73 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -738,7 +738,15 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - - int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame); - if(bpts != AV_NOPTS_VALUE) -+ { - pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; -+ if (pDvdVideoPicture->pts == m_decoderPts) -+ { -+ pDvdVideoPicture->iRepeatPicture = -0.5; -+ pDvdVideoPicture->pts = DVD_NOPTS_VALUE; -+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; -+ } -+ } - else - pDvdVideoPicture->pts = DVD_NOPTS_VALUE; - --- -1.9.1 - - -From 3732925c369d10341ed813ea6c0775ea5ecc1cb5 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Mon, 27 Jan 2014 19:49:03 +0100 -Subject: [PATCH 90/96] Introduce SWCodec - these are codecs that don't have - any GPU acceleration (yet) - add HVEC - ---- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 15 +++++++++------ - .../cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- - xbmc/settings/AdvancedSettings.cpp | 4 ++-- - xbmc/settings/AdvancedSettings.h | 2 +- - 4 files changed, 13 insertions(+), 10 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index ff18b73..354e206 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -160,7 +160,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() - m_iScreenHeight = 0; - m_iOrientation = 0; - m_bSoftware = false; -- m_isHi10p = false; -+ m_isSWCodec = false; - m_pHardware = NULL; - m_iLastKeyframe = 0; - m_dts = DVD_NOPTS_VALUE; -@@ -216,10 +216,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - // this is needed to not open the decoders - m_bSoftware = true; - // this we need to enable multithreading for hi10p via advancedsettings -- m_isHi10p = true; -+ m_isSWCodec = true; - break; - } - } -+ else if (hints.codec == AV_CODEC_ID_HEVC) -+ m_isSWCodec = true; - - if(pCodec == NULL) - pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); -@@ -245,12 +247,12 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - * sensitive to changes in frame sizes, and it causes crashes - * during HW accell - so we unset it in this case. - * -- * When we detect Hi10p and user did not disable hi10pmultithreading -+ * When we detect a pure SW codec and user did not disable SWmultithreading - * via advancedsettings.xml we keep the ffmpeg default thread type. - * */ -- if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading) -+ if(m_isSWCodec && !g_advancedSettings.m_videoDisableSWMultithreading) - { -- CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d", -+ CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for swcodec: %d", - m_pCodecContext->thread_type); - } - else if ((EDECODEMETHOD) CSettings::Get().GetInt("videoplayer.decodingmethod") == VS_DECODEMETHOD_SOFTWARE && CSettings::Get().GetBool("videoplayer.useframemtdec")) -@@ -302,7 +304,8 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount()); - if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded - && ( pCodec->id == AV_CODEC_ID_H264 -- || pCodec->id == AV_CODEC_ID_MPEG4 )) -+ || pCodec->id == AV_CODEC_ID_MPEG4 -+ || pCodec->id == AV_CODEC_ID_HEVC)) - m_pCodecContext->thread_count = num_threads; - - if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 4f88532..e301aa8 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -126,7 +126,7 @@ protected: - - std::string m_name; - bool m_bSoftware; -- bool m_isHi10p; -+ bool m_isSWCodec; - IHardwareDecoder *m_pHardware; - int m_iLastKeyframe; - double m_dts; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 7532914..0d5e546 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -182,7 +182,7 @@ void CAdvancedSettings::Initialize() - m_stagefrightConfig.useInputDTS = false; - - m_videoDefaultLatency = 0.0; -- m_videoDisableHi10pMultithreading = false; -+ m_videoDisableSWMultithreading = false; - - m_musicUseTimeSeeking = true; - m_musicTimeSeekForward = 10; -@@ -599,7 +599,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f); - XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); - XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); -- XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading); -+ XMLUtils::GetBoolean(pElement,"disableswmultithreading",m_videoDisableSWMultithreading); - XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); - XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); - XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD); -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index c43351d..7075f05 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -194,7 +194,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - bool m_DXVANoDeintProcForProgressive; - int m_videoFpsDetect; - int m_videoBusyDialogDelay_ms; -- bool m_videoDisableHi10pMultithreading; -+ bool m_videoDisableSWMultithreading; - StagefrightConfig m_stagefrightConfig; - - CStdString m_videoDefaultPlayer; --- -1.9.1 - - -From 552f5cec0cd0a753fcd920a1d5d7b3eb6d37e696 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 11 Feb 2014 18:15:06 +0100 -Subject: [PATCH 91/96] ActiveAE: add some debug logging - ---- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -index 0287e73..6904cb9 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -@@ -276,7 +276,13 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size) - } - } - if (!m_inMsgEvent.WaitMSec(200)) -+ { -+ double cachetime = GetCacheTime(); -+ CSingleLock lock(m_streamLock); -+ CLog::Log(LOGWARNING, "CActiveAEStream::AddData - timeout waiting for buffer, paused: %d, cache time: %f, free buffers: %d", -+ m_paused, cachetime, m_streamFreeBuffers); - break; -+ } - } - return copied; - } --- -1.9.1 - - -From b10b79798aa7827134f34e5ad436e491a402cf77 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 1 Apr 2014 15:45:16 +0200 -Subject: [PATCH 92/96] X11: remove obsolete sdl include - ---- - xbmc/windowing/X11/WinSystemX11.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index d1c8729..5489543 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -25,7 +25,6 @@ - - #include "system_gl.h" - #include --#include - - #include "windowing/WinSystem.h" - #include "utils/Stopwatch.h" --- -1.9.1 - - -From da2f57d73f6df8892b759b465ee47d9401b390f9 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 13 Apr 2014 10:52:26 +0200 -Subject: [PATCH 93/96] squash fast channel - ---- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 13 ++++++++++--- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 + - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index f4ba29c..ca545c0 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -220,6 +220,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() - m_pkt.result = -1; - memset(&m_pkt.pkt, 0, sizeof(AVPacket)); - m_streaminfo = true; /* set to true if we want to look for streams before playback */ -+ m_checkvideo = false; - } - - CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() -@@ -448,11 +449,10 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) - if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) - m_pFormatContext->max_analyze_duration = 500000; - -- bool short_analyze = false; - if (iformat && (strcmp(iformat->name, "mpegts") == 0)) - { - m_pFormatContext->max_analyze_duration = 500000; -- short_analyze = true; -+ m_checkvideo = true; - } - - // we need to know if this is matroska or avi later -@@ -484,14 +484,17 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo) - } - CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); - -- if (short_analyze) -+ if (m_checkvideo) - { - // make sure we start video with an i-frame - ResetVideoStreams(); - } - } - else -+ { - m_program = 0; -+ m_checkvideo = true; -+ } - - // reset any timeout - m_timeout.SetInfinite(); -@@ -1784,6 +1787,10 @@ bool CDVDDemuxFFmpeg::IsVideoReady() - { - AVStream *st; - bool hasVideo = false; -+ -+ if(!m_checkvideo) -+ return true; -+ - if(m_program != UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index 9ec0877..c8d706b 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -166,5 +166,6 @@ protected: - bool m_bPtsWrap, m_bPtsWrapChecked; - int64_t m_iStartTime, m_iMaxTime, m_iEndTime; - bool m_streaminfo; -+ bool m_checkvideo; - }; - --- -1.9.1 - - -From 303fbf8b6724f2a01cb0ed213922dc8a6bd57b01 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 13 Apr 2014 15:34:26 +0200 -Subject: [PATCH 94/96] X11: do not call xrandr until we have a window - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c95f4ec..d1e6c1f 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -243,15 +243,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - - // only call xrandr if mode changes -- if (currmode.w != mode.w || currmode.h != mode.h || -- currmode.hz != mode.hz || currmode.id != mode.id) -+ if (m_mainWindow) - { -- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); -- OnLostDevice(); -- m_bIsInternalXrr = true; -- g_xrandr.SetMode(out, mode); -- if (m_mainWindow) -+ if (currmode.w != mode.w || currmode.h != mode.h || -+ currmode.hz != mode.hz || currmode.id != mode.id) -+ { -+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); -+ OnLostDevice(); -+ m_bIsInternalXrr = true; -+ g_xrandr.SetMode(out, mode); - return true; -+ } - } - } - #endif --- -1.9.1 - - -From 836de0e5d789ea37b526d5869477f356c5cebfd1 Mon Sep 17 00:00:00 2001 -From: Stefan Saraev -Date: Wed, 16 Apr 2014 12:40:42 +0300 -Subject: [PATCH 95/96] vaapi: fix build - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 13 ++----------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 5 ----- - 2 files changed, 2 insertions(+), 16 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 51f9bed..f957393 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -24,16 +24,10 @@ - #include "DVDVideoCodec.h" - #include - #include --#include "utils/log.h" --#include "threads/SingleLock.h" - #include "XMemUtils.h" - #include "utils/CPUInfo.h" - #include "settings/Settings.h" - --extern "C" { --#include "libavutil/avutil.h" --} -- - #define CACHED_BUFFER_SIZE 4096 - - #define CHECK(a) \ -@@ -512,8 +506,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) - return VC_ERROR; - } - CProcPic pic; -- memset(&pic.frame, 0, sizeof(AVFrame)); -- av_frame_ref(&pic.frame, frame); -+ memcpy(&pic.frame, frame, sizeof(AVFrame)); - pic.surface = *it; - m_surfaces_proc.push_back(pic); - if (m_surfaces_proc.size() < m_renderbuffers_count) -@@ -686,9 +679,7 @@ bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame) - dst = m_frame_buffer + image.offsets[1]; - m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]); - -- av_frame_unref(frame); -- av_frame_move_ref(frame, &pic.frame); -- -+ memcpy(frame, &pic.frame, sizeof(AVFrame)); - frame->format = AV_PIX_FMT_NV12; - frame->data[0] = m_frame_buffer + image.offsets[0]; - frame->linesize[0] = image.pitches[0]; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index 755c192..b6fb320 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -31,11 +31,6 @@ - #include - #include "linux/sse4/DllLibSSE4.h" - --extern "C" { --#include "libavcodec/vaapi.h" --#include "libavcodec/avcodec.h" --} -- - namespace VAAPI { - - typedef boost::shared_ptr VASurfacePtr; --- -1.9.1 - - -From d54319d818ed995076e5e4470673891788d0ef8e Mon Sep 17 00:00:00 2001 -From: Stefan Saraev -Date: Mon, 24 Feb 2014 20:58:52 +0200 -Subject: [PATCH 96/96] no hevc in ffmpeg 1.2 - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 354e206..6bc35b1 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -220,8 +220,11 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - break; - } - } -+ #ifdef AV_CODEC_ID_HEVC - else if (hints.codec == AV_CODEC_ID_HEVC) - m_isSWCodec = true; -+ #endif -+ - - if(pCodec == NULL) - pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec); -@@ -304,8 +307,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount()); - if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded - && ( pCodec->id == AV_CODEC_ID_H264 -- || pCodec->id == AV_CODEC_ID_MPEG4 -- || pCodec->id == AV_CODEC_ID_HEVC)) -+ || pCodec->id == AV_CODEC_ID_MPEG4 )) - m_pCodecContext->thread_count = num_threads; - - if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) --- -1.9.1 -