From b0fd40f8e14c0152b5838fdc349ab3e7ac4a0d49 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 12 Feb 2014 21:49:45 +0100 Subject: [PATCH] xbmc: update FM patches, revert if switching to XBMC vanilla Signed-off-by: Stephan Raue --- ...bmc-995.01-fernetmenta-fixes-59f249c.patch | 21458 ++++++++++++++++ ...bmc-995.01-fernetmenta-fixes-b3b79dd.patch | 9795 ------- .../xbmc-999-010-linux-static-ffmpeg.patch | 67 - .../patches/xbmc-999.991-ffmpeg-prefix.patch | 11 - 4 files changed, 21458 insertions(+), 9873 deletions(-) create mode 100644 packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-59f249c.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-999-010-linux-static-ffmpeg.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-999.991-ffmpeg-prefix.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-59f249c.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-59f249c.patch new file mode 100644 index 0000000000..56d7218e62 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-59f249c.patch @@ -0,0 +1,21458 @@ +From 63c5908fce61cf9b6fe56f684979cf5ec665b18c Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 18 Jan 2014 12:51:47 +0100 +Subject: [PATCH 001/116] [depends] move ffmpeg to unified deps + +--- + tools/depends/target/Makefile | 4 +- + tools/depends/target/ffmpeg/Makefile | 93 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 96 insertions(+), 1 deletion(-) + 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/Makefile b/tools/depends/target/ffmpeg/Makefile +new file mode 100644 +index 0000000..2319780 +--- /dev/null ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -0,0 +1,93 @@ ++include ../../Makefile.include ++DEPS= ../../Makefile.include Makefile ++ ++# set to "yes" to enable patching ++# we don't apply patches until we move to a vanilla ffmpeg tarball ++APPLY_PATCHES=no ++ ++# lib name, version ++LIBNAME=ffmpeg ++# ffmpeg GIT ++BASE_URL=https://github.com/FernetMenta/FFmpeg/archive ++VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz ++ ++ ++# 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 ++ffmpg_config += --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis ++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 ++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) ++ if test "$(APPLY_PATCHES)" = "yes"; then \ ++ cd $(PLATFORM); \ ++ for PATCH in ../patches/*.patch ; do \ ++ patch -p1 < $${PATCH}; \ ++ done; \ ++ fi ++ 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.8.5.1 + + +From bbc7721667905ddc8958a4f61072ed98ff5a8dcd Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 18 Jan 2014 21:58:35 +0100 +Subject: [PATCH 002/116] [configure] remove internal ffmpeg + +--- + Makefile.in | 16 +- + Makefile.include.in | 3 - + configure.in | 276 +++++++------------------------ + tools/depends/target/ffmpeg/autobuild.sh | 166 +++++++++++++++++++ + 4 files changed, 231 insertions(+), 230 deletions(-) + create mode 100755 tools/depends/target/ffmpeg/autobuild.sh + +diff --git a/Makefile.in b/Makefile.in +index 428b67c..a9dfc39 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -489,16 +489,16 @@ DYNOBJSXBMC+= xbmc/freebsd/freebsd.a + endif + + ifeq (@USE_STATIC_FFMPEG@,1) +-DYNOBJSXBMC += 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 ++DYNOBJSXBMC += @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 ++ + LIBS+= @GNUTLS_ALL_LIBS@ @VORBISENC_ALL_LIBS@ + endif +- + OBJSXBMC:=$(filter-out $(DYNOBJSXBMC), $(OBJSXBMC)) + + MAINOBJS=xbmc/xbmc.o +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 8ebe6f0..3346748 100644 +--- a/configure.in ++++ b/configure.in +@@ -185,13 +185,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], ++ [path to your ffmpeg install (default is search pkg-config or auto build)])], ++ [ffmpeg_dir=$with_ffmpeg], ++ [with_ffmpeg=auto]) ++ + AC_ARG_ENABLE([shared-lib], + [AS_HELP_STRING([--enable-shared-lib], + [build libxbmc. helpful for tests (default is no)])], +@@ -204,30 +207,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)])], +@@ -420,12 +405,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)])], +@@ -559,13 +538,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 +@@ -597,17 +569,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*) +@@ -615,7 +576,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 +@@ -688,7 +648,6 @@ case $host in + arm*-*-linux-gnu*) + ARCH="arm" + use_arch="arm" +- ffmpeg_target_os=linux + use_joystick=no + use_neon=yes + use_gles=yes +@@ -701,7 +660,6 @@ case $host in + use_arch="arm" + use_cpu=cortex-a9 + ARCH="arm" +- ffmpeg_target_os=linux + use_joystick=no + use_neon=yes + use_gles=yes +@@ -746,7 +704,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 + +@@ -822,7 +779,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 +@@ -843,14 +799,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" +@@ -859,7 +813,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" +@@ -868,7 +821,6 @@ 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 +@@ -1111,7 +1063,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 +@@ -1750,41 +1702,59 @@ 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" + +-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.]) ++if test "$with_ffmpeg" = "auto" -o "$with_ffmpeg" = "yes"; then ++ # check for system installed ffmpeg. We require our specific versions. ++ PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], ++ [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], ++ [FFMPEG_FOUND="false"]) ++ ++ if test "$with_ffmpeg" = "yes" -o "$FFMPEG_FOUND" != "true"; then ++ # ffmpeg not found with pkg-config, lets install it ++ AC_MSG_NOTICE("Installing FFmpeg") ++ ffmpeg_build=$(pwd)/tools/depends/target/ffmpeg ++ if test "$use_debug" != "yes"; then ++ OPTS="-r" ++ fi ++ if test "$use_optimizations" != "yes"; then ++ OPTS="${OPTS} --disable-optimizations" ++ fi ++ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ${ffmpeg_build}/autobuild.sh ${OPTS} ++ export PKG_CONFIG_PATH="${ffmpeg_build}/ffmpeg-install/lib/pkgconfig:$PKG_CONFIG_PATH" ++ fi ++elif test "$with_ffmpeg" != ""; then ++ # user specified --with-ffmpeg=/path/to/ffmpeg, lets use it ++ AC_MSG_NOTICE("using ffmpeg: ${with_ffmpeg}") ++ export PKG_CONFIG_PATH="${with_ffmpeg}/lib/pkgconfig:$PKG_CONFIG_PATH" + fi + +-# External FFmpeg +-if test "$use_external_ffmpeg" = "yes"; then +- FFMPEG_LIBNAMES="libavcodec libavfilter libavformat libavutil libpostproc libswscale libswresample" +- ++if test "$FFMPEG_FOUND" != "true"; then + PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], +- [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"], +- AC_MSG_ERROR($missing_library)) +- +- # in case the headers are in a custom directory +- SAVE_CPPFLAGS="$CPPFLAGS" +- CPPFLAGS="$CPPFLAGS $FFMPEG_CFLAGS" ++ [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], ++ [AC_MSG_ERROR("ffmpeg not found")]) ++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)]) ++# get the libdir for static linking ++FFMPEG_LIBDIR=$(${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) + +- AC_MSG_NOTICE($external_ffmpeg_enabled) +- USE_EXTERNAL_FFMPEG=1 +- AC_DEFINE([USE_EXTERNAL_FFMPEG], [1], [Whether to use external FFmpeg libraries.]) ++# in case the headers are in a custom directory ++SAVE_CPPFLAGS="$CPPFLAGS" ++CPPFLAGS="$CPPFLAGS $FFMPEG_CFLAGS" + +- CPPFLAGS="$SAVE_CPPFLAGS" +-else +- AC_MSG_NOTICE($external_ffmpeg_disabled) +- USE_EXTERNAL_FFMPEG=0 +-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("ffmpeg headers missing")]) ++# TODO: make this conditional ++USE_STATIC_FFMPEG=1 ++CPPFLAGS="$SAVE_CPPFLAGS" + + echo "Checking for SWIG installation" + AC_PATH_PROG(SWIG_EXE, swig, "none") +@@ -2463,12 +2433,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 +@@ -2608,9 +2572,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) +@@ -2709,134 +2675,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" \ +- --disable-static \ +- `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; else echo --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" && test "$host_cpu" = "i686"; then echo --disable-mmx; fi #workaround for gcc 4.6 bug` \ +- `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..b062502 +--- /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 ++BUILDTHREADS=${BUILDTHREADS:-"2"} ++ ++BASE_URL=https://github.com/FernetMenta/FFmpeg/archive ++VERSION=$(grep "VERSION=" Makefile | 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 ++ ++[ -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} ++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.8.5.1 + + +From 8c367e20f647146d4c367735e40a0c6c92151208 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 22 Jan 2014 11:45:48 +0100 +Subject: [PATCH 003/116] 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 | 127 ------ + 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 | 19 +- + 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 +- + .../Audio/DVDAudioCodecPassthroughFFmpeg.cpp | 30 +- + .../Audio/DVDAudioCodecPassthroughFFmpeg.h | 10 +- + 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 | 202 +++------ + .../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 | 132 +++--- + 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 | 116 +++--- + xbmc/utils/BitstreamConverter.h | 13 +- + xbmc/video/FFmpegVideoDecoder.cpp | 89 ++-- + xbmc/video/FFmpegVideoDecoder.h | 11 +- + 91 files changed, 756 insertions(+), 3693 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 a9dfc39..5c0d66d 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 \ +@@ -190,10 +189,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/xbadpcm \ + lib/nosefart \ +@@ -406,7 +401,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 3346748..d782251 100644 +--- a/configure.in ++++ b/configure.in +@@ -2464,7 +2464,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 05e5c6f..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) +- 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 e9542eb..0000000 +--- a/lib/DllPostProc.h ++++ /dev/null +@@ -1,127 +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() { +- CLog::Log(LOGDEBUG, "DllPostProc: Using libpostproc system library"); +- 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 @@ + + 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() + { + 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 0a4aba0..ac5457c 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -175,10 +175,6 @@ void CActiveAE::Dispose() + m_controlPort.Purge(); + m_dataPort.Purge(); + m_sink.Dispose(); +- +- m_dllAvFormat.Unload(); +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); + } + + //----------------------------------------------------------------------------- +@@ -1966,7 +1962,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; + +@@ -2049,13 +2045,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, +@@ -2301,19 +2290,19 @@ void CActiveAE::OnResetDevice() + 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; + } + +@@ -2357,9 +2346,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) +@@ -2370,22 +2359,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; +@@ -2393,39 +2382,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; + } +@@ -2433,7 +2422,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); +@@ -2443,12 +2432,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 debc8e1..9a62624 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +@@ -30,9 +30,11 @@ + #include "guilib/DispResource.h" + + // 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; +@@ -340,11 +342,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 ca19263..55a944f 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,33 +58,33 @@ 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); + 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 +@@ -91,7 +93,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(!m_pContext) +@@ -116,10 +118,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; +@@ -131,7 +133,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 b5d9776..24b3e90 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 @@ + 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 0ecaecf..84c0217 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +@@ -41,13 +41,17 @@ + #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" + #include "RenderCapture.h" + #include "RenderFormats.h" + #include "cores/IPlayer.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 @@ + m_nonLinStretch = false; + m_nonLinStretchGui = false; + m_pixelRatio = 0.0f; +- +- m_dllSwScale = new DllSwScale; + } + + CLinuxRendererGL::~CLinuxRendererGL() +@@ -213,7 +215,7 @@ + + if (m_context) + { +- m_dllSwScale->sws_freeContext(m_context); ++ sws_freeContext(m_context); + m_context = NULL; + } + +@@ -223,8 +225,6 @@ + delete m_pYUVShader; + m_pYUVShader = NULL; + } +- +- delete m_dllSwScale; + } + + bool CLinuxRendererGL::ValidateRenderer() +@@ -778,9 +778,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; + } + +@@ -3157,14 +3154,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) + { +@@ -3237,9 +3234,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 }; +@@ -3247,8 +3244,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 @@ enum RenderQuality + 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 452a958..6528f54 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +@@ -44,7 +44,6 @@ + #include "windowing/WindowingFactory.h" + #include "dialogs/GUIDialogKaiToast.h" + #include "guilib/Texture.h" +-#include "lib/DllSwScale.h" + #include "../dvdplayer/DVDCodecs/Video/OpenMaxVideo.h" + #include "threads/SingleLock.h" + #include "RenderCapture.h" +@@ -52,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" +@@ -133,7 +136,6 @@ + m_rgbBuffer = NULL; + m_rgbBufferSize = 0; + +- m_dllSwScale = new DllSwScale; + m_sw_context = NULL; + m_NumYV12Buffers = 0; + m_iLastRenderBuffer = 0; +@@ -168,8 +170,6 @@ + delete m_pYUVShader; + m_pYUVShader = NULL; + } +- +- delete m_dllSwScale; + } + + bool CLinuxRendererGLES::ValidateRenderTarget() +@@ -607,9 +607,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; + } + +@@ -838,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; + } + +@@ -1679,7 +1676,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); +@@ -1688,7 +1685,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 @@ enum RenderQuality + 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 cc8fa4c..4543404 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 2453c65..ee41991 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +@@ -61,12 +61,7 @@ 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); +@@ -78,7 +73,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options + m_bLpcmMode = true; + #endif + +- 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; +@@ -98,7 +93,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; +@@ -106,14 +101,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; + +@@ -122,27 +117,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; +@@ -157,10 +148,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); +@@ -169,7 +160,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) +@@ -209,17 +200,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; +@@ -228,10 +219,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); +@@ -244,7 +235,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) + { +@@ -260,7 +251,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); + } + } + +@@ -283,7 +274,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; +@@ -362,7 +353,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 ab461ab..e231f56 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 + { +@@ -64,10 +67,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/Audio/DVDAudioCodecPassthroughFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp +index f49b5b5..f6a680f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp +@@ -81,7 +81,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + /* get the muxer */ + AVOutputFormat *fOut = NULL; + +- fOut = m_dllAvFormat.av_guess_format(muxerName.c_str(), NULL, NULL); ++ fOut = av_guess_format(muxerName.c_str(), NULL, NULL); + if (!fOut) + { + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to get the FFmpeg %s muxer", muxerName.c_str()); +@@ -90,7 +90,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + } + + /* allocate a the format context */ +- muxer.m_pFormat = m_dllAvFormat.avformat_alloc_context(); ++ muxer.m_pFormat = avformat_alloc_context(); + if (!muxer.m_pFormat) + { + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate AVFormat context"); +@@ -101,7 +101,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + muxer.m_pFormat->oformat = fOut; + + /* allocate a put_byte struct so we can grab the output */ +- muxer.m_pFormat->pb = m_dllAvFormat.avio_alloc_context(muxer.m_BCBuffer, sizeof(muxer.m_BCBuffer), AVIO_FLAG_READ, &muxer, NULL, MuxerReadPacket, NULL); ++ muxer.m_pFormat->pb = avio_alloc_context(muxer.m_BCBuffer, sizeof(muxer.m_BCBuffer), AVIO_FLAG_READ, &muxer, NULL, MuxerReadPacket, NULL); + if (!muxer.m_pFormat->pb) + { + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate ByteIOContext"); +@@ -125,7 +125,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + #endif + + /* request output of wanted endianness */ +- if (!fOut->priv_class || m_dllAvUtil.av_opt_set(muxer.m_pFormat->priv_data, "spdif_flags", spdifFlags, 0) != 0) ++ if (!fOut->priv_class || av_opt_set(muxer.m_pFormat->priv_data, "spdif_flags", spdifFlags, 0) != 0) + { + #if defined(WORDS_BIGENDIAN) && !defined(TARGET_DARWIN) + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Unable to set big-endian stream mode (FFmpeg too old?), disabling passthrough"); +@@ -135,7 +135,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + } + + /* add a stream to it */ +- muxer.m_pStream = m_dllAvFormat.avformat_new_stream(muxer.m_pFormat, NULL); ++ muxer.m_pStream = avformat_new_stream(muxer.m_pFormat, NULL); + if (!muxer.m_pStream) + { + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate AVStream context"); +@@ -160,7 +160,7 @@ bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdStri + codec->extradata_size = hints.extrasize; + memcpy(codec->extradata, hints.extradata, hints.extrasize); + +- muxer.m_WroteHeader = m_dllAvFormat.avformat_write_header(muxer.m_pFormat, NULL) == 0; ++ muxer.m_WroteHeader = avformat_write_header(muxer.m_pFormat, NULL) == 0; + if (!muxer.m_WroteHeader) + { + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to write the frame header"); +@@ -190,12 +190,12 @@ int CDVDAudioCodecPassthroughFFmpeg::MuxerReadPacket(void *opaque, uint8_t *buf, + void CDVDAudioCodecPassthroughFFmpeg::WriteFrame(Muxer &muxer, uint8_t *pData, int iSize) + { + AVPacket pkt; +- m_dllAvCodec.av_init_packet(&pkt); ++ av_init_packet(&pkt); + pkt.data = pData; + pkt.size = iSize; + + muxer.m_Consumed += iSize; +- if (m_dllAvFormat.av_write_frame(muxer.m_pFormat, &pkt) < 0) ++ if (av_write_frame(muxer.m_pFormat, &pkt) < 0) + CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::WriteFrame - Failed to write the frame data"); + } + +@@ -269,13 +269,13 @@ void CDVDAudioCodecPassthroughFFmpeg::DisposeMuxer(Muxer &muxer) + if (muxer.m_pFormat) + { + if (muxer.m_WroteHeader) +- m_dllAvFormat.av_write_trailer(muxer.m_pFormat); ++ av_write_trailer(muxer.m_pFormat); + muxer.m_WroteHeader = false; + if (muxer.m_pStream) + delete[] muxer.m_pStream->codec->extradata; +- m_dllAvUtil.av_freep(&muxer.m_pFormat->pb); +- m_dllAvUtil.av_freep(&muxer.m_pFormat); +- m_dllAvUtil.av_freep(&muxer.m_pStream); ++ av_freep(&muxer.m_pFormat->pb); ++ av_freep(&muxer.m_pFormat); ++ av_freep(&muxer.m_pStream); + } + } + /*===================== END MUXER FUNCTIONS ========================*/ +@@ -320,10 +320,10 @@ bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptio + return false; + } + +- if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load()) ++ if (!Load() || !Load() || !Load()) + return false; + +- m_dllAvFormat.av_register_all(); ++ av_register_all(); + + /* see if the muxer supports our codec (see spdif.c for supported formats) */ + if (!SupportsFormat(hints)) +@@ -554,7 +554,7 @@ unsigned int CDVDAudioCodecPassthroughFFmpeg::SyncAC3(uint8_t* pData, unsigned i + 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/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h +index 16facb4..8016fb0 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h +@@ -22,9 +22,9 @@ + + #include + #include "system.h" +-#include "DllAvFormat.h" +-#include "DllAvCodec.h" +-#include "DllAvUtil.h" ++#include "libavformat/avformat.h" ++#include "libavcodec/avcodec.h" ++#include "libavutil/avutil.h" + + #include "DVDAudioCodec.h" + +@@ -49,10 +49,6 @@ class CDVDAudioCodecPassthroughFFmpeg : public CDVDAudioCodec + virtual const char* GetName() { return "PassthroughFFmpeg"; } + virtual int GetBufferSize(); + private: +- DllAvFormat m_dllAvFormat; +- DllAvUtil m_dllAvUtil; +- DllAvCodec m_dllAvCodec; +- + typedef struct + { + int size; +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 @@ + + 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 @@ class CMPCOutputThread : public CThread + 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 @@ class CMPCOutputThread : public CThread + 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 a028d5e..54c5cc8 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -62,6 +62,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 +@@ -71,7 +78,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + + // if frame threading is enabled hw accel is not allowed + if(!ctx->IsHardwareAllowed() || CSettings::Get().GetBool("videoplayer.useframemtdec")) +- 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) +@@ -133,7 +140,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() +@@ -143,11 +150,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + 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; +@@ -174,16 +177,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; + +@@ -218,7 +211,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) + { +@@ -229,7 +222,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; +@@ -275,7 +268,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); + } + +@@ -292,7 +285,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()); +@@ -301,19 +294,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; +@@ -321,33 +312,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) +@@ -475,13 +459,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; +@@ -556,7 +540,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(); +@@ -570,14 +554,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) +@@ -591,10 +567,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; +@@ -619,7 +591,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)); +@@ -689,12 +661,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; +@@ -717,14 +684,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, +@@ -735,64 +702,56 @@ 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 = 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, buffersink_params, m_pFilterGraph)) < 0) + { +- m_dllAvUtil.av_freep(&buffersink_params); ++ av_freep(&buffersink_params); + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out"); + return result; + } +- m_dllAvUtil.av_freep(&buffersink_params); ++ av_freep(&buffersink_params); + + 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; +@@ -803,17 +762,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; +@@ -827,19 +778,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"); +@@ -847,8 +786,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; +@@ -858,54 +796,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 @@ static void GetFrameDisplayTimeFromDictionary( + 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 @@ void vtdec_session_dump_properties(VTDecompressionSessionRef session) + 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 @@ bool validate_avcC_spc(uint8_t *extradata, uint32_t extrasize, int32_t *max_ref_ + + 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 @@ + 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 79f8cea..8d7a633 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -524,9 +524,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; + + { +@@ -592,11 +589,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 2dd3c28..e60fc65 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; + +@@ -611,7 +613,6 @@ class CDecoder + CCriticalSection m_DecoderSection; + CEvent m_DisplayEvent; + +- 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 9c642f6..c23b82d 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +@@ -34,7 +34,10 @@ + #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 1146c6f..e957994 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,17 +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"); ++ 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 +@@ -298,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; +@@ -332,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 +@@ -349,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()); +@@ -358,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 +@@ -372,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) + { +@@ -381,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) + { +@@ -404,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) +@@ -430,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(); +@@ -458,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()); +@@ -483,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(); + +@@ -495,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) + { +@@ -504,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; +@@ -520,10 +510,6 @@ void CDVDDemuxFFmpeg::Dispose() + DisposeStreams(); + + m_pInput = NULL; +- +- m_dllAvFormat.Unload(); +- m_dllAvCodec.Unload(); +- m_dllAvUtil.Unload(); + } + + void CDVDDemuxFFmpeg::Reset() +@@ -537,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() +@@ -558,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; + +@@ -604,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")) +@@ -616,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; +@@ -676,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(); + } + +@@ -715,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 + { +@@ -800,7 +786,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; +@@ -812,7 +798,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 +@@ -869,7 +855,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) +@@ -902,7 +888,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(); +@@ -927,13 +913,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); + } +@@ -1080,8 +1066,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) + st->iBitRate = pStream->codec->bit_rate; + st->iBitsPerSample = pStream->codec->bits_per_coded_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; + } +@@ -1099,7 +1085,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 +@@ -1148,11 +1134,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; + +@@ -1193,8 +1179,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; + } +@@ -1207,7 +1193,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; +@@ -1248,7 +1234,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); + +@@ -1379,7 +1365,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; +@@ -1460,7 +1446,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 e5f8234..7fec32f 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 @@ void CDemuxStreamSubtitlePVRClient::GetStreamInfo(std::string& strInfo) + + 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 e2e2b01..6bb2d92 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 cfd3dc3..05a758f 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() + { +- 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 4fbd3bd..7d7fb37 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 6cc6817..0bbc0b5 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 @@ bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size) + 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,11 +408,6 @@ 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) +@@ -484,7 +464,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; +@@ -492,25 +472,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; +@@ -519,13 +499,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; + } +@@ -608,14 +588,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); +@@ -695,7 +677,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; + } +@@ -712,7 +694,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; +@@ -747,8 +729,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; + } +@@ -758,14 +740,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; + } + +@@ -810,26 +792,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 @@ + 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.8.5.1 + + +From a860beefc4cca98ecbaaa4ad2da5a9c5ed8ab8a6 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 24 Jan 2014 13:15:08 +0100 +Subject: [PATCH 004/116] 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 99b2484..c04b58f 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -347,6 +347,8 @@ + #include "utils/AMLUtils.h" + #endif + ++#include "lib/ffmpeg.h" ++ + using namespace std; + using namespace ADDON; + using namespace XFILE; +@@ -777,6 +779,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 +@@ -3599,6 +3612,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 e957994..8fc57b1 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.8.5.1 + + +From 1d8bf221dc7a1f4b50b69348c1a83303c02d9434 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 25 Jan 2014 12:26:42 +0100 +Subject: [PATCH 005/116] 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 c04b58f..20cfe0c 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -347,7 +347,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 8fc57b1..3249c9f 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.8.5.1 + + +From 0d965c2eef8d760f949212854be3d009150b2ad6 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 31 Jan 2014 09:46:08 +0100 +Subject: [PATCH 006/116] 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 d35ea97..addeb16 100644 +--- a/xbmc/DllPaths_generated.h.in ++++ b/xbmc/DllPaths_generated.h.in +@@ -72,15 +72,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.8.5.1 + + +From bb14181eeb6e13b7d8493f2281a7824186a36d30 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 31 Jan 2014 15:25:31 +0100 +Subject: [PATCH 007/116] sq to configure - add --with-ffmpeg=force option this + will always build our ffmpeg version, even if its found in system + +--- + configure.in | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/configure.in b/configure.in +index d782251..47ded02 100644 +--- a/configure.in ++++ b/configure.in +@@ -1711,6 +1711,14 @@ FFMPEG_LIBNAMES="libavcodec >= 55.39.101 + libswscale >= 2.5.101 + libswresample >= 0.17.104" + ++ffmpeg_build="$(pwd)/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 ++ + if test "$with_ffmpeg" = "auto" -o "$with_ffmpeg" = "yes"; then + # check for system installed ffmpeg. We require our specific versions. + PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], +@@ -1720,18 +1728,15 @@ if test "$with_ffmpeg" = "auto" -o "$with_ffmpeg" = "yes"; then + if test "$with_ffmpeg" = "yes" -o "$FFMPEG_FOUND" != "true"; then + # ffmpeg not found with pkg-config, lets install it + AC_MSG_NOTICE("Installing FFmpeg") +- ffmpeg_build=$(pwd)/tools/depends/target/ffmpeg +- if test "$use_debug" != "yes"; then +- OPTS="-r" +- fi +- if test "$use_optimizations" != "yes"; then +- OPTS="${OPTS} --disable-optimizations" +- fi +- CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ${ffmpeg_build}/autobuild.sh ${OPTS} ++ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ${ffmpeg_build}/autobuild.sh ${FFMPEG_OPTS} + export PKG_CONFIG_PATH="${ffmpeg_build}/ffmpeg-install/lib/pkgconfig:$PKG_CONFIG_PATH" + fi +-elif test "$with_ffmpeg" != ""; then +- # user specified --with-ffmpeg=/path/to/ffmpeg, lets use it ++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} ++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 +-- +1.8.5.1 + + +From 96b25e9054663ee4d78e7caf2c1885c5fdf3ad01 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 1 Feb 2014 20:06:59 +0100 +Subject: [PATCH 008/116] only enable auto building ffmpeg if we are not cross + compiling + +--- + configure.in | 52 +++++++++++++++++++++++++++------------------------- + 1 file changed, 27 insertions(+), 25 deletions(-) + +diff --git a/configure.in b/configure.in +index 47ded02..2c90dac 100644 +--- a/configure.in ++++ b/configure.in +@@ -1711,34 +1711,36 @@ FFMPEG_LIBNAMES="libavcodec >= 55.39.101 + libswscale >= 2.5.101 + libswresample >= 0.17.104" + +-ffmpeg_build="$(pwd)/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 +- +-if test "$with_ffmpeg" = "auto" -o "$with_ffmpeg" = "yes"; then +- # check for system installed ffmpeg. We require our specific versions. +- PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], +- [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], +- [FFMPEG_FOUND="false"]) ++if test "$cross_compiling" != "yes"; then ++ ffmpeg_build="$(pwd)/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 + +- if test "$with_ffmpeg" = "yes" -o "$FFMPEG_FOUND" != "true"; then +- # ffmpeg not found with pkg-config, lets install it +- AC_MSG_NOTICE("Installing FFmpeg") ++ if test "$with_ffmpeg" = "auto" -o "$with_ffmpeg" = "yes"; then ++ # check for system installed ffmpeg. We require our specific versions. ++ PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES], ++ [INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"; FFMPEG_FOUND="true"], ++ [FFMPEG_FOUND="false"]) ++ ++ if test "$with_ffmpeg" = "yes" -o "$FFMPEG_FOUND" != "true"; 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 ++ 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" ++ 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 +-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} +-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 + + if test "$FFMPEG_FOUND" != "true"; then +-- +1.8.5.1 + + +From 85e2a51054fc6b5a606dc8ba63e4233cf180f6b8 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Fri, 31 Jan 2014 10:54:08 +0100 +Subject: [PATCH 009/116] [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..042cbae +--- 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 ++ [ -w $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.8.5.1 + + +From 40f5aa6cd6395a506f7d72e9e94d0d25f201c4c3 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sat, 1 Feb 2014 22:34:16 +0100 +Subject: [PATCH 010/116] sq to configure - fixup after upstream rebase + +--- + configure.in | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/configure.in b/configure.in +index 2c90dac..d26ea95 100644 +--- a/configure.in ++++ b/configure.in +@@ -588,8 +588,6 @@ case $host in + if test "$use_cpu" = "no" -a "$cross_compiling" = "yes"; then + use_arch="x86" + use_cpu="i686" +- else +- target_platform=target_linux + fi + ;; + x86_64-*-linux-gnu*|x86_64-*-linux-uclibc*) +@@ -597,8 +595,6 @@ case $host in + if test "$use_cpu" = "no" -a "$cross_compiling" = "yes"; then + use_arch="x86_64" + use_cpu="x86_64" +- else +- target_platform=target_linux + fi + ;; + i386-*-freebsd*) +@@ -824,15 +820,6 @@ elif test "$use_arch" = "arm"; then + fi + fi + fi +-if test "$target_platform" = "target_linux"; then +- USE_STATIC_FFMPEG=1 +- use_static_ffmpeg=yes +- 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` +- VORBISENC_ALL_LIBS=`${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc` +-fi + + # Checks for library functions. + AC_FUNC_ALLOCA +@@ -2628,8 +2615,6 @@ AC_SUBST(USE_ANDROID) + AC_SUBST(GTEST_CONFIGURED) + AC_SUBST(USE_DOXYGEN) + AC_SUBST(USE_PVR_ADDONS) +-AC_SUBST(GNUTLS_ALL_LIBS) +-AC_SUBST(VORBISENC_ALL_LIBS) + + # pushd and popd are not available in other shells besides bash, so implement + # our own pushd/popd functions +-- +1.8.5.1 + + +From cf8403e84941ed9827cf82326f60e83868984119 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sun, 2 Feb 2014 09:57:00 +0100 +Subject: [PATCH 011/116] add ffmpeg makefile for rpi + +--- + tools/rbp/depends/Makefile | 4 +-- + tools/rbp/depends/ffmpeg/Makefile | 71 +++++++++++++++++++++++++++++++++++++++ + tools/rbp/depends/xbmc/Makefile | 1 + + 3 files changed, 74 insertions(+), 2 deletions(-) + create mode 100644 tools/rbp/depends/ffmpeg/Makefile + +diff --git a/tools/rbp/depends/Makefile b/tools/rbp/depends/Makefile +index 5afbc5a..ff5ad21 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'` +diff --git a/tools/rbp/depends/ffmpeg/Makefile b/tools/rbp/depends/ffmpeg/Makefile +new file mode 100644 +index 0000000..9079eaf +--- /dev/null ++++ b/tools/rbp/depends/ffmpeg/Makefile +@@ -0,0 +1,71 @@ ++include ../../Makefile.include ++include ../depends.mk ++DEPS= ../../Makefile.include ../depends.mk Makefile ++ ++# set to "yes" to enable patching ++# we don't apply patches until we move to a vanilla ffmpeg tarball ++APPLY_PATCHES=no ++ ++# lib name, version ++LIBNAME=ffmpeg ++# ffmpeg GIT ++BASE_URL=https://github.com/FernetMenta/FFmpeg/archive ++VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz ++ ++ ++# 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-rpi ++ ++$(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) ++ ++build: rpi ++ $(MAKE) -j $(JOBS) -C rpi ++ ++.installed-rpi: build ++ $(MAKE) -C rpi install ++ touch $@ ++ ++clean: ++ $(MAKE) -C rpi clean ++ rm -f .installed-rpi ++ ++distclean:: ++ rm -rf rpi .installed-rpi ++ +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.8.5.1 + + +From 821242726498d6fda84c42b00799ca562062151b Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Sun, 2 Feb 2014 16:31:16 +0100 +Subject: [PATCH 012/116] sq to configure - unset PKG_CONFIG_SYSROOT_DIR when + getting FFMPEG_LIBDIR + +--- + configure.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configure.in b/configure.in +index d26ea95..66c6332 100644 +--- a/configure.in ++++ b/configure.in +@@ -1737,9 +1737,9 @@ if test "$FFMPEG_FOUND" != "true"; then + fi + + # get the libdir for static linking +-FFMPEG_LIBDIR=$(${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) ++FFMPEG_LIBDIR=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --variable=libdir libavcodec) ++GNUTLS_ALL_LIBS=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --libs-only-l --silence-errors gnutls) ++VORBISENC_ALL_LIBS=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc) + + # in case the headers are in a custom directory + SAVE_CPPFLAGS="$CPPFLAGS" +-- +1.8.5.1 + + +From fe07d9c00a9fd752c8ffe453e3b1a22c9b995d87 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Mon, 3 Feb 2014 09:56:45 +0100 +Subject: [PATCH 013/116] sq to setup-sdk.sh - fix sudo needs detection + +--- + tools/rbp/setup-sdk.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/rbp/setup-sdk.sh b/tools/rbp/setup-sdk.sh +index 042cbae..70f2a36 100755 +--- a/tools/rbp/setup-sdk.sh ++++ b/tools/rbp/setup-sdk.sh +@@ -23,7 +23,7 @@ fi + + if [ -d $XBMCPREFIX ] + then +- [ -w $XBMCPREFIX ] || SUDO="sudo" ++ [ -O $XBMCPREFIX ] || SUDO="sudo" + else + [ -w $(dirname $XBMCPREFIX) ] || SUDO="sudo" + fi +-- +1.8.5.1 + + +From 09b52d3ca22171fc36ab9ee3ba43a48b87db4614 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 2 Feb 2014 15:17:20 +0100 +Subject: [PATCH 014/116] bump ffmpeg + +--- + tools/depends/target/ffmpeg/Makefile | 2 +- + tools/rbp/depends/ffmpeg/Makefile | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index 2319780..808c2a3 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -9,7 +9,7 @@ APPLY_PATCHES=no + LIBNAME=ffmpeg + # ffmpeg GIT + BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++VERSION=11086c540305ffb208e6fc17d301db989d3c4151 + ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz + + +diff --git a/tools/rbp/depends/ffmpeg/Makefile b/tools/rbp/depends/ffmpeg/Makefile +index 9079eaf..3c26de1 100644 +--- a/tools/rbp/depends/ffmpeg/Makefile ++++ b/tools/rbp/depends/ffmpeg/Makefile +@@ -10,7 +10,7 @@ APPLY_PATCHES=no + LIBNAME=ffmpeg + # ffmpeg GIT + BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=9292bac08d62b92fcd66a8df468741190269f510 ++VERSION=11086c540305ffb208e6fc17d301db989d3c4151 + ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz + + +-- +1.8.5.1 + + +From 50e69b0c00292f99ec26a9113b558bb63f13891d Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Thu, 6 Feb 2014 13:32:27 +0100 +Subject: [PATCH 015/116] sq to depends - add a single file to specify our + ffmpeg version + +--- + tools/depends/target/ffmpeg/FFMPEG-VERSION | 5 +++++ + tools/depends/target/ffmpeg/Makefile | 11 ++--------- + 2 files changed, 7 insertions(+), 9 deletions(-) + create mode 100644 tools/depends/target/ffmpeg/FFMPEG-VERSION + +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 +index 808c2a3..ad91f64 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -1,18 +1,11 @@ + include ../../Makefile.include +-DEPS= ../../Makefile.include Makefile ++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 + +-# lib name, version +-LIBNAME=ffmpeg +-# ffmpeg GIT +-BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=11086c540305ffb208e6fc17d301db989d3c4151 +-ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz +- +- + # configuration settings + ffmpg_config = --prefix=$(PREFIX) + ffmpg_config += --cc=$(CC) --cxx=$(CXX) +-- +1.8.5.1 + + +From 7cb23bacc93cb06eb30763a185f37c1f6d0759f7 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Thu, 6 Feb 2014 13:57:15 +0100 +Subject: [PATCH 016/116] sq to rpi ffmpeg makefile - use FFMPEG-VERSION file + +--- + tools/rbp/depends/ffmpeg/Makefile | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/tools/rbp/depends/ffmpeg/Makefile b/tools/rbp/depends/ffmpeg/Makefile +index 3c26de1..79a23d6 100644 +--- a/tools/rbp/depends/ffmpeg/Makefile ++++ b/tools/rbp/depends/ffmpeg/Makefile +@@ -1,19 +1,12 @@ + include ../../Makefile.include + include ../depends.mk +-DEPS= ../../Makefile.include ../depends.mk Makefile ++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 + +-# lib name, version +-LIBNAME=ffmpeg +-# ffmpeg GIT +-BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=11086c540305ffb208e6fc17d301db989d3c4151 +-ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz +- +- + # configuration settings + ffmpg_config = --sysroot=$(SYSROOT) --prefix=$(PREFIX) + ffmpg_config += --enable-cross-compile --target-os=linux --cpu=arm1176jzf-s --arch=arm +-- +1.8.5.1 + + +From 9c34233532018b9cbdbee39f8a5db01a5fdcbf50 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Thu, 6 Feb 2014 13:51:20 +0100 +Subject: [PATCH 017/116] sq to configure - use FFMPEG-VERSION file in + autobuild.sh + +--- + tools/depends/target/ffmpeg/autobuild.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh +index b062502..b7a1ba6 100755 +--- a/tools/depends/target/ffmpeg/autobuild.sh ++++ b/tools/depends/target/ffmpeg/autobuild.sh +@@ -19,14 +19,12 @@ + # + + +- + MYDIR=$(cd $(dirname $0); pwd) + cd $MYDIR + FFMPEG_PREFIX=${MYDIR}/ffmpeg-install +-BUILDTHREADS=${BUILDTHREADS:-"2"} + +-BASE_URL=https://github.com/FernetMenta/FFmpeg/archive +-VERSION=$(grep "VERSION=" Makefile | sed 's/VERSION=//g') ++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 { +@@ -102,6 +100,8 @@ do + 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 +@@ -112,7 +112,7 @@ 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} ++[ -d ffmpeg-${VERSION} ] && rm -rf ffmpeg-${VERSION} && rm .ffmpeg-installed >/dev/null 2>&1 + if [ -d ${FFMPEG_PREFIX} ] + then + [ -w ${FFMPEG_PREFIX} ] || SUDO="sudo" +-- +1.8.5.1 + + +From 1f21f402336cded917f15e2831b6a04a05505c00 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Mon, 10 Feb 2014 14:10:06 +0100 +Subject: [PATCH 018/116] sq to configure - remove superfluous ffmpeg header + checks + +--- + configure.in | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/configure.in b/configure.in +index 66c6332..332efcc 100644 +--- a/configure.in ++++ b/configure.in +@@ -1741,14 +1741,8 @@ FFMPEG_LIBDIR=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --variable=libd + GNUTLS_ALL_LIBS=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --libs-only-l --silence-errors gnutls) + VORBISENC_ALL_LIBS=$(PKG_CONFIG_SYSROOT_DIR="" ${PKG_CONFIG} --static --libs-only-l --silence-errors vorbisenc) + +-# in case the headers are in a custom directory +-SAVE_CPPFLAGS="$CPPFLAGS" +-CPPFLAGS="$CPPFLAGS $FFMPEG_CFLAGS" +- +-AC_CHECK_HEADERS([libavcodec/avcodec.h libavfilter/avfilter.h libavformat/avformat.h libavutil/avutil.h libpostproc/postprocess.h libswscale/swscale.h],,[AC_MSG_ERROR("ffmpeg headers missing")]) + # TODO: make this conditional + USE_STATIC_FFMPEG=1 +-CPPFLAGS="$SAVE_CPPFLAGS" + + echo "Checking for SWIG installation" + AC_PATH_PROG(SWIG_EXE, swig, "none") +-- +1.8.5.1 + + +From c44882d37a5a38dc8197140bb81b3982253f78d4 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Wed, 5 Feb 2014 09:25:09 +0100 +Subject: [PATCH 019/116] sq to remove wrappers - add missing log include + +--- + xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +index 6528f54..06ea0ed 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" +-- +1.8.5.1 + + +From 6cd87162d90127c19a3c04ffdf119e0bfec57ed9 Mon Sep 17 00:00:00 2001 +From: wsnipex +Date: Wed, 5 Feb 2014 13:29:26 +0100 +Subject: [PATCH 020/116] sq to depends - don't enable vorbis on all platforms + +--- + tools/depends/target/ffmpeg/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index ad91f64..4814db1 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -18,13 +18,13 @@ 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 + 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) +-- +1.8.5.1 + + +From 7801dac923098fa8a5976e4b86c895e1d389ece8 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:34:39 +0200 +Subject: [PATCH 021/116] 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..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 d82e4bb..fbbb681 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 @@ struct DVDVideoUserData + #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 54c5cc8..dc2ee5d 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -166,6 +166,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + m_iLastKeyframe = 0; + m_dts = DVD_NOPTS_VALUE; + m_started = false; ++ m_decoderPts = DVD_NOPTS_VALUE; + } + + CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() +@@ -338,6 +339,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 +@@ -539,6 +548,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); + +@@ -636,6 +646,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; + +@@ -817,3 +843,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 @@ + + #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.8.5.1 + + +From 1514420983a8a5ad48c4933f487bf1d53af3a15c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 2 Sep 2012 16:05:21 +0200 +Subject: [PATCH 022/116] 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.8.5.1 + + +From 180775a53c50653c8e183317ddb91ddbd42c4a51 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 16 Feb 2013 18:25:53 +0100 +Subject: [PATCH 023/116] 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 fbbb681..5c7b943 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -156,7 +156,6 @@ struct DVDVideoUserData + #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 dc2ee5d..9a1654b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -844,6 +844,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.8.5.1 + + +From f78d2e34125744cf7b7134b81da49c4e062fc497 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 1 Jun 2013 11:21:19 +0200 +Subject: [PATCH 024/116] 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.8.5.1 + + +From c6249c3e9b6c5cc69f63ca30191e2b8c5ef35ba3 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:41:31 +0200 +Subject: [PATCH 025/116] 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.8.5.1 + + +From 3cebd9833315fe62ee238ff3812be1a3d137b389 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:43:06 +0200 +Subject: [PATCH 026/116] 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.8.5.1 + + +From d5ebfccf5d9c0271e1f4a171b01e162284d35997 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:49:05 +0200 +Subject: [PATCH 027/116] 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 05a758f..78fc80c 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -1657,7 +1657,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()) + { +@@ -2318,6 +2318,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.8.5.1 + + +From 426f161bf3c3e799fc11bf8b0bd865802e16f374 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:22:05 +0200 +Subject: [PATCH 028/116] 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 20cfe0c..ae72204 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -920,7 +920,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/icon.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.8.5.1 + + +From c64e363b4d0dc458971632eb28ab6d9428d365ec Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:24:22 +0200 +Subject: [PATCH 029/116] 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.8.5.1 + + +From d77f8266f3c2db981e752a8994b21b3afeb82271 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 20 May 2012 14:11:26 +0200 +Subject: [PATCH 030/116] 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.8.5.1 + + +From 0c0bbdc4653a0601c115ebc16b01d232cba9b08f Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 12:35:55 +0200 +Subject: [PATCH 031/116] 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.8.5.1 + + +From ee2c379e3296a8fbcf38dda8a9e393616e25fb31 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 15:02:00 +0200 +Subject: [PATCH 032/116] 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.8.5.1 + + +From 3e9dcac16d4626f855e1fa211a12c49ba54df1f8 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 12 Apr 2012 15:43:56 +0200 +Subject: [PATCH 033/116] 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.8.5.1 + + +From be53ab59a46e4fd527f17b59de4105d4fec49b79 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 20 May 2012 13:17:10 +0200 +Subject: [PATCH 034/116] 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.8.5.1 + + +From d782ebb1198f38e49248b98cecdf3b9ca1f25e62 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:54:15 +0200 +Subject: [PATCH 035/116] 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 @@ + 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.8.5.1 + + +From c5952574639f571b120fa537b9d9bed623380068 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:44:00 +0200 +Subject: [PATCH 036/116] 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 ba434d9..864cc1d 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -1019,7 +1019,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 45e8167..fa62f71 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2163,6 +2163,15 @@ +
+ + ++ ++ HAS_GLX ++ 0 ++ Default ++ ++ monitors ++ ++ ++ + + 0 + 0 +@@ -2184,6 +2193,7 @@ + -1 + + ++ + + + +@@ -2201,6 +2211,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 c8c2bbd..966d08f 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -219,13 +219,19 @@ 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") + newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue(); + else if (settingId == "videoscreen.screen") + newRes = GetResolutionForScreen(); ++ else if (settingId == "videoscreen.monitor") ++ { ++ g_Windowing.UpdateResolutions(); ++ newRes = GetResolutionForScreen(); ++ } + + string screenmode = GetStringFromResolution(newRes); + CSettings::Get().SetString("videoscreen.screenmode", screenmode); +@@ -236,7 +242,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 +@@ -622,6 +632,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; +@@ -636,6 +650,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) +@@ -663,3 +678,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 478ec47..c635edd 100644 +--- a/xbmc/settings/Settings.cpp ++++ b/xbmc/settings/Settings.cpp +@@ -407,6 +407,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"); +@@ -843,6 +844,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); +@@ -873,6 +875,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 +@@ -1025,6 +1030,7 @@ void CSettings::InitializeISettingCallbacks() + settingSet.insert("videoscreen.screen"); + settingSet.insert("videoscreen.resolution"); + settingSet.insert("videoscreen.screenmode"); ++ 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 @@ + 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.8.5.1 + + +From ac37524c99432eddfc22bba5b00df101b859066b Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:36:32 +0200 +Subject: [PATCH 037/116] 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.8.5.1 + + +From 7536bd6013d25a129aa4546b9558b977053f00ca Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 11:45:22 +0200 +Subject: [PATCH 038/116] 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.8.5.1 + + +From 0b654ffc364b14bd134ee97c85aa6c4806c96dea Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 20 Jun 2012 17:37:11 +0200 +Subject: [PATCH 039/116] 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.8.5.1 + + +From f64e957e8d2321893bca38aee0321db2d4b78bc6 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:06:25 +0200 +Subject: [PATCH 040/116] 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 @@ + 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.8.5.1 + + +From 43586a6b7814a6a7d506f7925799465b707d60dd Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 21 Jun 2012 17:26:51 +0200 +Subject: [PATCH 041/116] 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.8.5.1 + + +From dce1b8fa6ee305900e2141a0b1858b769532350c Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:00:26 +0200 +Subject: [PATCH 042/116] 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.8.5.1 + + +From de44bfff590f654ae74eab5b27e6a7d101b2f367 Mon Sep 17 00:00:00 2001 +From: FernetMenta +Date: Thu, 5 Jul 2012 12:10:09 +0200 +Subject: [PATCH 043/116] 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.8.5.1 + + +From f4b28f9b18224599a25b18791ab04bb827a61ad9 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Jun 2012 19:12:39 +0200 +Subject: [PATCH 044/116] 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.8.5.1 + + +From 8299face964f9b74a66b9c5488f9a6a787374036 Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 14:18:46 +0200 +Subject: [PATCH 045/116] 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 @@ size_t CWinEventsX11::GetQueueSize() + m_display = 0; + m_window = 0; + m_keybuf = 0; +- m_utf16buf = 0; + } + + CWinEventsX11Imp::~CWinEventsX11Imp() +@@ -181,12 +181,6 @@ size_t CWinEventsX11::GetQueueSize() + 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.8.5.1 + + +From 4d047fc3e79b8bc3d18d9b52aa5b7e99fddc630f Mon Sep 17 00:00:00 2001 +From: Joakim Plate +Date: Thu, 5 Jul 2012 14:23:54 +0200 +Subject: [PATCH 046/116] 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 @@ size_t CWinEventsX11::GetQueueSize() + 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.8.5.1 + + +From 10ce5bb454ea6243c063af4cf83763be23950ed4 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 9 Jun 2012 18:23:53 +0200 +Subject: [PATCH 047/116] 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 @@ + , { 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.8.5.1 + + +From 0874e3b6ca8cc4c9bc0367a1497619fa375754e7 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 16 Mar 2012 15:57:51 +0100 +Subject: [PATCH 048/116] 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 @@ + m_Context = NULL; + m_pixmap = None; + m_glPixmap = None; +- m_UseNvSettings = true; ++ m_UseNvSettings = false; + m_bIsATI = false; + #endif + } +-- +1.8.5.1 + + +From 2bee8486b6dc0a82348e6b4ae948698df5d3bc72 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 20 Aug 2012 09:09:09 +0200 +Subject: [PATCH 049/116] 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.8.5.1 + + +From b35897a6da5d564fc57d66f2e271fd7f4d2a53eb Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 9 Jul 2012 14:00:18 +0200 +Subject: [PATCH 050/116] 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.8.5.1 + + +From 94e7b7a69b446a7050ebbf1b28e7636162287e27 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 10 Jul 2012 11:14:12 +0200 +Subject: [PATCH 051/116] 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.8.5.1 + + +From 160944933fc75e1727a4966bb56cb834651f230e Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 12 Jul 2012 11:11:47 +0200 +Subject: [PATCH 052/116] 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.8.5.1 + + +From 04a58d91796989751190f14b1bc6f69fd360acf3 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 26 Jul 2012 09:34:28 +0200 +Subject: [PATCH 053/116] 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.8.5.1 + + +From a44036475fb49e5d106ad1ab59075edc452cb90d Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 15 Sep 2012 18:27:29 +0200 +Subject: [PATCH 054/116] 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.8.5.1 + + +From b3cf17f457fb62eafab02ddf6240e8256d361ebc Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 20 Aug 2012 16:06:39 +0200 +Subject: [PATCH 055/116] 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 3249c9f..8afd9c3 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; + +@@ -829,7 +856,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) +@@ -848,6 +884,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.8.5.1 + + +From ce7ad5dd4b16e0b304f73178642bdb7d0a8ce4e7 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 2 Oct 2012 13:02:10 +0200 +Subject: [PATCH 056/116] 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.8.5.1 + + +From d73da060a03d32fc6c41ac30e5f932105f5c2db7 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 11 Oct 2012 12:05:50 +0200 +Subject: [PATCH 057/116] 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 8d7a633..aa735f2 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1960,10 +1960,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 e21d21e..c7a5ff9 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; +@@ -598,6 +600,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 1e54c93..6497592 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.8.5.1 + + +From 52866cb18217f481be19a526de88859823b7d8f4 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 2 Nov 2012 13:20:03 +0100 +Subject: [PATCH 058/116] 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 78fc80c..f465b7e 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -1658,11 +1658,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 +@@ -1681,7 +1683,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)); + } + } + } +@@ -2167,7 +2169,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"); +@@ -2303,9 +2305,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(); + } + +@@ -2321,7 +2324,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 +@@ -3317,7 +3321,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) +@@ -3329,19 +3333,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; + +@@ -3385,7 +3393,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.8.5.1 + + +From b06a92b81ce5fced6bdb7f338fc1206629caaab5 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 23 Nov 2012 17:41:12 +0100 +Subject: [PATCH 059/116] 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 060/116] 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.8.5.1 + + +From b9258c431b13a49d0005983a0d2c1ee9d380475c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 11 Dec 2012 11:08:13 +0100 +Subject: [PATCH 061/116] 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.8.5.1 + + +From 3e43a8cc737881949492abf83b1e3f3b4702b488 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 062/116] 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.8.5.1 + + +From c6ccfc3d62d6d3e0c58dcb966318b2ea5fc46fd3 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 24 Dec 2012 16:02:42 +0100 +Subject: [PATCH 063/116] 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 7fec32f..f833ec1 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.8.5.1 + + +From 87df1131050e59d1db090287906bbd2470c9bb1b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 17 Jan 2013 16:03:22 +0100 +Subject: [PATCH 064/116] 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 @@ + , {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.8.5.1 + + +From 00a450d5beafae898a729c489823902bbda444e0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 21 Jan 2013 09:00:19 +0100 +Subject: [PATCH 065/116] 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.8.5.1 + + +From 7378fa0d965df0ee50ef9d0bc5258428c268dabc Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 23 Jan 2013 17:03:02 +0100 +Subject: [PATCH 066/116] 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.8.5.1 + + +From 1a0d2bc3b4cac3af2ef13c00903feb855be5153b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 23 Jan 2013 17:03:39 +0100 +Subject: [PATCH 067/116] 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.8.5.1 + + +From 2af3ab822266e3a0c717c90d84ece245b082e0cd Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 14 Dec 2012 14:19:15 +0100 +Subject: [PATCH 068/116] 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.8.5.1 + + +From 3136716ac10f3eabe87ca6a41d60b33ce774547f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 3 Feb 2013 08:17:16 +0100 +Subject: [PATCH 069/116] 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.8.5.1 + + +From 66e937fd2ef2b6ac21d0e269caf82edee429fe2a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 23 Mar 2013 15:13:32 +0100 +Subject: [PATCH 070/116] 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 @@ + 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.8.5.1 + + +From 2adfdfd2e3a76ef4c64454599b2446a8b5f5b129 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 24 Mar 2013 12:30:12 +0100 +Subject: [PATCH 071/116] 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.8.5.1 + + +From 18978e447fb6137af06b84a147ea5d323dc2a112 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 24 Mar 2013 16:04:48 +0100 +Subject: [PATCH 072/116] 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 @@ + 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.8.5.1 + + +From 5714a269a59291e6121ac62acfc06329ed3ae3f0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Mar 2013 15:18:53 +0100 +Subject: [PATCH 073/116] 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 7d7fb37..3daaf98 100644 +--- a/xbmc/cores/omxplayer/OMXPlayer.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayer.cpp +@@ -2572,7 +2572,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.8.5.1 + + +From a2e2db687fd12847047a33fdef1ccaf9b48a89c7 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Thu, 28 Mar 2013 20:50:59 +0100 +Subject: [PATCH 074/116] 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 ae72204..95cdf1a 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -2317,10 +2317,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.8.5.1 + + +From 7493e9af986394d670a95ad188cf173d9a55e42d Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 13 Apr 2013 08:32:06 +0200 +Subject: [PATCH 075/116] 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.8.5.1 + + +From b3407c95ab81ea27ace1c0901f64469594caf20b Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 8 May 2013 13:14:58 +0200 +Subject: [PATCH 076/116] 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.8.5.1 + + +From eea851828707e14b18424ad45d82767ab157d11d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 9 May 2013 12:07:09 +0200 +Subject: [PATCH 077/116] 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.8.5.1 + + +From c36d06e1dddafffcb2ce47e30cd872a4468f0662 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 12 May 2013 10:50:30 +0200 +Subject: [PATCH 078/116] 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 @@ + 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.8.5.1 + + +From f3e8cae0467bd451ba2acb58adf872eb495bc911 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 19 May 2013 12:55:35 +0200 +Subject: [PATCH 079/116] 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.8.5.1 + + +From 78f84eb97eb21b72c95ad2eb597c0dcc62f3cf9c Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 11 May 2013 17:12:12 +0200 +Subject: [PATCH 080/116] 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 | 6 +++ + 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, 105 insertions(+), 12 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 864cc1d..b38ea65 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -6537,7 +6537,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" +@@ -6669,7 +6669,12 @@ msgctxt "#14100" + msgid "Stop ripping CD" + msgstr "" + +-#empty strings from id 14101 to 15011 ++#: xbmc/settings/settings.xml ++msgctxt "#14101" ++msgid "Swtich off other Monitor" ++msgstr "" ++ ++#empty strings from id 14102 to 15011 + + #: xbmc/video/VideoDatabase.cpp + msgctxt "#15012" +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index fa62f71..f9361b8 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2172,6 +2172,11 @@ + + + ++ ++ HAS_GLX ++ 0 ++ false ++ + + 0 + 0 +@@ -2224,6 +2229,7 @@ + + + ++ !HAS_GLX + 1 + false + +diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp +index 966d08f..40bc3b3 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -265,6 +265,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.8.5.1 + + +From 03a46ffc79e46013339bea2734dc3a7cc21e7870 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Wed, 15 May 2013 09:14:34 +0200 +Subject: [PATCH 081/116] 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.8.5.1 + + +From dec34d1d3e51f5466ea1009fa635ba2184baca05 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 11 Jun 2013 16:20:29 +0200 +Subject: [PATCH 082/116] 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 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.8.5.1 + + +From eb9176c1780a5d311b898eb589e9909b8ce1e84a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 16 Jun 2013 13:22:58 +0200 +Subject: [PATCH 083/116] 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.8.5.1 + + +From 807d10697edd42d88c979932f08b53614ac0eb35 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 5 Jul 2013 12:14:00 +0200 +Subject: [PATCH 084/116] 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.8.5.1 + + +From 2a12b1fa396125d66ff96376710ece9b051870b6 Mon Sep 17 00:00:00 2001 +From: spiff +Date: Tue, 16 Jul 2013 14:34:04 +0200 +Subject: [PATCH 085/116] fixed: typo + +--- + language/English/strings.po | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index b38ea65..ee0c57f 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -6671,7 +6671,7 @@ msgstr "" + + #: xbmc/settings/settings.xml + msgctxt "#14101" +-msgid "Swtich off other Monitor" ++msgid "Switch off other Monitor" + msgstr "" + + #empty strings from id 14102 to 15011 +-- +1.8.5.1 + + +From 93fe4011fd1d73d61f2f8464f5ddf9387dbd9982 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 25 Jul 2013 17:18:13 +0200 +Subject: [PATCH 086/116] 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 ac5457c..4bda5af 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -30,8 +30,8 @@ + #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 + + void CEngineStats::Reset(unsigned int sampleRate) + { +-- +1.8.5.1 + + +From 7397e9e3d8c68f3a1bbc7134bf6bb23b3d3c379d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 4 Aug 2013 10:11:16 +0200 +Subject: [PATCH 087/116] 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 aa735f2..a097fc3 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1090,8 +1090,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; +@@ -2284,8 +2283,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); +@@ -2297,8 +2295,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))) + { +@@ -2320,8 +2317,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.8.5.1 + + +From df1f98e16b823d5c90bfd3d2721948abefd07599 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 9 Aug 2013 18:01:40 +0200 +Subject: [PATCH 088/116] 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.8.5.1 + + +From 2e0bf1ac4f52a3e753e668a1fb7bcf7305114ad3 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 9 Aug 2013 18:42:36 +0200 +Subject: [PATCH 089/116] 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.8.5.1 + + +From 43a7ae021c601892fb1a0a3dc28c71d5de93009a Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 10 Aug 2013 11:18:16 +0200 +Subject: [PATCH 090/116] add some missing multi media keys + +--- + system/keymaps/keyboard.xml | 3 +++ + xbmc/input/XBMC_keytable.cpp | 4 ++++ + xbmc/input/XBMC_vkeys.h | 3 +++ + 3 files changed, 10 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 b807897..30bad46 100644 +--- a/xbmc/input/XBMC_keytable.cpp ++++ b/xbmc/input/XBMC_keytable.cpp +@@ -182,6 +182,10 @@ + , { 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 ee6bb69..364b45a 100644 +--- a/xbmc/input/XBMC_vkeys.h ++++ b/xbmc/input/XBMC_vkeys.h +@@ -188,6 +188,9 @@ + XBMCVK_LAUNCH_APP2 = 0xC1, + XBMCVK_LAUNCH_FILE_BROWSER = 0xC2, + XBMCVK_LAUNCH_MEDIA_CENTER = 0xC3, ++ XBMCVK_MEDIA_RECORD = 0xC4, ++ XBMCVK_MEDIA_REWIND = 0xC5, ++ XBMCVK_MEDIA_FASTFORWARD = 0xC6, + + XBMCVK_LCONTROL = 0xD0, + XBMCVK_RCONTROL = 0xD1, +-- +1.8.5.1 + + +From 213b870f63e42747c45abe4ed9cfb73c83e5e59f Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 10 Aug 2013 15:53:45 +0200 +Subject: [PATCH 091/116] 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.8.5.1 + + +From 1241a1d0f1207109c68552627da1d5eaec4e64f9 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 3 Sep 2013 20:46:17 +0200 +Subject: [PATCH 092/116] 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.8.5.1 + + +From 22e902860ecd25f15545f027b077ca46e4ac07c7 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 29 Oct 2013 20:57:28 +0100 +Subject: [PATCH 093/116] 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 f9361b8..011b7cb 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2216,7 +2216,6 @@ + -1 + + +- + + + +diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp +index 40bc3b3..1663836 100644 +--- a/xbmc/settings/DisplaySettings.cpp ++++ b/xbmc/settings/DisplaySettings.cpp +@@ -219,19 +219,13 @@ 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") + newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue(); + else if (settingId == "videoscreen.screen") + newRes = GetResolutionForScreen(); +- else if (settingId == "videoscreen.monitor") +- { +- g_Windowing.UpdateResolutions(); +- newRes = GetResolutionForScreen(); +- } + + string screenmode = GetStringFromResolution(newRes); + CSettings::Get().SetString("videoscreen.screenmode", screenmode); +@@ -242,11 +236,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 +@@ -265,6 +255,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(); +@@ -688,9 +700,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 094/116] 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.8.5.1 + + +From 7819d5b47eac96713f82253c089418922ef0e8f8 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 09:37:13 +0100 +Subject: [PATCH 095/116] 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.8.5.1 + + +From c337eb61a637a729eb8e73a0e3ff098785fd4943 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 10:46:40 +0100 +Subject: [PATCH 096/116] 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.8.5.1 + + +From 3f13293339efbc960f3c108d59482d9731140b1d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 31 Oct 2013 11:25:19 +0100 +Subject: [PATCH 097/116] 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.8.5.1 + + +From 1ef7dc22b3a0ed4431a50a5d0d9ee116fe5944f6 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 7 Nov 2013 15:02:00 +0100 +Subject: [PATCH 098/116] 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 011b7cb..0abb304 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -2176,6 +2176,7 @@ + HAS_GLX + 0 + false ++ + + + 0 +-- +1.8.5.1 + + +From 142a31beaa7c48c773a36e6fa201adcde4c84c1d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 14 Nov 2013 09:28:24 +0100 +Subject: [PATCH 099/116] 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.8.5.1 + + +From ddce10d9590de1940634ace4b9cb92699e65083f Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Mon, 18 Nov 2013 17:44:31 +0100 +Subject: [PATCH 100/116] ActiveAE: correct time of buffered samples by + resample ratio + +--- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 2 +- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +index 4bda5af..8dcbeaf 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -101,7 +101,7 @@ float CEngineStats::GetDelay(CActiveAEStream *stream) + if (delay < 0) + delay = 0.0; + +- delay += stream->m_bufferedTime; ++ delay += stream->m_bufferedTime / stream->m_streamResampleRatio; + return delay; + } + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +index 99989b3..0287e73 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +@@ -58,6 +58,7 @@ + m_forceResampler = false; + m_remapper = NULL; + m_remapBuffer = NULL; ++ m_streamResampleRatio = 1.0; + } + + CActiveAEStream::~CActiveAEStream() +-- +1.8.5.1 + + +From ff1afecb0715bb897cb77f6b614083ac0f0f51b0 Mon Sep 17 00:00:00 2001 +From: Marcel Groothuis +Date: Thu, 5 Dec 2013 22:02:50 +0100 +Subject: [PATCH 101/116] 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 8afd9c3..cb20412 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 @@ static int64_t dvd_file_seek(void *h, int64_t pos, int whence) + 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) + { +@@ -1607,3 +1618,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.8.5.1 + + +From 98c72fa8e6db9edae5ef8a42cf2a37baea06d29d Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 14 Nov 2013 20:35:04 +0100 +Subject: [PATCH 102/116] 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 cb20412..2688358 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; +@@ -1654,7 +1667,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 +@@ -1716,3 +1729,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.8.5.1 + + +From 50e6f19c31f6ce4f192ca4b9e6bb893d53de1978 Mon Sep 17 00:00:00 2001 +From: Wolfgang Haupt +Date: Thu, 5 Dec 2013 22:11:57 +0100 +Subject: [PATCH 103/116] 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 95b8091..515cd5c 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); +@@ -1242,3 +1272,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 cf7ea3f..7857c3b 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); +@@ -126,6 +128,8 @@ class URIUtils + static bool IsBluray(const CStdString& strFile); + static bool IsAndroidApp(const CStdString& strFile); + static bool IsLibraryFolder(const CStdString& 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.8.5.1 + + +From 45ba01ccd9406ac765ae0bd545ffc00efa5ea166 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 08:43:29 +0100 +Subject: [PATCH 104/116] squash fast switch + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 2688358..750996b 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -1739,7 +1739,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.8.5.1 + + +From 3aa629e7c45247b7d5e8377c357e424f3da03a28 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 22 Dec 2013 14:52:29 +0100 +Subject: [PATCH 105/116] 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 5c0d66d..4edd98c 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -318,6 +318,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) +@@ -452,7 +458,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 332efcc..c5af908 100644 +--- a/configure.in ++++ b/configure.in +@@ -821,6 +821,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 +@@ -2531,6 +2544,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" +@@ -2609,6 +2626,7 @@ AC_SUBST(USE_ANDROID) + AC_SUBST(GTEST_CONFIGURED) + AC_SUBST(USE_DOXYGEN) + AC_SUBST(USE_PVR_ADDONS) ++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 addeb16..2edbf5a 100644 +--- a/xbmc/DllPaths_generated.h.in ++++ b/xbmc/DllPaths_generated.h.in +@@ -95,4 +95,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.8.5.1 + + +From d79e199bbb8a1c3a041bc645662e29d87fa574c1 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Thu, 19 Dec 2013 15:36:11 +0100 +Subject: [PATCH 106/116] vaapi: option to enable sw filters + +--- + language/English/strings.po | 15 ++- + system/settings/settings.xml | 7 + + 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 | 150 +++++++++++++++++++++ + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 37 ++++- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 32 ++--- + 9 files changed, 282 insertions(+), 43 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index ee0c57f..adaf2f6 100755 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -6074,7 +6074,13 @@ msgctxt "#13452" + msgid "Enable this option to use hardware acceleration for VC-1 based codecs. If disabled the CPU will be used instead. Especially VC-1 Interlaced fails hard on Intel hardware." + msgstr "" + +-#empty strings from id 13453 to 13499 ++#. Description of setting #13453 'Use SW Filter for VAAPI' ++#: system/settings/settings.xml ++msgctxt "#13453" ++msgid "Use SW Filter for VAAPI" ++msgstr "" ++ ++#empty strings from id 13454 to 13499 + + #: system/settings/settings.xml + msgctxt "#13500" +@@ -14877,7 +14883,12 @@ msgctxt "#36429" + msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality" + msgstr "" + +-#empty strings from id 36430 to 36499 ++#: system/settings/settings.xml ++msgctxt "#36430" ++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 36431 to 36499 + #end reservation + + #: system/settings/settings.xml +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index 0abb304..7553396 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -513,6 +513,13 @@ + true + + 3 ++ ++ ++ HAVE_LIBVA ++ ++ true ++ ++ 3 + false + + +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 46841a1..6930a13 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +@@ -454,6 +454,7 @@ struct EFormatMap { + , { 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 9a1654b..0fefe80 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -37,6 +37,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))) +@@ -167,6 +168,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + m_dts = DVD_NOPTS_VALUE; + m_started = false; + m_decoderPts = DVD_NOPTS_VALUE; ++ m_interlace = false; + } + + CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() +@@ -371,7 +373,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) +@@ -445,10 +447,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) +@@ -503,19 +505,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; +@@ -532,7 +575,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); +@@ -616,6 +659,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; +@@ -639,7 +683,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); +@@ -670,7 +718,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)) +@@ -690,6 +738,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, +@@ -848,10 +897,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 47c84e6..cce40d2 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 @@ static CDisplayPtr GetGlobalDisplay() + 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) +@@ -390,6 +404,8 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + if (!EnsureContext(avctx)) + return false; + ++ CheckUseFilter(); ++ + m_hwaccel->display = m_display->get(); + + avctx->hwaccel_context = m_hwaccel; +@@ -474,7 +490,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; + } +@@ -552,4 +596,110 @@ 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; ++ } ++ VASurfaceStatus surf_status; ++ VAImage image; ++ VASurfaceID surface = m_surfaces_free.front()->m_id; ++ VAStatus status = 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 9744c80..e4793ae 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +@@ -21,15 +21,19 @@ + + #include "system_gl.h" + +-#include "libavcodec/avcodec.h" ++ + #include "DVDVideoCodecFFmpeg.h" +-#include + #include + #include + #include + #include + #include ++#include "linux/sse4/DllLibSSE4.h" + ++extern "C" { ++#include "libavcodec/vaapi.h" ++#include "libavcodec/avcodec.h" ++} + + namespace VAAPI { + +@@ -101,11 +105,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 +138,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); + void RelBuffer(AVCodecContext *avctx, AVFrame *pic); +@@ -132,14 +159,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.8.5.1 + + +From dd93a39160f397a87b20618fba659114ba2df4b9 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 3 Jan 2014 20:50:46 +0100 +Subject: [PATCH 107/116] 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.8.5.1 + + +From 417117033c75e30abbf6f446f1fc85e6865aa36e Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Fri, 24 Jan 2014 18:29:33 +0100 +Subject: [PATCH 108/116] 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 0fefe80..04ebdfe 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -454,7 +454,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) +@@ -576,7 +581,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.8.5.1 + + +From 4172280fad53b2481df1c96fb881f80bf3d19d26 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 10:05:26 +0100 +Subject: [PATCH 109/116] 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 04ebdfe..9fcb356 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -478,6 +478,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; +@@ -698,8 +706,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.8.5.1 + + +From 207f3c33e295df283221b20697a947a85e798453 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 28 Jan 2014 17:24:58 +0100 +Subject: [PATCH 110/116] 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 9fcb356..54508b7 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -709,7 +709,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.8.5.1 + + +From df1ffe150ca1c4a8244ee69eb5f3a757d5e1ebfd Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Mon, 27 Jan 2014 19:49:03 +0100 +Subject: [PATCH 111/116] 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, 14 insertions(+), 9 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 54508b7..b8f619d 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -162,7 +162,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + 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; +@@ -208,10 +208,15 @@ 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; + } + } ++ #ifdef AV_CODEC_ID_HEVC ++ else if (hints.codec == AV_CODEC_ID_HEVC) ++ m_isSWCodec = true; ++ #endif ++ + + if(pCodec == NULL) + pCodec = avcodec_find_decoder(hints.codec); +@@ -237,12 +242,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 (CSettings::Get().GetBool("videoplayer.useframemtdec")) +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 c7a5ff9..f642b97 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; +@@ -597,7 +597,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 6497592..d44f38a 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.8.5.1 + + +From 28030355bb2d9fae78fb860191f5069c697adcdb Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 18 Jan 2014 13:02:21 +0100 +Subject: [PATCH 112/116] vdpau: map/unmap surfaces on every cycle, requested + by AMD + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 156 ++++++++++++++----------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 2 +- + 2 files changed, 86 insertions(+), 72 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index a097fc3..5b53054 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -3042,7 +3042,7 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() + m_config.useInteropYuv = false; + m_bufferPool.numOutputSurfaces = NUM_RENDER_PICS; + EnsureBufferPool(); +- GLMapSurfaces(); ++ GLMapSurface(false, procPic.outputSurface); + retPic->sourceIdx = procPic.outputSurface; + retPic->texture[0] = m_bufferPool.glOutputSurfaceMap[procPic.outputSurface].texture[0]; + retPic->texWidth = m_config.outWidth; +@@ -3055,7 +3055,7 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() + else + { + m_config.useInteropYuv = true; +- GLMapSurfaces(); ++ GLMapSurface(true, procPic.videoSurface); + retPic->sourceIdx = procPic.videoSurface; + for (unsigned int i=0; i<4; ++i) + retPic->texture[i] = m_bufferPool.glVideoSurfaceMap[procPic.videoSurface].texture[i]; +@@ -3170,6 +3170,9 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) + CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); + return; + } ++#ifdef GL_NV_vdpau_interop ++ glVDPAUUnmapSurfacesNV(1, &(it->second.glVdpauSurface)); ++#endif + VdpVideoSurface surf = it->second.sourceVuv; + m_config.videoSurfaces->ClearRender(surf); + } +@@ -3182,6 +3185,9 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) + CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); + return; + } ++#ifdef GL_NV_vdpau_interop ++ glVDPAUUnmapSurfacesNV(1, &(it->second.glVdpauSurface)); ++#endif + VdpOutputSurface outSurf = it->second.sourceRgb; + m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, &outSurf, sizeof(outSurf)); + } +@@ -3391,95 +3397,103 @@ bool COutput::GLInit() + return true; + } + +-void COutput::GLMapSurfaces() ++void COutput::GLMapSurface(bool yuv, uint32_t source) + { + #ifdef GL_NV_vdpau_interop + +- if (m_config.useInteropYuv) ++ if (yuv) + { +- VdpauBufferPool::GLVideoSurface glSurface; +- VdpVideoSurface surf; +- if (m_config.videoSurfaces->Size() != m_bufferPool.glVideoSurfaceMap.size()) ++ std::map::iterator it; ++ it = m_bufferPool.glVideoSurfaceMap.find(source); ++ if (it == m_bufferPool.glVideoSurfaceMap.end()) + { +- for (unsigned int i = 0; i < m_config.videoSurfaces->Size(); i++) +- { +- surf = m_config.videoSurfaces->GetAtIndex(i); ++ VdpauBufferPool::GLVideoSurface glSurface; ++ VdpVideoSurface surf = source; + +- if (surf == VDP_INVALID_HANDLE) +- continue; ++ if (surf == VDP_INVALID_HANDLE) ++ return; + +- if (m_bufferPool.glVideoSurfaceMap.find(surf) == m_bufferPool.glVideoSurfaceMap.end()) +- { +- glSurface.sourceVuv = surf; +- while (glGetError() != GL_NO_ERROR) ; +- glGenTextures(4, glSurface.texture); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); +- m_vdpError = true; +- } +- glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast(surf), ++ glSurface.sourceVuv = surf; ++ while (glGetError() != GL_NO_ERROR) ; ++ glGenTextures(4, glSurface.texture); ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); ++ m_vdpError = true; ++ } ++ glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast(surf), + GL_TEXTURE_2D, 4, glSurface.texture); + +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error register video surface"); +- m_vdpError = true; +- } +- glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); +- m_vdpError = true; +- } +- glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); +- m_vdpError = true; +- } +- m_bufferPool.glVideoSurfaceMap[surf] = glSurface; +- if (m_vdpError) +- return; +- CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); +- } ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error register video surface"); ++ m_vdpError = true; + } ++ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); ++ m_vdpError = true; ++ } ++ m_bufferPool.glVideoSurfaceMap[surf] = glSurface; ++ ++ CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); + } ++ ++ while (glGetError() != GL_NO_ERROR) ; ++ glVDPAUMapSurfacesNV(1, &m_bufferPool.glVideoSurfaceMap[source].glVdpauSurface); ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); ++ m_vdpError = true; ++ } ++ ++ if (m_vdpError) ++ return; + } + else + { +- if (m_bufferPool.glOutputSurfaceMap.size() != m_bufferPool.numOutputSurfaces) ++ std::map::iterator it; ++ it = m_bufferPool.glOutputSurfaceMap.find(source); ++ if (it == m_bufferPool.glOutputSurfaceMap.end()) + { +- VdpauBufferPool::GLVideoSurface glSurface; +- for (unsigned int i = m_bufferPool.glOutputSurfaceMap.size(); i(m_bufferPool.outputSurfaces[i]), ++ if (m_bufferPool.outputSurfaces[idx] == source) ++ break; ++ } ++ ++ VdpauBufferPool::GLVideoSurface glSurface; ++ glSurface.sourceRgb = m_bufferPool.outputSurfaces[idx]; ++ glGenTextures(1, glSurface.texture); ++ glSurface.glVdpauSurface = glVDPAURegisterOutputSurfaceNV(reinterpret_cast(m_bufferPool.outputSurfaces[idx]), + GL_TEXTURE_2D, 1, glSurface.texture); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error register output surface"); +- m_vdpError = true; +- } +- glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); +- m_vdpError = true; +- } +- glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); +- if (glGetError() != GL_NO_ERROR) +- { +- CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); +- m_vdpError = true; +- } +- m_bufferPool.glOutputSurfaceMap[m_bufferPool.outputSurfaces[i]] = glSurface; +- if (m_vdpError) +- return; ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error register output surface"); ++ m_vdpError = true; + } ++ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); ++ m_vdpError = true; ++ } ++ m_bufferPool.glOutputSurfaceMap[source] = glSurface; + CLog::Log(LOGNOTICE, "VDPAU::COutput registered output surfaces"); + } ++ ++ while (glGetError() != GL_NO_ERROR) ; ++ glVDPAUMapSurfacesNV(1, &m_bufferPool.glOutputSurfaceMap[source].glVdpauSurface); ++ if (glGetError() != GL_NO_ERROR) ++ { ++ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); ++ m_vdpError = true; ++ } ++ ++ if (m_vdpError) ++ return; + } + #endif + } +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index e60fc65..32d6cdb 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -445,7 +445,7 @@ class COutput : private CThread + void PreCleanup(); + void InitMixer(); + bool GLInit(); +- void GLMapSurfaces(); ++ void GLMapSurface(bool yuv, uint32_t source); + void GLUnmapSurfaces(); + bool CheckStatus(VdpStatus vdp_st, int line); + CEvent m_outMsgEvent; +-- +1.8.5.1 + + +From 113a716924272f886a3552a29091bdcfc89b12f2 Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Sun, 9 Feb 2014 15:50:53 +0100 +Subject: [PATCH 113/116] VAAPI: remove unneeded VASurfaceStatus + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index cce40d2..d7c9863 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -620,10 +620,9 @@ void CDecoder::CheckUseFilter() + m_use_filter = false; + return; + } +- VASurfaceStatus surf_status; + VAImage image; + VASurfaceID surface = m_surfaces_free.front()->m_id; +- VAStatus status = status = vaDeriveImage(m_display->get(), surface, &image); ++ VAStatus status = vaDeriveImage(m_display->get(), surface, &image); + m_use_filter = true; + if (status != VA_STATUS_SUCCESS) + { +-- +1.8.5.1 + + +From fe5f6deb1a989894a3e8299078dbd34acc408ebf Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Mon, 10 Feb 2014 23:04:55 +0100 +Subject: [PATCH 114/116] Settings: Readd toggle after merge (would not be + visible at all) + +--- + system/settings/settings.xml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/system/settings/settings.xml b/system/settings/settings.xml +index 7553396..1b29179 100644 +--- a/system/settings/settings.xml ++++ b/system/settings/settings.xml +@@ -513,6 +513,8 @@ + true + + 3 ++ false ++ + + + HAVE_LIBVA +-- +1.8.5.1 + + +From 1aab16e8f288a5df5a46af10ae7897ade12a5fed Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 11 Feb 2014 18:15:06 +0100 +Subject: [PATCH 115/116] 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.8.5.1 + + +From 59f249c9de1a3fad45e65683e6fc6c3772fa84c3 Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Wed, 12 Feb 2014 08:05:15 +0100 +Subject: [PATCH 116/116] VAAPI: Only use swfilter when width <= 1920 and + height <= 1088 + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index d7c9863..51f9bed 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -404,7 +404,10 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + if (!EnsureContext(avctx)) + return false; + +- CheckUseFilter(); ++ if (avctx->width <= 1920 && avctx->height <= 1088) ++ CheckUseFilter(); ++ else ++ m_use_filter = false; + + m_hwaccel->display = m_display->get(); + +-- +1.8.5.1 + 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 7512fd23d6..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-995.01-fernetmenta-fixes-b3b79dd.patch +++ /dev/null @@ -1,9795 +0,0 @@ -From 7156cdb19f3529caa0c8af213cc90fdef0a91db8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 01/97] 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 d82e4bb..fbbb681 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 @@ public: - 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 @@ 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 54c5cc8..dc2ee5d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -166,6 +166,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() - m_iLastKeyframe = 0; - m_dts = DVD_NOPTS_VALUE; - m_started = false; -+ m_decoderPts = DVD_NOPTS_VALUE; - } - - CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() -@@ -338,6 +339,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 -@@ -539,6 +548,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); - -@@ -636,6 +646,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; - -@@ -817,3 +843,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 @@ 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; } - }; -@@ -67,6 +68,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; }; -@@ -122,4 +125,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.rc1 - -From 9bfa855ce02a290f17f886a2ebf940fb459d9eca Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 02/97] 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.rc1 - -From 32e5002c04d55bf4c11d9a54927c4092c0a150c1 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 18:25:53 +0100 -Subject: [PATCH 03/97] 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 fbbb681..5c7b943 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 @@ 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 dc2ee5d..9a1654b 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -844,6 +844,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 @@ 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.rc1 - -From 730e4abeb47a9f6c11ca053bd29316541ae47530 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 1 Jun 2013 11:21:19 +0200 -Subject: [PATCH 04/97] 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.rc1 - -From 0638de168ecb47845e6a94b4d3656173ab856866 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 05/97] 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.rc1 - -From 9471b26b54b94b6e286732cf6e9be7989a050ce6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 06/97] 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.rc1 - -From 6f3551332f122caddc614ea72b9eb3e770a57fd0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 07/97] 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 05a758f..78fc80c 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1657,7 +1657,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()) - { -@@ -2318,6 +2318,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.rc1 - -From ca9bd0b91df408993a919d9299ff39f8d79049e5 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 08/97] 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 20cfe0c..ae72204 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -920,7 +920,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/icon.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.rc1 - -From 7f06ecbbed71d8945f986901aaf6af0520ece4c5 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 09/97] 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 @@ 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.rc1 - -From 9ead568a8397f1db30ce7c81def966e388e275f2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 10/97] 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.rc1 - -From 81791c1d75743cea03b03fff9066dacbdaa8d673 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 11/97] 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.rc1 - -From 3731182a75891b20b1a3a422b1684cc9153c048c Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 12/97] 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.rc1 - -From 9eeeb447ade3232184bcc4a8c7e90eb82dc3f90b Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 13/97] 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.rc1 - -From 617818ec90976dd5e417af33e0f99d86878d6174 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 14/97] 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.rc1 - -From af1c9b1105de4a23bba2d5a7ffeace733f957250 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 15/97] 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.rc1 - -From 855f533e933af78fbcec3b83ea7583c360c7f0ea Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 16/97] 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 ba434d9..864cc1d 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -1019,7 +1019,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 7f07b3d..16f75f0 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2163,6 +2163,15 @@ -
- - -+ -+ HAS_GLX -+ 0 -+ Default -+ -+ monitors -+ -+ -+ - - 0 - 0 -@@ -2184,6 +2193,7 @@ - -1 - - -+ - - - -@@ -2201,6 +2211,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 c8c2bbd..966d08f 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -219,13 +219,19 @@ 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") - newRes = (RESOLUTION)((CSettingInt*)setting)->GetValue(); - else if (settingId == "videoscreen.screen") - newRes = GetResolutionForScreen(); -+ else if (settingId == "videoscreen.monitor") -+ { -+ g_Windowing.UpdateResolutions(); -+ newRes = GetResolutionForScreen(); -+ } - - string screenmode = GetStringFromResolution(newRes); - CSettings::Get().SetString("videoscreen.screenmode", screenmode); -@@ -236,7 +242,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 -@@ -622,6 +632,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; -@@ -636,6 +650,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) -@@ -663,3 +678,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 ec5b32b..0db1827 100644 ---- a/xbmc/settings/Settings.cpp -+++ b/xbmc/settings/Settings.cpp -@@ -407,6 +407,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"); -@@ -840,6 +841,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); -@@ -870,6 +872,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 -@@ -1019,6 +1024,7 @@ void CSettings::InitializeISettingCallbacks() - settingSet.insert("videoscreen.screen"); - settingSet.insert("videoscreen.resolution"); - settingSet.insert("videoscreen.screenmode"); -+ 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.rc1 - -From 77eb40bd1161f51c94242518157c329f81d7d83c Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 17/97] 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.rc1 - -From b54ee3a9b549f41a90fa7385a39ad186511d67aa Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 18/97] 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.rc1 - -From 5a2d859edac02dcc49c7d591d6eabb71fba239f6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 19/97] 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.rc1 - -From d14bc23d8fc80228b5f7bb8655d528d65f2ac754 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 20/97] 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.rc1 - -From 2c1e17fd699480e6ae5f9f6b3f1a25203ffdaf6d Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 21/97] 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.rc1 - -From c3465fb3ae45d82f60392cee24f1d65e089d0e41 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 22/97] 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.rc1 - -From b73b1167150d48fc934fceab290593892769a702 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 23/97] 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.rc1 - -From 0b655192e990ebd129b7e91e2ccd2e3df56aae99 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 24/97] 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.rc1 - -From a59bc0d2736c1339ef00dce58127b1b3347ce9f0 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 25/97] 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.rc1 - -From 1bae5a3f2f3ff14eee59d5669414cdec1a114158 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 26/97] 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.rc1 - -From 8986cf2319d822d0fa8cf94849cd48480695272a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 27/97] 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.rc1 - -From f515ce00855d4a24aefbc600f140a4e9a2ac9358 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 28/97] 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.rc1 - -From 809eae4c4168ab2bccefa12204377dc6a1d46fc7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 29/97] 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.rc1 - -From 0fa28c48d7289c17cf5cf92ce6b5cd203ff92293 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 30/97] 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.rc1 - -From d3843d9b464bc396d4ad10fd02a5bf2b6c26c76f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 31/97] 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.rc1 - -From 268b4baf9fa0146ba7c1c7c7f4e4c9dbd4377a86 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 32/97] 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.rc1 - -From 7a55c33359e35cc1c208abe9893e1ccee96e779f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 33/97] 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.rc1 - -From 0d5a6d7560fd3597dc5b8e8b2d568cc28ab48d91 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 34/97] 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.rc1 - -From a6e274d74a76800107731c3d9803311386b2f4cc Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 35/97] 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 3249c9f..8afd9c3 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; - -@@ -829,7 +856,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) -@@ -848,6 +884,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 @@ 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); -@@ -153,5 +154,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.rc1 - -From afa31948b564b108bef691ec6a4a62f78f91aa84 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 36/97] 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.rc1 - -From ddd20c4bdddb6541bc5eaa858f9dec61ae222da7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 37/97] 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 8d7a633..aa735f2 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1960,10 +1960,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 41d45e2..be06adf 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; -@@ -598,6 +600,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 1e54c93..6497592 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.rc1 - -From 15c53ef3e0c0228c2140967fb2043166eed17b7a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 38/97] 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 78fc80c..f465b7e 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1658,11 +1658,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 -@@ -1681,7 +1683,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)); - } - } - } -@@ -2167,7 +2169,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"); -@@ -2303,9 +2305,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(); - } - -@@ -2321,7 +2324,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 -@@ -3317,7 +3321,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) -@@ -3329,19 +3333,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; - -@@ -3385,7 +3393,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.rc1 - -From 7e7272e6958547bd4dcc3762a4f21ea94ac678b8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 39/97] 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/97] 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.rc1 - -From e5d273f06d9eb17cf5271126165c06a3838cdbf5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 41/97] 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.rc1 - -From 1c3d9766d13abb26b434d4abb023f8c8ebc39971 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/97] 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.rc1 - -From bb26b8d9b4bdc4c7b63048bfbc7432a72644a1e4 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 43/97] 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 7fec32f..f833ec1 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.rc1 - -From 85cdd5c054f008a0d743abac5dfa5d1900288cd7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 44/97] 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.rc1 - -From 7d5271b572b87086d046811c700f1193a9fb08d0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 45/97] 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.rc1 - -From 754927fdf86fc41d18841678795c348194ace7cf Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 46/97] 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.rc1 - -From 84ea46e9abf2b8b2f535146ff2fda75707560809 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 47/97] 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.rc1 - -From ed3d1a826e892a714f4af7989caa673a560aa576 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 14 Dec 2012 14:19:15 +0100 -Subject: [PATCH 48/97] 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.rc1 - -From 1797d4c1564c345016f4414b52de48d138f57a14 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 3 Feb 2013 08:17:16 +0100 -Subject: [PATCH 49/97] 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.rc1 - -From af1185e339e982e0a3e66aa027c375139466e8c7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 23 Mar 2013 15:13:32 +0100 -Subject: [PATCH 50/97] 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.rc1 - -From 8fe39badae0588dd51648fe20b2cbb536a43a4d9 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Mar 2013 12:30:12 +0100 -Subject: [PATCH 51/97] 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.rc1 - -From 0933abe20df9c6296cb9037097befbc4f282f263 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Mar 2013 16:04:48 +0100 -Subject: [PATCH 52/97] 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.rc1 - -From 0bbd7293472c24fd52f2cb2056e88d97b20f5e78 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Mar 2013 15:18:53 +0100 -Subject: [PATCH 53/97] 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 7d7fb37..3daaf98 100644 ---- a/xbmc/cores/omxplayer/OMXPlayer.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp -@@ -2572,7 +2572,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.rc1 - -From a84bf4d1bc8129d3e347b3362c08d2065729389c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Mar 2013 20:50:59 +0100 -Subject: [PATCH 54/97] 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 ae72204..95cdf1a 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2317,10 +2317,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.rc1 - -From 4c812159523d87e23e91e3852511a770e63239f3 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 13 Apr 2013 08:32:06 +0200 -Subject: [PATCH 55/97] 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.rc1 - -From 27fb7d233e47a75ec92e558f532f9096dd6207d5 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 8 May 2013 13:14:58 +0200 -Subject: [PATCH 56/97] 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.rc1 - -From a8c2192656c6e4deb54b1da5316d9f62b4a417ee Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 9 May 2013 12:07:09 +0200 -Subject: [PATCH 57/97] 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.rc1 - -From 03e16fee76a63455dd8416e1f5eb73a8a0a657c6 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 12 May 2013 10:50:30 +0200 -Subject: [PATCH 58/97] 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.rc1 - -From 930a405d31088b176659c761f1cf57e0d980f1c5 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 19 May 2013 12:55:35 +0200 -Subject: [PATCH 59/97] 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.rc1 - -From 4921fa4d0f840a67f179e580d774e6fac780140e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 11 May 2013 17:12:12 +0200 -Subject: [PATCH 60/97] 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 | 6 +++ - 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, 105 insertions(+), 12 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 864cc1d..b38ea65 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -6537,7 +6537,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" -@@ -6669,7 +6669,12 @@ msgctxt "#14100" - msgid "Stop ripping CD" - msgstr "" - --#empty strings from id 14101 to 15011 -+#: xbmc/settings/settings.xml -+msgctxt "#14101" -+msgid "Swtich off other Monitor" -+msgstr "" -+ -+#empty strings from id 14102 to 15011 - - #: xbmc/video/VideoDatabase.cpp - msgctxt "#15012" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 16f75f0..e4638fa 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2172,6 +2172,11 @@ - - - -+ -+ HAS_GLX -+ 0 -+ false -+ - - 0 - 0 -@@ -2224,6 +2229,7 @@ - - - -+ !HAS_GLX - 1 - false - -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index 966d08f..40bc3b3 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -265,6 +265,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.rc1 - -From c5e2c847aca518bf5ebd5e3f29cdf4dfaaba5710 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Wed, 15 May 2013 09:14:34 +0200 -Subject: [PATCH 61/97] 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.rc1 - -From 6be3109d5a8b374898fa1359b480e4939f286566 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 11 Jun 2013 16:20:29 +0200 -Subject: [PATCH 62/97] 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.rc1 - -From 7d335d88c6f7ef37c42cecd96991350ee3a98d97 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 16 Jun 2013 13:22:58 +0200 -Subject: [PATCH 63/97] 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.rc1 - -From e8b08c5fd17393f1e6a2330c22a17d8906bbf58a Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 5 Jul 2013 12:14:00 +0200 -Subject: [PATCH 64/97] 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.rc1 - -From 661fb9c4f23fb3c5e47e17deadcc7b1a6ef7516b Mon Sep 17 00:00:00 2001 -From: spiff -Date: Tue, 16 Jul 2013 14:34:04 +0200 -Subject: [PATCH 65/97] fixed: typo - ---- - language/English/strings.po | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index b38ea65..ee0c57f 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -6671,7 +6671,7 @@ msgstr "" - - #: xbmc/settings/settings.xml - msgctxt "#14101" --msgid "Swtich off other Monitor" -+msgid "Switch off other Monitor" - msgstr "" - - #empty strings from id 14102 to 15011 --- -1.9.rc1 - -From d88be50eb4d9e529231309a735d39f1f4d3a2e46 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 25 Jul 2013 17:18:13 +0200 -Subject: [PATCH 66/97] 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 ac5457c..4bda5af 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 - - void CEngineStats::Reset(unsigned int sampleRate) - { --- -1.9.rc1 - -From b7fb85c4476373c6fafa41781bb920805874db8c Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 4 Aug 2013 10:11:16 +0200 -Subject: [PATCH 67/97] 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 aa735f2..a097fc3 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1090,8 +1090,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; -@@ -2284,8 +2283,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); -@@ -2297,8 +2295,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))) - { -@@ -2320,8 +2317,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.rc1 - -From f3a6c92e4bb404fc8cec019841d45f3b7ff9c1b2 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 9 Aug 2013 18:01:40 +0200 -Subject: [PATCH 68/97] 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.rc1 - -From d11d9ccb464e49039e728d6cf5338c2faf2098d2 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 9 Aug 2013 18:42:36 +0200 -Subject: [PATCH 69/97] 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.rc1 - -From fb2c75db380e1f7ba6164f1de14e491f66d816a3 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 10 Aug 2013 11:18:16 +0200 -Subject: [PATCH 70/97] add some missing multi media keys - ---- - system/keymaps/keyboard.xml | 3 +++ - xbmc/input/XBMC_keytable.cpp | 4 ++++ - xbmc/input/XBMC_vkeys.h | 3 +++ - 3 files changed, 10 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 b807897..30bad46 100644 ---- a/xbmc/input/XBMC_keytable.cpp -+++ b/xbmc/input/XBMC_keytable.cpp -@@ -182,6 +182,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 ee6bb69..364b45a 100644 ---- a/xbmc/input/XBMC_vkeys.h -+++ b/xbmc/input/XBMC_vkeys.h -@@ -188,6 +188,9 @@ typedef enum { - XBMCVK_LAUNCH_APP2 = 0xC1, - XBMCVK_LAUNCH_FILE_BROWSER = 0xC2, - XBMCVK_LAUNCH_MEDIA_CENTER = 0xC3, -+ XBMCVK_MEDIA_RECORD = 0xC4, -+ XBMCVK_MEDIA_REWIND = 0xC5, -+ XBMCVK_MEDIA_FASTFORWARD = 0xC6, - - XBMCVK_LCONTROL = 0xD0, - XBMCVK_RCONTROL = 0xD1, --- -1.9.rc1 - -From f1fa7d061305f18751e94bd9c99a42f6dbf935aa Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 10 Aug 2013 15:53:45 +0200 -Subject: [PATCH 71/97] 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.rc1 - -From 4c79c073e98876cc76f1373ff5f3a6e41122ac4f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 3 Sep 2013 20:46:17 +0200 -Subject: [PATCH 72/97] 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.rc1 - -From 9f8be5a6e7dbc5df1ee2b0207a729128d329c9fd Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 29 Oct 2013 20:57:59 +0100 -Subject: [PATCH 74/97] 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.rc1 - -From 11900ebb90578edd05333d6a44ac8a53d83b207a Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 09:37:13 +0100 -Subject: [PATCH 75/97] 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.rc1 - -From fcb4c4d844921b050f6d302acae749f30fcf9502 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 10:46:40 +0100 -Subject: [PATCH 76/97] 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.rc1 - -From 0c1ca6f12cec2f1d8b28cce03fd1d2cedc75040a Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 31 Oct 2013 11:25:19 +0100 -Subject: [PATCH 77/97] 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.rc1 - -From c56d30bfe7c0c689b0117590723c21f01eaaf2f7 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 7 Nov 2013 15:02:00 +0100 -Subject: [PATCH 78/97] 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 4d6df66..46293d3 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2176,6 +2176,7 @@ - HAS_GLX - 0 - false -+ - - - 0 --- -1.9.rc1 - -From e56cd935a1fd0674c3796f40200ead3f3d5fd120 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 14 Nov 2013 09:28:24 +0100 -Subject: [PATCH 79/97] 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.rc1 - -From f916d50da6401cf09995acb6a45bb01654f2f78e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Mon, 18 Nov 2013 17:44:31 +0100 -Subject: [PATCH 80/97] ActiveAE: correct time of buffered samples by resample - ratio - ---- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 2 +- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 4bda5af..8dcbeaf 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -101,7 +101,7 @@ float CEngineStats::GetDelay(CActiveAEStream *stream) - if (delay < 0) - delay = 0.0; - -- delay += stream->m_bufferedTime; -+ delay += stream->m_bufferedTime / stream->m_streamResampleRatio; - return delay; - } - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -index 99989b3..0287e73 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp -@@ -58,6 +58,7 @@ CActiveAEStream::CActiveAEStream(AEAudioFormat *format) - m_forceResampler = false; - m_remapper = NULL; - m_remapBuffer = NULL; -+ m_streamResampleRatio = 1.0; - } - - CActiveAEStream::~CActiveAEStream() --- -1.9.rc1 - -From 0e8a7fab69680fd0a537af2b42efb4712aca5508 Mon Sep 17 00:00:00 2001 -From: Marcel Groothuis -Date: Thu, 5 Dec 2013 22:02:50 +0100 -Subject: [PATCH 81/97] 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 8afd9c3..cb20412 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) - { -@@ -1607,3 +1618,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 @@ public: - CDVDDemuxFFmpeg(); - virtual ~CDVDDemuxFFmpeg(); - -- bool Open(CDVDInputStream* pInput); -+ bool Open(CDVDInputStream* pInput, bool streaminfo = true); - void Dispose(); - void Reset(); - void Flush(); -@@ -127,6 +127,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); -@@ -157,5 +159,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.rc1 - -From e63a89a138270675e3ee18f78bb77e42cf506d6c Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 14 Nov 2013 20:35:04 +0100 -Subject: [PATCH 82/97] 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 cb20412..2688358 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; -@@ -1654,7 +1667,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 -@@ -1716,3 +1729,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 @@ 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.rc1 - -From 94a5dabaef0a03dceb0da7fa8817d6f702c89d26 Mon Sep 17 00:00:00 2001 -From: Wolfgang Haupt -Date: Thu, 5 Dec 2013 22:11:57 +0100 -Subject: [PATCH 83/97] 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 95b8091..515cd5c 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); -@@ -1242,3 +1272,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 cf7ea3f..7857c3b 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); -@@ -126,6 +128,8 @@ public: - static bool IsBluray(const CStdString& strFile); - static bool IsAndroidApp(const CStdString& strFile); - static bool IsLibraryFolder(const CStdString& 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.rc1 - -From 4d567e4ee2b631d591d712e12568ab40f8400f46 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 3 Jan 2014 20:50:46 +0100 -Subject: [PATCH 87/97] 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.rc1 - -From 916c1f8d9d2e9d1fb25ee1f3f90f4c225293fa9e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 18 Jan 2014 13:02:21 +0100 -Subject: [PATCH 93/97] vdpau: map/unmap surfaces on every cycle, requested by - AMD - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 156 ++++++++++++++----------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 2 +- - 2 files changed, 86 insertions(+), 72 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index a097fc3..5b53054 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -3042,7 +3042,7 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() - m_config.useInteropYuv = false; - m_bufferPool.numOutputSurfaces = NUM_RENDER_PICS; - EnsureBufferPool(); -- GLMapSurfaces(); -+ GLMapSurface(false, procPic.outputSurface); - retPic->sourceIdx = procPic.outputSurface; - retPic->texture[0] = m_bufferPool.glOutputSurfaceMap[procPic.outputSurface].texture[0]; - retPic->texWidth = m_config.outWidth; -@@ -3055,7 +3055,7 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() - else - { - m_config.useInteropYuv = true; -- GLMapSurfaces(); -+ GLMapSurface(true, procPic.videoSurface); - retPic->sourceIdx = procPic.videoSurface; - for (unsigned int i=0; i<4; ++i) - retPic->texture[i] = m_bufferPool.glVideoSurfaceMap[procPic.videoSurface].texture[i]; -@@ -3170,6 +3170,9 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) - CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); - return; - } -+#ifdef GL_NV_vdpau_interop -+ glVDPAUUnmapSurfacesNV(1, &(it->second.glVdpauSurface)); -+#endif - VdpVideoSurface surf = it->second.sourceVuv; - m_config.videoSurfaces->ClearRender(surf); - } -@@ -3182,6 +3185,9 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) - CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); - return; - } -+#ifdef GL_NV_vdpau_interop -+ glVDPAUUnmapSurfacesNV(1, &(it->second.glVdpauSurface)); -+#endif - VdpOutputSurface outSurf = it->second.sourceRgb; - m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, &outSurf, sizeof(outSurf)); - } -@@ -3391,95 +3397,103 @@ bool COutput::GLInit() - return true; - } - --void COutput::GLMapSurfaces() -+void COutput::GLMapSurface(bool yuv, uint32_t source) - { - #ifdef GL_NV_vdpau_interop - -- if (m_config.useInteropYuv) -+ if (yuv) - { -- VdpauBufferPool::GLVideoSurface glSurface; -- VdpVideoSurface surf; -- if (m_config.videoSurfaces->Size() != m_bufferPool.glVideoSurfaceMap.size()) -+ std::map::iterator it; -+ it = m_bufferPool.glVideoSurfaceMap.find(source); -+ if (it == m_bufferPool.glVideoSurfaceMap.end()) - { -- for (unsigned int i = 0; i < m_config.videoSurfaces->Size(); i++) -- { -- surf = m_config.videoSurfaces->GetAtIndex(i); -+ VdpauBufferPool::GLVideoSurface glSurface; -+ VdpVideoSurface surf = source; - -- if (surf == VDP_INVALID_HANDLE) -- continue; -+ if (surf == VDP_INVALID_HANDLE) -+ return; - -- if (m_bufferPool.glVideoSurfaceMap.find(surf) == m_bufferPool.glVideoSurfaceMap.end()) -- { -- glSurface.sourceVuv = surf; -- while (glGetError() != GL_NO_ERROR) ; -- glGenTextures(4, glSurface.texture); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); -- m_vdpError = true; -- } -- glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast(surf), -+ glSurface.sourceVuv = surf; -+ while (glGetError() != GL_NO_ERROR) ; -+ glGenTextures(4, glSurface.texture); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); -+ m_vdpError = true; -+ } -+ glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast(surf), - GL_TEXTURE_2D, 4, glSurface.texture); - -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error register video surface"); -- m_vdpError = true; -- } -- glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -- m_vdpError = true; -- } -- glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -- m_vdpError = true; -- } -- m_bufferPool.glVideoSurfaceMap[surf] = glSurface; -- if (m_vdpError) -- return; -- CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); -- } -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error register video surface"); -+ m_vdpError = true; - } -+ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -+ m_vdpError = true; -+ } -+ m_bufferPool.glVideoSurfaceMap[surf] = glSurface; -+ -+ CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); - } -+ -+ while (glGetError() != GL_NO_ERROR) ; -+ glVDPAUMapSurfacesNV(1, &m_bufferPool.glVideoSurfaceMap[source].glVdpauSurface); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -+ m_vdpError = true; -+ } -+ -+ if (m_vdpError) -+ return; - } - else - { -- if (m_bufferPool.glOutputSurfaceMap.size() != m_bufferPool.numOutputSurfaces) -+ std::map::iterator it; -+ it = m_bufferPool.glOutputSurfaceMap.find(source); -+ if (it == m_bufferPool.glOutputSurfaceMap.end()) - { -- VdpauBufferPool::GLVideoSurface glSurface; -- for (unsigned int i = m_bufferPool.glOutputSurfaceMap.size(); i(m_bufferPool.outputSurfaces[i]), -+ if (m_bufferPool.outputSurfaces[idx] == source) -+ break; -+ } -+ -+ VdpauBufferPool::GLVideoSurface glSurface; -+ glSurface.sourceRgb = m_bufferPool.outputSurfaces[idx]; -+ glGenTextures(1, glSurface.texture); -+ glSurface.glVdpauSurface = glVDPAURegisterOutputSurfaceNV(reinterpret_cast(m_bufferPool.outputSurfaces[idx]), - GL_TEXTURE_2D, 1, glSurface.texture); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error register output surface"); -- m_vdpError = true; -- } -- glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -- m_vdpError = true; -- } -- glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); -- if (glGetError() != GL_NO_ERROR) -- { -- CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -- m_vdpError = true; -- } -- m_bufferPool.glOutputSurfaceMap[m_bufferPool.outputSurfaces[i]] = glSurface; -- if (m_vdpError) -- return; -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error register output surface"); -+ m_vdpError = true; - } -+ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -+ m_vdpError = true; -+ } -+ m_bufferPool.glOutputSurfaceMap[source] = glSurface; - CLog::Log(LOGNOTICE, "VDPAU::COutput registered output surfaces"); - } -+ -+ while (glGetError() != GL_NO_ERROR) ; -+ glVDPAUMapSurfacesNV(1, &m_bufferPool.glOutputSurfaceMap[source].glVdpauSurface); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -+ m_vdpError = true; -+ } -+ -+ if (m_vdpError) -+ return; - } - #endif - } -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index e60fc65..32d6cdb 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -445,7 +445,7 @@ protected: - void PreCleanup(); - void InitMixer(); - bool GLInit(); -- void GLMapSurfaces(); -+ void GLMapSurface(bool yuv, uint32_t source); - void GLUnmapSurfaces(); - bool CheckStatus(VdpStatus vdp_st, int line); - CEvent m_outMsgEvent; --- -1.9.rc1 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-999-010-linux-static-ffmpeg.patch b/packages/mediacenter/xbmc/patches/xbmc-999-010-linux-static-ffmpeg.patch deleted file mode 100644 index 20921e32b4..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-999-010-linux-static-ffmpeg.patch +++ /dev/null @@ -1,67 +0,0 @@ -diff -Naur xbmc-13.alpha-65ad3ae/configure.in xbmc-13.alpha-65ad3ae.patch/configure.in ---- xbmc-13.alpha-65ad3ae/configure.in 2014-02-03 16:36:26.000000000 +0100 -+++ xbmc-13.alpha-65ad3ae.patch/configure.in 2014-02-05 02:38:47.233903531 +0100 -@@ -622,24 +622,22 @@ - use_sdl=no - use_x11=no - build_shared_lib=yes -- ;; -+ ;; - i*86*-linux-gnu*|i*86*-*-linux-uclibc*) - ARCH="i486-linux" - if test "$use_cpu" = "no" -a "$cross_compiling" = "yes"; then - use_arch="x86" - use_cpu="i686" -- else -- target_platform=target_linux - fi -+ use_static_ffmpeg=yes - ;; - x86_64-*-linux-gnu*|x86_64-*-linux-uclibc*) - ARCH="x86_64-linux" - if test "$use_cpu" = "no" -a "$cross_compiling" = "yes"; then - use_arch="x86_64" - use_cpu="x86_64" -- else -- target_platform=target_linux - fi -+ use_static_ffmpeg=yes - ;; - i386-*-freebsd*) - ARCH="x86-freebsd" -@@ -695,6 +693,7 @@ - use_sdl=no - use_x11=no - use_wayland=no -+ use_static_ffmpeg=yes - ;; - arm*-*linux-android*) - target_platform=target_android -@@ -872,9 +871,8 @@ - fi - fi - fi --if test "$target_platform" = "target_linux"; then -+if test "$use_static_ffmpeg" = "yes"; then - USE_STATIC_FFMPEG=1 -- use_static_ffmpeg=yes - 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 -@@ -2795,7 +2793,6 @@ - LDFLAGS="$(echo "$LDFLAGS" | sed "s/-Wl,-Bsymbolic-functions//g")" \ - ./configure \ - --extra-cflags="$PASSED_CFLAGS $FFMPEG_EXTRACFLAGS" \ -- --disable-static \ - `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`\ -@@ -2819,7 +2816,7 @@ - --disable-ffserver \ - --disable-ffmpeg \ - --disable-crystalhd \ -- `if test "$use_static_ffmpeg" = "yes"; then echo --enable-static; else echo --enable-shared; fi` \ -+ `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 \ diff --git a/packages/mediacenter/xbmc/patches/xbmc-999.991-ffmpeg-prefix.patch b/packages/mediacenter/xbmc/patches/xbmc-999.991-ffmpeg-prefix.patch deleted file mode 100644 index a8ad588bfe..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-999.991-ffmpeg-prefix.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur xbmc-13.alpha-fc8358e/configure.in xbmc-13.alpha-fc8358e.patch/configure.in ---- xbmc-13.alpha-fc8358e/configure.in 2014-02-02 04:41:09.000000000 +0100 -+++ xbmc-13.alpha-fc8358e.patch/configure.in 2014-02-03 15:47:44.591058586 +0100 -@@ -2794,6 +2794,7 @@ - CXXFLAGS="" \ - LDFLAGS="$(echo "$LDFLAGS" | sed "s/-Wl,-Bsymbolic-functions//g")" \ - ./configure \ -+ --prefix="${prefix}" \ - --extra-cflags="$PASSED_CFLAGS $FFMPEG_EXTRACFLAGS" \ - --disable-static \ - `if test "$use_debug" = "no"; then echo --disable-debug; fi` \