diff --git a/packages/mediacenter/package.mk b/packages/mediacenter/package.mk
index b8607f6ee5..993d79630d 100644
--- a/packages/mediacenter/package.mk
+++ b/packages/mediacenter/package.mk
@@ -36,7 +36,7 @@ for i in $SKINS; do
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET $MEDIACENTER-theme-$i"
done
-if [ "$MEDIACENTER" = "xbmc" -o "$MEDIACENTER" = "xbmc-master" ]; then
+if [ "$MEDIACENTER" = "xbmc" ]; then
# some python stuff needed for various addons
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET Imaging"
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET simplejson"
diff --git a/packages/mediacenter/service.openelec.settings/package.mk b/packages/mediacenter/service.openelec.settings/package.mk
index 9972298023..097cc51294 100644
--- a/packages/mediacenter/service.openelec.settings/package.mk
+++ b/packages/mediacenter/service.openelec.settings/package.mk
@@ -17,11 +17,7 @@
################################################################################
PKG_NAME="service.openelec.settings"
-if [ "$XBMC" = "master" ]; then
- PKG_VERSION="0.4.0"
-else
- PKG_VERSION="0.3.17"
-fi
+PKG_VERSION="0.3.17"
PKG_REV="1"
PKG_ARCH="any"
PKG_LICENSE="prop."
diff --git a/packages/mediacenter/xbmc-master-theme-Confluence/package.mk b/packages/mediacenter/xbmc-master-theme-Confluence/package.mk
deleted file mode 100644
index dbd52978a0..0000000000
--- a/packages/mediacenter/xbmc-master-theme-Confluence/package.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-PKG_NAME="xbmc-master-theme-Confluence"
-PKG_VERSION="14-603c7fa"
-PKG_REV="1"
-PKG_ARCH="any"
-PKG_LICENSE="GPL"
-PKG_SITE="http://www.xbmc.org"
-PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz"
-PKG_DEPENDS_TARGET="toolchain xbmc-master"
-PKG_PRIORITY="optional"
-PKG_SECTION="mediacenter"
-PKG_SHORTDESC="xbmc-theme-Confluence: XBMC Mediacenter default theme"
-PKG_LONGDESC="XBMC Media Center (which was formerly named Xbox Media Center) is a free and open source cross-platform media player and home entertainment system software with a 10-foot user interface designed for the living-room TV. Its graphical user interface allows the user to easily manage video, photos, podcasts, and music from a computer, optical disk, local network, and the internet using a remote control."
-
-PKG_IS_ADDON="no"
-PKG_AUTORECONF="no"
-
-make_target() {
- TexturePacker -input media/ \
- -output Textures.xbt \
- -dupecheck \
- -use_none
-}
-
-makeinstall_target() {
- mkdir -p $INSTALL/usr/share/xbmc/addons/skin.confluence
- cp -R */ $INSTALL/usr/share/xbmc/addons/skin.confluence
- cp *.txt $INSTALL/usr/share/xbmc/addons/skin.confluence
- cp *.xml $INSTALL/usr/share/xbmc/addons/skin.confluence
- cp *.png $INSTALL/usr/share/xbmc/addons/skin.confluence
- rm -rf $INSTALL/usr/share/xbmc/addons/skin.confluence/media
-
- mkdir -p $INSTALL/usr/share/xbmc/addons/skin.confluence/media
- cp Textures.xbt $INSTALL/usr/share/xbmc/addons/skin.confluence/media
-}
diff --git a/packages/mediacenter/xbmc-master-theme-Confluence/patches/xbmc-master-theme-Confluence-001-add_oe_settings_to_homescreen.patch b/packages/mediacenter/xbmc-master-theme-Confluence/patches/xbmc-master-theme-Confluence-001-add_oe_settings_to_homescreen.patch
deleted file mode 100644
index 79a3addf5a..0000000000
--- a/packages/mediacenter/xbmc-master-theme-Confluence/patches/xbmc-master-theme-Confluence-001-add_oe_settings_to_homescreen.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/720p/IncludesHomeMenuItems.xml 2012-07-22 21:56:07.000000000 +0400
-+++ b/720p/IncludesHomeMenuItems.xml 2012-09-13 23:34:16.975470148 +0400
-@@ -189,6 +189,11 @@
-
- ActivateWindow(Settings)
-
-+
-+ ButtonHomeSubCommonValues
-+
-+ RunAddon(service.openelec.settings)
-+
-
- ButtonHomeSubCommonValues
-
diff --git a/packages/mediacenter/xbmc-master/config/advancedsettings.xml b/packages/mediacenter/xbmc-master/config/advancedsettings.xml
deleted file mode 100644
index c54111aaa3..0000000000
--- a/packages/mediacenter/xbmc-master/config/advancedsettings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
- false
- cputemp
- gputemp
-
-
- 30
-
-
- 4.0
-
-
diff --git a/packages/mediacenter/xbmc-master/config/appliance.xml b/packages/mediacenter/xbmc-master/config/appliance.xml
deleted file mode 100644
index 98fd49f28c..0000000000
--- a/packages/mediacenter/xbmc-master/config/appliance.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
- true
-
-
-
-
-
-
-
- true
-
-
-
-
-
-
-
- true
-
-
-
-
-
-
-
-
-
- /usr/bin/setwakeup.sh
-
-
-
-
-
-
diff --git a/packages/mediacenter/xbmc-master/config/os.openelec.tv/addon.xml b/packages/mediacenter/xbmc-master/config/os.openelec.tv/addon.xml
deleted file mode 100644
index 206659f9da..0000000000
--- a/packages/mediacenter/xbmc-master/config/os.openelec.tv/addon.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/packages/mediacenter/xbmc-master/config/repository.openelec.tv/addon.xml b/packages/mediacenter/xbmc-master/config/repository.openelec.tv/addon.xml
deleted file mode 100644
index 7b21ca7f12..0000000000
--- a/packages/mediacenter/xbmc-master/config/repository.openelec.tv/addon.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- @ADDON_URL@/addons.xml
- @ADDON_URL@/addons.xml.md5
- @ADDON_URL@
-
-
- Install Add-ons, Plugins, Games and Programs from [COLOR FF757677]Open[/COLOR][COLOR FF8ABEE2]ELEC[/COLOR]
- Download and install Add-ons, Plugins, Games and Programs from the Official [COLOR FF757677]Open[/COLOR][COLOR FF8ABEE2]ELEC[/COLOR] addon repository.[CR] By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR] All addons on this repository have under gone basic testing, if you find a broken or not working addon please report it to [COLOR FF757677]Open[/COLOR][COLOR FF8ABEE2]ELEC[/COLOR] so we can take any action needed.
- all
-
-
diff --git a/packages/mediacenter/xbmc-master/config/repository.openelec.tv/icon.png b/packages/mediacenter/xbmc-master/config/repository.openelec.tv/icon.png
deleted file mode 100644
index 1147ae1d37..0000000000
Binary files a/packages/mediacenter/xbmc-master/config/repository.openelec.tv/icon.png and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/debug.d/xbmc.conf b/packages/mediacenter/xbmc-master/debug.d/xbmc.conf
deleted file mode 100644
index 7c6c362ac3..0000000000
--- a/packages/mediacenter/xbmc-master/debug.d/xbmc.conf
+++ /dev/null
@@ -1 +0,0 @@
-XBMC_DEBUG="--debug"
diff --git a/packages/mediacenter/xbmc-master/fonts/DejaVuSans.ttf b/packages/mediacenter/xbmc-master/fonts/DejaVuSans.ttf
deleted file mode 100644
index 84ca1d7503..0000000000
Binary files a/packages/mediacenter/xbmc-master/fonts/DejaVuSans.ttf and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/fonts/Trebuchet MS Bold.ttf b/packages/mediacenter/xbmc-master/fonts/Trebuchet MS Bold.ttf
deleted file mode 100644
index 867f56d776..0000000000
Binary files a/packages/mediacenter/xbmc-master/fonts/Trebuchet MS Bold.ttf and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/fonts/YanoneKaffeesatz-Bold.ttf b/packages/mediacenter/xbmc-master/fonts/YanoneKaffeesatz-Bold.ttf
deleted file mode 100644
index e9964b0809..0000000000
Binary files a/packages/mediacenter/xbmc-master/fonts/YanoneKaffeesatz-Bold.ttf and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/package.mk b/packages/mediacenter/xbmc-master/package.mk
deleted file mode 100644
index 79b8af7fc4..0000000000
--- a/packages/mediacenter/xbmc-master/package.mk
+++ /dev/null
@@ -1,525 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-PKG_NAME="xbmc-master"
-PKG_VERSION="14-603c7fa"
-PKG_REV="1"
-PKG_ARCH="any"
-PKG_LICENSE="GPL"
-PKG_SITE="http://www.xbmc.org"
-PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz"
-PKG_DEPENDS_TARGET="toolchain boost Python zlib bzip2 systemd pciutils lzo pcre swig:host libass enca curl rtmpdump fontconfig fribidi gnutls tinyxml libjpeg-turbo libpng tiff freetype jasper libogg libcdio libmodplug faad2 flac libmpeg2 taglib libxml2 libxslt yajl sqlite libvorbis ffmpeg xbmc-master:host"
-PKG_DEPENDS_HOST="toolchain"
-PKG_PRIORITY="optional"
-PKG_SECTION="mediacenter"
-PKG_SHORTDESC="xbmc: XBMC Mediacenter"
-PKG_LONGDESC="XBMC Media Center (which was formerly named Xbox Media Center) is a free and open source cross-platform media player and home entertainment system software with a 10-foot user interface designed for the living-room TV. Its graphical user interface allows the user to easily manage video, photos, podcasts, and music from a computer, optical disk, local network, and the internet using a remote control."
-
-PKG_IS_ADDON="no"
-PKG_AUTORECONF="no"
-
-# for dbus support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET dbus"
-
-# needed for hosttools (Texturepacker)
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET lzo:host SDL:host SDL_image:host"
-
-if [ "$DISPLAYSERVER" = "x11" ]; then
-# for libX11 support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libX11 libXext"
-# for libXrandr support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libXrandr"
- XBMC_XORG="--enable-x11 --enable-xrandr"
-else
- XBMC_XORG="--disable-x11 --disable-xrandr"
-fi
-
-if [ "$OPENGL" = "Mesa" ]; then
-# for OpenGL (GLX) support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET Mesa glu glew"
- XBMC_OPENGL="--enable-gl"
-else
- XBMC_OPENGL="--disable-gl"
-fi
-
-if [ "$OPENGLES_SUPPORT" = yes ]; then
-# for OpenGL-ES support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET $OPENGLES"
- XBMC_OPENGLES="--enable-gles"
-else
- XBMC_OPENGLES="--disable-gles"
-fi
-
-if [ "$SDL_SUPPORT" = yes ]; then
-# for SDL support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET SDL SDL_image"
- XBMC_SDL="--enable-sdl"
-else
- XBMC_SDL="--disable-sdl"
-fi
-
-if [ "$ALSA_SUPPORT" = yes ]; then
-# for ALSA support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET alsa-lib"
- XBMC_ALSA="--enable-alsa"
-else
- XBMC_ALSA="--disable-alsa"
-fi
-
-if [ "$PULSEAUDIO_SUPPORT" = yes ]; then
-# for PulseAudio support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET pulseaudio"
- XBMC_PULSEAUDIO="--enable-pulse"
-else
- XBMC_PULSEAUDIO="--disable-pulse"
-fi
-
-if [ "$ESPEAK_SUPPORT" = yes ]; then
-# for espeak support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET espeak"
-fi
-
-if [ "$CEC_SUPPORT" = yes ]; then
-# for CEC support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libcec"
- XBMC_CEC="--enable-libcec"
-else
- XBMC_CEC="--disable-libcec"
-fi
-
-if [ "$XBMC_SCR_RSXS" = yes ]; then
-# for RSXS Screensaver support
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libXt libXmu"
- XBMC_RSXS="--enable-rsxs"
-# fix build of RSXS Screensaver support if not using libiconv
- export jm_cv_func_gettimeofday_clobber=no
-else
- XBMC_RSXS="--disable-rsxs"
-fi
-
-if [ "$XBMC_VIS_PROJECTM" = yes ]; then
-# for ProjectM Visualisation support
- XBMC_PROJECTM="--enable-projectm"
-else
- XBMC_PROJECTM="--disable-projectm"
-fi
-
-if [ "$XBMC_VIS_GOOM" = yes ]; then
-# for GOOM Visualisation support
- XBMC_GOOM="--enable-goom"
-else
- XBMC_GOOM="--disable-goom"
-fi
-
-if [ "$XBMC_VIS_WAVEFORM" = yes ]; then
-# for Waveform Visualisation support
- XBMC_WAVEFORM="--enable-waveform"
-else
- XBMC_WAVEFORM="--disable-waveform"
-fi
-
-if [ "$XBMC_VIS_SPECTRUM" = yes ]; then
-# for Spectrum Visualisation support
- XBMC_SPECTRUM="--enable-spectrum"
-else
- XBMC_SPECTRUM="--disable-spectrum"
-fi
-
-if [ "$XBMC_VIS_FISHBMC" = yes ]; then
-# for FishBMC Visualisation support
- XBMC_FISHBMC="--enable-fishbmc"
-else
- XBMC_FISHBMC="--disable-fishbmc"
-fi
-
-if [ "$JOYSTICK_SUPPORT" = yes ]; then
-# for Joystick support
- XBMC_JOYSTICK="--enable-joystick"
-else
- XBMC_JOYSTICK="--disable-joystick"
-fi
-
-if [ "$OPTICAL_DRIVE_SUPPORT" = yes ]; then
- XBMC_OPTICAL="--enable-optical-drive"
-else
- XBMC_OPTICAL="--disable-optical-drive"
-fi
-
-if [ "$NONFREE_SUPPORT" = yes ]; then
-# for non-free support
- XBMC_NONFREE="--enable-non-free"
-else
- XBMC_NONFREE="--disable-non-free"
-fi
-
-if [ "$DVDCSS_SUPPORT" = yes ]; then
- XBMC_DVDCSS="--enable-dvdcss"
-else
- XBMC_DVDCSS="--disable-dvdcss"
-fi
-
-if [ "$FAAC_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET faac"
-fi
-
-if [ "$ENCODER_LAME" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET lame"
- XBMC_LAMEENC="--enable-libmp3lame"
-else
- XBMC_LAMEENC="--disable-libmp3lame"
-fi
-
-if [ "$BLURAY_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libbluray"
- XBMC_BLURAY="--enable-libbluray"
-else
- XBMC_BLURAY="--disable-libbluray"
-fi
-
-if [ "$AVAHI_DAEMON" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET avahi nss-mdns"
- XBMC_AVAHI="--enable-avahi"
-else
- XBMC_AVAHI="--disable-avahi"
-fi
-
-if [ "$MYSQL_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET mysql"
- XBMC_MYSQL="--enable-mysql"
-else
- XBMC_MYSQL="--disable-mysql"
-fi
-
-if [ "$AIRPLAY_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libplist"
- XBMC_AIRPLAY="--enable-airplay"
-else
- XBMC_AIRPLAY="--disable-airplay"
-fi
-
-if [ "$AIRTUNES_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libshairplay"
- XBMC_AIRTUNES="--enable-airtunes"
-else
- XBMC_AIRTUNES="--disable-airtunes"
-fi
-
-if [ "$NFS_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libnfs"
- XBMC_NFS="--enable-nfs"
-else
- XBMC_NFS="--disable-nfs"
-fi
-
-if [ "$AFP_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET afpfs-ng"
- XBMC_AFP="--enable-afpclient"
-else
- XBMC_AFP="--disable-afpclient"
-fi
-
-if [ "$SAMBA_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET samba"
- XBMC_SAMBA="--enable-samba"
-else
- XBMC_SAMBA="--disable-samba"
-fi
-
-if [ "$WEBSERVER" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libmicrohttpd"
- XBMC_WEBSERVER="--enable-webserver"
-else
- XBMC_WEBSERVER="--disable-webserver"
-fi
-
-if [ "$UPNP_SUPPORT" = yes ]; then
- XBMC_UPNP="--enable-upnp"
-else
- XBMC_UPNP="--disable-upnp"
-fi
-
-if [ "$SSHLIB_SUPPORT" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libssh"
- XBMC_SSH="--enable-ssh"
-else
- XBMC_SSH="--disable-ssh"
-fi
-
-if [ ! "$XBMCPLAYER_DRIVER" = default ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET $XBMCPLAYER_DRIVER"
-
- if [ "$XBMCPLAYER_DRIVER" = bcm2835-driver ]; then
- XBMC_OPENMAX="--enable-openmax"
- XBMC_PLAYER="--enable-player=omxplayer"
- XBMC_CODEC="--with-platform=raspberry-pi"
- BCM2835_INCLUDES="-I$SYSROOT_PREFIX/usr/include/interface/vcos/pthreads/ \
- -I$SYSROOT_PREFIX/usr/include/interface/vmcs_host/linux"
- XBMC_CFLAGS="$XBMC_CFLAGS $BCM2835_INCLUDES"
- XBMC_CXXFLAGS="$XBMC_CXXFLAGS $BCM2835_INCLUDES"
- elif [ "$XBMCPLAYER_DRIVER" = libfslvpuwrap ]; then
- XBMC_CODEC="--enable-codec=imxvpu"
- else
- XBMC_OPENMAX="--disable-openmax"
- fi
-fi
-
-if [ "$VDPAU" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libvdpau"
- XBMC_VDPAU="--enable-vdpau"
-else
- XBMC_VDPAU="--disable-vdpau"
-fi
-
-if [ "$VAAPI" = yes ]; then
-# configure GPU drivers and dependencies:
- get_graphicdrivers
-
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET $LIBVA"
- XBMC_VAAPI="--enable-vaapi"
-else
- XBMC_VAAPI="--disable-vaapi"
-fi
-
-if [ "$CRYSTALHD" = yes ]; then
- PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET crystalhd"
- XBMC_CRYSTALHD="--enable-crystalhd"
-else
- XBMC_CRYSTALHD="--disable-crystalhd"
-fi
-
-export CXX_FOR_BUILD="$HOST_CXX"
-export CC_FOR_BUILD="$HOST_CC"
-export CXXFLAGS_FOR_BUILD="$HOST_CXXFLAGS"
-export CFLAGS_FOR_BUILD="$HOST_CFLAGS"
-export LDFLAGS_FOR_BUILD="$HOST_LDFLAGS"
-
-export PYTHON_VERSION="2.7"
-export PYTHON_CPPFLAGS="-I$SYSROOT_PREFIX/usr/include/python$PYTHON_VERSION"
-export PYTHON_LDFLAGS="-L$SYSROOT_PREFIX/usr/lib/python$PYTHON_VERSION -lpython$PYTHON_VERSION"
-export PYTHON_SITE_PKG="$SYSROOT_PREFIX/usr/lib/python$PYTHON_VERSION/site-packages"
-export ac_python_version="$PYTHON_VERSION"
-
-PKG_CONFIGURE_OPTS_TARGET="gl_cv_func_gettimeofday_clobber=no \
- ac_cv_lib_bluetooth_hci_devid=no \
- --disable-debug \
- --disable-optimizations \
- $XBMC_OPENGL \
- $XBMC_OPENGLES \
- $XBMC_SDL \
- $XBMC_OPENMAX \
- $XBMC_VDPAU \
- $XBMC_VAAPI \
- $XBMC_CRYSTALHD \
- --disable-vtbdecoder \
- --disable-tegra \
- --disable-profiling \
- $XBMC_JOYSTICK \
- $XBMC_CEC \
- --enable-udev \
- --disable-libusb \
- $XBMC_GOOM \
- $XBMC_RSXS \
- $XBMC_PROJECTM \
- $XBMC_WAVEFORM \
- $XBMC_SPECTRUM \
- $XBMC_FISHBMC \
- $XBMC_XORG \
- --disable-ccache \
- $XBMC_ALSA \
- $XBMC_PULSEAUDIO \
- --enable-rtmp \
- $XBMC_SAMBA \
- $XBMC_NFS \
- $XBMC_AFP \
- --enable-libvorbisenc \
- --disable-libcap \
- $XBMC_LAMEENC \
- $XBMC_DVDCSS \
- --disable-mid \
- --disable-hal \
- $XBMC_AVAHI \
- $XBMC_UPNP \
- $XBMC_MYSQL \
- $XBMC_SSH \
- $XBMC_AIRPLAY \
- $XBMC_AIRTUNES \
- $XBMC_NONFREE \
- --disable-asap-codec \
- $XBMC_WEBSERVER \
- $XBMC_OPTICAL \
- $XBMC_BLURAY \
- --enable-texturepacker \
- $XBMC_CODEC \
- $XBMC_PLAYER"
-
-pre_configure_host() {
-# xbmc fails to build in subdirs
- cd $ROOT/$PKG_BUILD
- rm -rf .$HOST_NAME
-}
-
-make_host() {
- make -C tools/depends/native/JsonSchemaBuilder
-}
-
-makeinstall_host() {
- cp -PR tools/depends/native/JsonSchemaBuilder/native/JsonSchemaBuilder $ROOT/$TOOLCHAIN/bin
-}
-
-pre_build_target() {
-# adding fake Makefile for stripped skin
- mkdir -p $PKG_BUILD/addons/skin.confluence/media
- touch $PKG_BUILD/addons/skin.confluence/media/Makefile.in
-
-# autoreconf
- BOOTSTRAP_STANDALONE=1 make -C $PKG_BUILD -f bootstrap.mk
-}
-
-pre_configure_target() {
-# xbmc fails to build in subdirs
- cd $ROOT/$PKG_BUILD
- rm -rf .$TARGET_NAME
-
-# xbmc fails to build with LTO optimization if build without GOLD support
- [ ! "$GOLD_SUPPORT" = "yes" ] && strip_lto
-
-# Todo: XBMC segfaults on exit when building with LTO support
- strip_lto
-
- export CFLAGS="$CFLAGS $XBMC_CFLAGS"
- export CXXFLAGS="$CXXFLAGS $XBMC_CXXFLAGS"
- export LIBS="$LIBS -lz"
-
- export JSON_BUILDER=$ROOT/$TOOLCHAIN/bin/JsonSchemaBuilder
-}
-
-make_target() {
-# setup skin dir from default skin
- SKIN_DIR="skin.`tolower $SKIN_DEFAULT`"
-
-# setup default skin inside the sources
- sed -i -e "s|skin.confluence|$SKIN_DIR|g" $ROOT/$PKG_BUILD/xbmc/settings/Settings.h
-
- make externals
- make xbmc.bin
-
- if [ "$DISPLAYSERVER" = "x11" ]; then
- make xbmc-xrandr
- fi
-
- make -C tools/TexturePacker
- cp -PR tools/TexturePacker/TexturePacker $ROOT/$TOOLCHAIN/bin
-}
-
-post_makeinstall_target() {
- rm -rf $INSTALL/usr/bin/xbmc
- rm -rf $INSTALL/usr/bin/xbmc-standalone
- rm -rf $INSTALL/usr/lib/xbmc/*.cmake
-
- mkdir -p $INSTALL/usr/lib/xbmc
- cp $PKG_DIR/scripts/xbmc-config $INSTALL/usr/lib/xbmc
- cp $PKG_DIR/scripts/xbmc-hacks $INSTALL/usr/lib/xbmc
- cp $PKG_DIR/scripts/xbmc-sources $INSTALL/usr/lib/xbmc
-
- mkdir -p $INSTALL/usr/lib/openelec
- cp $PKG_DIR/scripts/systemd-addon-wrapper $INSTALL/usr/lib/openelec
-
- mkdir -p $INSTALL/usr/bin
- cp $PKG_DIR/scripts/cputemp $INSTALL/usr/bin
- ln -sf cputemp $INSTALL/usr/bin/gputemp
- cp $PKG_DIR/scripts/setwakeup.sh $INSTALL/usr/bin
- cp tools/EventClients/Clients/XBMC\ Send/xbmc-send.py $INSTALL/usr/bin/xbmc-send
-
- if [ ! "$DISPLAYSERVER" = "x11" ]; then
- rm -rf $INSTALL/usr/lib/xbmc/xbmc-xrandr
- fi
-
- if [ ! "$XBMC_SCR_RSXS" = yes ]; then
- rm -rf $INSTALL/usr/share/xbmc/addons/screensaver.rsxs.*
- fi
-
- if [ ! "$XBMC_VIS_PROJECTM" = yes ]; then
- rm -rf $INSTALL/usr/share/xbmc/addons/visualization.projectm
- fi
-
- rm -rf $INSTALL/usr/share/applications
- rm -rf $INSTALL/usr/share/icons
- rm -rf $INSTALL/usr/share/xbmc/addons/repository.pvr-*
- rm -rf $INSTALL/usr/share/xbmc/addons/script.module.pysqlite
- rm -rf $INSTALL/usr/share/xbmc/addons/script.module.simplejson
- rm -rf $INSTALL/usr/share/xbmc/addons/visualization.dxspectrum
- rm -rf $INSTALL/usr/share/xbmc/addons/visualization.itunes
- rm -rf $INSTALL/usr/share/xbmc/addons/visualization.milkdrop
- rm -rf $INSTALL/usr/share/xbmc/addons/service.xbmc.versioncheck
- rm -rf $INSTALL/usr/share/xsessions
-
- mkdir -p $INSTALL/usr/share/xbmc/addons
- cp -R $PKG_DIR/config/os.openelec.tv $INSTALL/usr/share/xbmc/addons
- $SED "s|@OS_VERSION@|$OS_VERSION|g" -i $INSTALL/usr/share/xbmc/addons/os.openelec.tv/addon.xml
- cp -R $PKG_DIR/config/repository.openelec.tv $INSTALL/usr/share/xbmc/addons
- $SED "s|@ADDON_URL@|$ADDON_URL|g" -i $INSTALL/usr/share/xbmc/addons/repository.openelec.tv/addon.xml
-
- mkdir -p $INSTALL/usr/lib/python"$PYTHON_VERSION"/site-packages/xbmc
- cp -R tools/EventClients/lib/python/* $INSTALL/usr/lib/python"$PYTHON_VERSION"/site-packages/xbmc
-
-# install project specific configs
- mkdir -p $INSTALL/usr/share/xbmc/config
- if [ -f $PROJECT_DIR/$PROJECT/xbmc/guisettings.xml ]; then
- cp -R $PROJECT_DIR/$PROJECT/xbmc/guisettings.xml $INSTALL/usr/share/xbmc/config
- fi
-
- if [ -f $PROJECT_DIR/$PROJECT/xbmc/sources.xml ]; then
- cp -R $PROJECT_DIR/$PROJECT/xbmc/sources.xml $INSTALL/usr/share/xbmc/config
- fi
-
- mkdir -p $INSTALL/usr/share/xbmc/system/
- if [ -f $PROJECT_DIR/$PROJECT/xbmc/advancedsettings.xml ]; then
- cp $PROJECT_DIR/$PROJECT/xbmc/advancedsettings.xml $INSTALL/usr/share/xbmc/system/
- else
- cp $PKG_DIR/config/advancedsettings.xml $INSTALL/usr/share/xbmc/system/
- fi
-
- mkdir -p $INSTALL/usr/share/xbmc/system/settings
- if [ -f $PROJECT_DIR/$PROJECT/xbmc/appliance.xml ]; then
- cp $PROJECT_DIR/$PROJECT/xbmc/appliance.xml $INSTALL/usr/share/xbmc/system/settings
- else
- cp $PKG_DIR/config/appliance.xml $INSTALL/usr/share/xbmc/system/settings
- fi
-
- if [ "$XBMC_EXTRA_FONTS" = yes ]; then
- mkdir -p $INSTALL/usr/share/xbmc/media/Fonts
- cp $PKG_DIR/fonts/*.ttf $INSTALL/usr/share/xbmc/media/Fonts
- fi
-}
-
-post_install() {
-# link default.target to xbmc.target
- ln -sf xbmc.target $INSTALL/usr/lib/systemd/system/default.target
-
- enable_service xbmc-autostart.service
- enable_service xbmc-cleanlogs.service
- enable_service xbmc-config.service
- enable_service xbmc-hacks.service
- enable_service xbmc-sources.service
- enable_service xbmc-halt.service
- enable_service xbmc-poweroff.service
- enable_service xbmc-reboot.service
- enable_service xbmc-waitonnetwork.service
- enable_service xbmc.service
- enable_service xbmc-lirc-suspend.service
-}
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-051-add_ouya_controller_keymap.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-051-add_ouya_controller_keymap.patch
deleted file mode 100644
index 5a6df63bf4..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-051-add_ouya_controller_keymap.patch
+++ /dev/null
@@ -1,338 +0,0 @@
-diff -Naur xbmc-master-14-5ec51aa.orig/system/keymaps/joystick.Ouya.Controller.xml xbmc-master-14-5ec51aa/system/keymaps/joystick.Ouya.Controller.xml
---- xbmc-master-14-5ec51aa.orig/system/keymaps/joystick.Ouya.Controller.xml 1969-12-31 16:00:00.000000000 -0800
-+++ xbmc-master-14-5ec51aa/system/keymaps/joystick.Ouya.Controller.xml 2014-06-06 16:31:54.812044875 -0700
-@@ -0,0 +1,334 @@
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ AnalogSeekBack
-+ AnalogSeekForward
-+ ScrollUp
-+ ScrollDown
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ AnalogRewind
-+ AnalogFastForward
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ AnalogRewind
-+ AnalogFastForward
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ AnalogMove
-+ AnalogMove
-+ ZoomOut
-+ ZoomIn
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ CursorLeft
-+ CursorRight
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-052-ps4_controller_support.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-052-ps4_controller_support.patch
deleted file mode 100644
index 6beb85108b..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-052-ps4_controller_support.patch
+++ /dev/null
@@ -1,328 +0,0 @@
-diff -Naur xbmc-master-14-5ec51aa.orig/system/keymaps/joystick.PS4.Controller.xml xbmc-master-14-5ec51aa/system/keymaps/joystick.PS4.Controller.xml
---- xbmc-master-14-5ec51aa.orig/system/keymaps/joystick.PS4.Controller.xml 1969-12-31 16:00:00.000000000 -0800
-+++ xbmc-master-14-5ec51aa/system/keymaps/joystick.PS4.Controller.xml 2014-06-06 16:53:33.786191904 -0700
-@@ -0,0 +1,324 @@
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ Left
-+ Right
-+ Up
-+ Down
-+ AnalogSeekForward
-+ AnalogSeekBack
-+ ScrollUp
-+ ScrollDown
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ StepBack
-+ StepForward
-+ BigStepForward
-+ BigStepBack
-+
-+
-+
-+
-+
-+ ChannelUp
-+ ChannelDown
-+ PreviousChannelGroup
-+ NextChannelGroup
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ PreviousPicture
-+ NextPicture
-+ AnalogMove
-+ AnalogMove
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-101-fix_libdvd_xFLAGS-0.1.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-101-fix_libdvd_xFLAGS-0.1.patch
deleted file mode 100644
index 00df7bb51c..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-101-fix_libdvd_xFLAGS-0.1.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-diff -Naur xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnav-config2.sh xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnav-config2.sh
---- xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnav-config2.sh 2014-05-01 16:53:36.000000000 +0200
-+++ xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnav-config2.sh 2014-05-01 17:54:59.643325427 +0200
-@@ -56,17 +56,17 @@
- fi
-
- if test "$echo_cflags" = "yes"; then
-- echo -I$prefix/include $dvdread_cflags $extracflags $threadcflags
-+ echo $dvdread_cflags $extracflags $threadcflags
- fi
-
- if test "$echo_minicflags" = "yes"; then
-- echo -I$prefix/include -I$prefix/include/dvdnav $extracflags $threadcflags
-+ echo $extracflags $threadcflags
- fi
-
- if test "$echo_libs" = "yes"; then
-- echo -L$libdir -ldvdnav $dvdread_libs $threadlib
-+ echo -ldvdnav $dvdread_libs $threadlib
- fi
-
- if test "$echo_minilibs" = "yes"; then
-- echo -L$libdir -ldvdnavmini $threadlib
-+ echo -ldvdnavmini $threadlib
- fi
-diff -Naur xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnavmini.pc.in xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnavmini.pc.in
---- xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnavmini.pc.in 2014-05-01 16:53:36.000000000 +0200
-+++ xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnavmini.pc.in 2014-05-01 17:56:12.030447794 +0200
-@@ -7,5 +7,5 @@
- Description: DVD Navigation mini library
- Version: @VERSION@
-
--Cflags: -I${includedir} @DVDREAD_CFLAGS@ @THREAD_CFLAGS@
--Libs: -L${libdir} -ldvdnav @THREAD_LIBS@
-+Cflags: @DVDREAD_CFLAGS@ @THREAD_CFLAGS@
-+Libs: -ldvdnav @THREAD_LIBS@
-diff -Naur xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnav.pc.in xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnav.pc.in
---- xbmc-master-14-088e9fa/lib/libdvd/libdvdnav/misc/dvdnav.pc.in 2014-05-01 16:53:36.000000000 +0200
-+++ xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdnav/misc/dvdnav.pc.in 2014-05-01 17:55:50.427406667 +0200
-@@ -8,5 +8,5 @@
- Version: @VERSION@
-
- Requires.private: dvdread >= 4.1.2
--Cflags: -I${includedir} @THREAD_CFLAGS@
--Libs: -L${libdir} -ldvdnav @THREAD_LIBS@
-+Cflags: @THREAD_CFLAGS@
-+Libs: -ldvdnav @THREAD_LIBS@
-diff -Naur xbmc-master-14-088e9fa/lib/libdvd/libdvdread/misc/dvdread-config.sh xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdread/misc/dvdread-config.sh
---- xbmc-master-14-088e9fa/lib/libdvd/libdvdread/misc/dvdread-config.sh 2014-05-01 16:53:36.000000000 +0200
-+++ xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdread/misc/dvdread-config.sh 2014-05-01 17:56:55.745553577 +0200
-@@ -48,9 +48,9 @@
- fi
-
- if test "$echo_cflags" = "yes"; then
-- echo -I$prefix/include $extracflags
-+ echo $extracflags
- fi
-
- if test "$echo_libs" = "yes"; then
-- echo -L$libdir $dvdreadlib
-+ echo $dvdreadlib
- fi
-diff -Naur xbmc-master-14-088e9fa/lib/libdvd/libdvdread/misc/dvdread.pc.in xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdread/misc/dvdread.pc.in
---- xbmc-master-14-088e9fa/lib/libdvd/libdvdread/misc/dvdread.pc.in 2014-05-01 16:53:36.000000000 +0200
-+++ xbmc-master-14-088e9fa.patch/lib/libdvd/libdvdread/misc/dvdread.pc.in 2014-05-01 17:57:28.731937685 +0200
-@@ -7,5 +7,5 @@
- Description: Low level DVD access library
- Version: @VERSION@
-
--Cflags: -I${includedir}
--Libs: -L${libdir} -ldvdread
-+Cflags: -I.
-+Libs: -ldvdread
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-102-disable_backslash-0.1.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-102-disable_backslash-0.1.patch
deleted file mode 100644
index 0888920258..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-102-disable_backslash-0.1.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -Naur xbmc-30a9070/system/keymaps/keyboard.xml xbmc-30a9070.patch/system/keymaps/keyboard.xml
---- xbmc-30a9070/system/keymaps/keyboard.xml 2011-07-28 06:20:13.000000000 +0200
-+++ xbmc-30a9070.patch/system/keymaps/keyboard.xml 2011-07-28 09:39:57.210973380 +0200
-@@ -90,7 +90,7 @@
- Number7
- Number8
- Number9
-- ToggleFullScreen
-+
- FirstPage
- LastPage
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-103-disable-online-check.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-103-disable-online-check.patch
deleted file mode 100644
index 57476fed62..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-103-disable-online-check.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 1716ffbf57a8d812f3bc7b26752e867066c36c44 Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Sat, 7 Jun 2014 12:40:57 +0300
-Subject: [PATCH] disable online check
-
----
- xbmc/GUIInfoManager.cpp | 1 -
- xbmc/utils/SystemInfo.cpp | 5 +----
- xbmc/windows/GUIWindowSystemInfo.cpp | 1 -
- 3 files changed, 1 insertion(+), 6 deletions(-)
-
-diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
-index 456c733..0c20ae2 100644
---- a/xbmc/GUIInfoManager.cpp
-+++ b/xbmc/GUIInfoManager.cpp
-@@ -273,7 +273,6 @@ const infomap system_labels[] = {{ "hasnetwork", SYSTEM_ETHERNET_LINK_ACT
- { "currentwindow", SYSTEM_CURRENT_WINDOW },
- { "currentcontrol", SYSTEM_CURRENT_CONTROL },
- { "dvdlabel", SYSTEM_DVD_LABEL },
-- { "internetstate", SYSTEM_INTERNET_STATE },
- { "osversioninfo", SYSTEM_OS_VERSION_INFO },
- { "kernelversion", SYSTEM_OS_VERSION_INFO }, // old, not correct name
- { "uptime", SYSTEM_UPTIME },
-diff --git a/xbmc/utils/SystemInfo.cpp b/xbmc/utils/SystemInfo.cpp
-index 55ed760..aefeb70 100644
---- a/xbmc/utils/SystemInfo.cpp
-+++ b/xbmc/utils/SystemInfo.cpp
-@@ -240,7 +240,6 @@ bool CSysInfoJob::DoWork()
- {
- m_info.systemUptime = GetSystemUpTime(false);
- m_info.systemTotalUptime = GetSystemUpTime(true);
-- m_info.internetState = GetInternetState();
- m_info.videoEncoder = GetVideoEncoder();
- m_info.cpuFrequency = GetCPUFreqInfo();
- m_info.osVersionInfo = CSysInfo::GetOsPrettyNameWithVersion() + " (kernel: " + CSysInfo::GetKernelName() + " " + CSysInfo::GetKernelVersionFull() + ")";
-@@ -963,9 +962,7 @@ int CSysInfo::GetXbmcBitness(void)
-
- bool CSysInfo::HasInternet()
- {
-- if (m_info.internetState != CSysData::UNKNOWN)
-- return m_info.internetState == CSysData::CONNECTED;
-- return (m_info.internetState = CSysInfoJob::GetInternetState()) == CSysData::CONNECTED;
-+ return m_info.internetState == CSysData::UNKNOWN;
- }
-
- CStdString CSysInfo::GetHddSpaceInfo(int drive, bool shortText)
-diff --git a/xbmc/windows/GUIWindowSystemInfo.cpp b/xbmc/windows/GUIWindowSystemInfo.cpp
-index 03a23e3..1528939 100644
---- a/xbmc/windows/GUIWindowSystemInfo.cpp
-+++ b/xbmc/windows/GUIWindowSystemInfo.cpp
-@@ -126,7 +126,6 @@ void CGUIWindowSystemInfo::FrameMove()
- SetControlLabel(i++, "%s: %s", 13160, NETWORK_GATEWAY_ADDRESS);
- SetControlLabel(i++, "%s: %s", 13161, NETWORK_DNS1_ADDRESS);
- SetControlLabel(i++, "%s: %s", 20307, NETWORK_DNS2_ADDRESS);
-- SetControlLabel(i++, "%s %s", 13295, SYSTEM_INTERNET_STATE);
- }
- else if (m_section == CONTROL_BT_VIDEO)
- {
---
-1.9.1
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-104-use-udevil-to-umount.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-104-use-udevil-to-umount.patch
deleted file mode 100644
index 86bfb5c4fe..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-104-use-udevil-to-umount.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 855160db446fe0059f072b207d53c15ba18d952f Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Thu, 17 Apr 2014 12:12:50 +0300
-Subject: [PATCH] use udevil to umount
-
----
- xbmc/linux/PosixMountProvider.cpp | 2 +-
- xbmc/storage/linux/UDevProvider.cpp | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/xbmc/linux/PosixMountProvider.cpp b/xbmc/linux/PosixMountProvider.cpp
-index 2339709..7001563 100644
---- a/xbmc/linux/PosixMountProvider.cpp
-+++ b/xbmc/linux/PosixMountProvider.cpp
-@@ -131,7 +131,7 @@ bool CPosixMountProvider::Eject(CStdString mountpath)
- {
- // just go ahead and try to umount the disk
- // if it does umount, life is good, if not, no loss.
-- std::string cmd = "umount \"" + mountpath + "\"";
-+ std::string cmd = "udevil umount \"" + mountpath + "\"";
- int status = system(cmd.c_str());
-
- if (status == 0)
-diff --git a/xbmc/storage/linux/UDevProvider.cpp b/xbmc/storage/linux/UDevProvider.cpp
-index 73aa408..8bd02b6 100644
---- a/xbmc/storage/linux/UDevProvider.cpp
-+++ b/xbmc/storage/linux/UDevProvider.cpp
-@@ -183,7 +183,7 @@ bool CUDevProvider::Eject(CStdString mountpath)
- {
- // just go ahead and try to umount the disk
- // if it does umount, life is good, if not, no loss.
-- std::string cmd = "umount \"" + mountpath + "\"";
-+ std::string cmd = "udevil umount \"" + mountpath + "\"";
- int status = system(cmd.c_str());
-
- if (status == 0)
---
-1.9.1
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch
deleted file mode 100644
index d58eeecb9d..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp
-index 01a129e..07b4878 100644
---- a/xbmc/interfaces/python/XBPython.cpp
-+++ b/xbmc/interfaces/python/XBPython.cpp
-@@ -445,10 +445,9 @@ bool XBPython::InitializeEngine()
- // at http://docs.python.org/using/cmdline.html#environment-variables
-
- #if !defined(TARGET_WINDOWS) && !defined(TARGET_ANDROID)
-- /* PYTHONOPTIMIZE is set off intentionally when using external Python.
-- Reason for this is because we cannot be sure what version of Python
-- was used to compile the various Python object files (i.e. .pyo,
-- .pyc, etc.). */
-+ // Required for python to find optimized code (pyo) files
-+ setenv("PYTHONOPTIMIZE", "1", 1);
-+
- // check if we are running as real xbmc.app or just binary
- if (!CUtil::GetFrameworksPath(true).empty())
- {
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-502-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-502-add_openelec.tv_RSS_news-0.1.patch
deleted file mode 100644
index f0b08b5e8d..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-502-add_openelec.tv_RSS_news-0.1.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Naur xbmc-12.0.7/userdata/RssFeeds.xml xbmc-12.0.7.patch/userdata/RssFeeds.xml
---- xbmc-12.0.7/userdata/RssFeeds.xml 2013-03-15 14:25:26.000000000 +0100
-+++ xbmc-12.0.7.patch/userdata/RssFeeds.xml 2013-03-15 14:40:54.695338102 +0100
-@@ -3,6 +3,7 @@
-
-
-
-+ http://feeds.openelec.tv/news
- http://feeds.xbmc.org/xbmc
-
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-990.15-depends-mark_our_wrapped_functions_as_used.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-990.15-depends-mark_our_wrapped_functions_as_used.patch
deleted file mode 100644
index 7e78fbb3b9..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-990.15-depends-mark_our_wrapped_functions_as_used.patch
+++ /dev/null
@@ -1,458 +0,0 @@
-From 0c2eaf5082a30fb06bad553775e805a745d59ee2 Mon Sep 17 00:00:00 2001
-From: theuni
-Date: Tue, 22 Jan 2013 04:09:07 -0500
-Subject: [PATCH] depends: mark our wrapped functions as used
-
-otherwise they get stripped when enabling dead code stripping
----
- xbmc/cores/DllLoader/exports/wrapper.c | 138 ++++++++++++++++-----------------
- 1 file changed, 69 insertions(+), 69 deletions(-)
-
-diff -Naur xbmc-f81d56e/xbmc/cores/DllLoader/exports/wrapper.c xbmc-f81d56e.patch/xbmc/cores/DllLoader/exports/wrapper.c
---- xbmc-f81d56e/xbmc/cores/DllLoader/exports/wrapper.c 2013-05-18 12:30:19.000000000 +0200
-+++ xbmc-f81d56e.patch/xbmc/cores/DllLoader/exports/wrapper.c 2013-05-18 16:55:55.222087716 +0200
-@@ -115,7 +115,7 @@
- int dll_setvbuf(FILE *stream, char *buf, int type, size_t size);
- struct mntent *dll_getmntent(FILE *fp);
-
--void *__wrap_dlopen(const char *filename, int flag)
-+__attribute__((used)) void *__wrap_dlopen(const char *filename, int flag)
- {
- #if defined(TARGET_ANDROID)
- return dll_dlopen(filename, flag);
-@@ -124,213 +124,213 @@
- #endif
- }
-
--FILE *__wrap_popen(const char *command, const char *mode)
-+__attribute__((used)) FILE *__wrap_popen(const char *command, const char *mode)
- {
- return dll_popen(command, mode);
- }
-
--void* __wrap_calloc( size_t num, size_t size )
-+__attribute__((used)) void* __wrap_calloc( size_t num, size_t size )
- {
- return dllcalloc(num, size);
- }
-
--void* __wrap_malloc(size_t size)
-+__attribute__((used)) void* __wrap_malloc(size_t size)
- {
- return dllmalloc(size);
- }
-
--void* __wrap_realloc( void *memblock, size_t size )
-+__attribute__((used)) void* __wrap_realloc( void *memblock, size_t size )
- {
- return dllrealloc(memblock, size);
- }
-
--void __wrap_free( void* pPtr )
-+__attribute__((used)) void __wrap_free( void* pPtr )
- {
- dllfree(pPtr);
- }
-
--int __wrap_open(const char *file, int oflag, ...)
-+__attribute__((used)) int __wrap_open(const char *file, int oflag, ...)
- {
- return dll_open(file, oflag);
- }
-
--int __wrap_open64(const char *file, int oflag, ...)
-+__attribute__((used)) int __wrap_open64(const char *file, int oflag, ...)
- {
- return dll_open(file, oflag);
- }
-
--int __wrap_close(int fd)
-+__attribute__((used)) int __wrap_close(int fd)
- {
- return dll_close(fd);
- }
-
--ssize_t __wrap_write(int fd, const void *buf, size_t count)
-+__attribute__((used)) ssize_t __wrap_write(int fd, const void *buf, size_t count)
- {
- return dll_write(fd, buf, count);
- }
-
--ssize_t __wrap_read(int fd, void *buf, size_t count)
-+__attribute__((used)) ssize_t __wrap_read(int fd, void *buf, size_t count)
- {
- return dll_read(fd, buf, count);
- }
-
--__off_t __wrap_lseek(int fildes, __off_t offset, int whence)
-+__attribute__((used)) __off_t __wrap_lseek(int fildes, __off_t offset, int whence)
- {
- return dll_lseek(fildes, offset, whence);
- }
-
--__off64_t __wrap_lseek64(int fildes, __off64_t offset, int whence)
-+__attribute__((used)) __off64_t __wrap_lseek64(int fildes, __off64_t offset, int whence)
- {
- __off64_t seekRes = dll_lseeki64(fildes, offset, whence);
- return seekRes;
- }
-
--int __wrap_fclose(FILE *fp)
-+__attribute__((used)) int __wrap_fclose(FILE *fp)
- {
- return dll_fclose(fp);
- }
-
--int __wrap_ferror(FILE *stream)
-+__attribute__((used)) int __wrap_ferror(FILE *stream)
- {
- return dll_ferror(stream);
- }
-
--void __wrap_clearerr(FILE *stream)
-+__attribute__((used)) void __wrap_clearerr(FILE *stream)
- {
- return dll_clearerr(stream);
- }
-
--int __wrap_feof(FILE *stream)
-+__attribute__((used)) int __wrap_feof(FILE *stream)
- {
- return dll_feof(stream);
- }
-
--int __wrap_fileno(FILE *stream)
-+__attribute__((used)) int __wrap_fileno(FILE *stream)
- {
- return dll_fileno(stream);
- }
-
--FILE *__wrap_fopen(const char *path, const char *mode)
-+__attribute__((used)) FILE *__wrap_fopen(const char *path, const char *mode)
- {
- return dll_fopen(path, mode);
- }
-
--FILE *__wrap_fopen64(const char *path, const char *mode)
-+__attribute__((used)) FILE *__wrap_fopen64(const char *path, const char *mode)
- {
- return dll_fopen(path, mode);
- }
-
--FILE *__wrap_fdopen(int fildes, const char *mode)
-+__attribute__((used)) FILE *__wrap_fdopen(int fildes, const char *mode)
- {
- return dll_fdopen(fildes, mode);
- }
-
--FILE *__wrap_freopen(const char *path, const char *mode, FILE *stream)
-+__attribute__((used)) FILE *__wrap_freopen(const char *path, const char *mode, FILE *stream)
- {
- return dll_freopen(path, mode, stream);
- }
-
--size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-+__attribute__((used)) size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
- {
- return dll_fread(ptr, size, nmemb, stream);
- }
-
--size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
-+__attribute__((used)) size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
- {
- return dll_fwrite(ptr, size, nmemb, stream);
- }
-
--int __wrap_fflush(FILE *stream)
-+__attribute__((used)) int __wrap_fflush(FILE *stream)
- {
- return dll_fflush(stream);
- }
-
--int __wrap_fputc(int c, FILE *stream)
-+__attribute__((used)) int __wrap_fputc(int c, FILE *stream)
- {
- return dll_fputc(c, stream);
- }
-
--int __wrap_fputs(const char *s, FILE *stream)
-+__attribute__((used)) int __wrap_fputs(const char *s, FILE *stream)
- {
- return dll_fputs(s, stream);
- }
-
--int __wrap__IO_putc(int c, FILE *stream)
-+__attribute__((used)) int __wrap__IO_putc(int c, FILE *stream)
- {
- return dll_putc(c, stream);
- }
-
--int __wrap_fseek(FILE *stream, long offset, int whence)
-+__attribute__((used)) int __wrap_fseek(FILE *stream, long offset, int whence)
- {
- return dll_fseek(stream, offset, whence);
- }
-
--int __wrap_fseeko64(FILE *stream, off64_t offset, int whence)
-+__attribute__((used)) int __wrap_fseeko64(FILE *stream, off64_t offset, int whence)
- {
- return dll_fseek64(stream, offset, whence);
- }
-
--long __wrap_ftell(FILE *stream)
-+__attribute__((used)) long __wrap_ftell(FILE *stream)
- {
- return dll_ftell(stream);
- }
-
--off64_t __wrap_ftello64(FILE *stream)
-+__attribute__((used)) off64_t __wrap_ftello64(FILE *stream)
- {
- return dll_ftell64(stream);
- }
-
--void __wrap_rewind(FILE *stream)
-+__attribute__((used)) void __wrap_rewind(FILE *stream)
- {
- dll_rewind(stream);
- }
-
--int __wrap_fgetpos(FILE *stream, fpos_t *pos)
-+__attribute__((used)) int __wrap_fgetpos(FILE *stream, fpos_t *pos)
- {
- return dll_fgetpos(stream, pos);
- }
-
--int __wrap_fgetpos64(FILE *stream, fpos64_t *pos)
-+__attribute__((used)) int __wrap_fgetpos64(FILE *stream, fpos64_t *pos)
- {
- return dll_fgetpos64(stream, pos);
- }
-
--int __wrap_fsetpos(FILE *stream, fpos_t *pos)
-+__attribute__((used)) int __wrap_fsetpos(FILE *stream, fpos_t *pos)
- {
- return dll_fsetpos(stream, pos);
- }
-
--int __wrap_fsetpos64(FILE *stream, fpos64_t *pos)
-+__attribute__((used)) int __wrap_fsetpos64(FILE *stream, fpos64_t *pos)
- {
- return dll_fsetpos64(stream, pos);
- }
-
--DIR * __wrap_opendir(const char *name)
-+__attribute__((used)) DIR * __wrap_opendir(const char *name)
- {
- return dll_opendir(name);
- }
-
--struct dirent * __wrap_readdir(DIR* dirp)
-+__attribute__((used)) struct dirent * __wrap_readdir(DIR* dirp)
- {
- return dll_readdir(dirp);
- }
-
--struct dirent * __wrap_readdir64(DIR* dirp)
-+__attribute__((used)) struct dirent * __wrap_readdir64(DIR* dirp)
- {
- return dll_readdir(dirp);
- }
-
--int __wrap_closedir(DIR* dirp)
-+__attribute__((used)) int __wrap_closedir(DIR* dirp)
- {
- return dll_closedir(dirp);
- }
-
--void __wrap_rewinddir(DIR* dirp)
-+__attribute__((used)) void __wrap_rewinddir(DIR* dirp)
- {
- dll_rewinddir(dirp);
- }
-
--int __wrap_fprintf(FILE *stream, const char *format, ...)
-+__attribute__((used)) int __wrap_fprintf(FILE *stream, const char *format, ...)
- {
- int res;
- va_list va;
-@@ -340,12 +340,12 @@
- return res;
- }
-
--int __wrap_vfprintf(FILE *stream, const char *format, va_list ap)
-+__attribute__((used)) int __wrap_vfprintf(FILE *stream, const char *format, va_list ap)
- {
- return dll_vfprintf(stream, format, ap);
- }
-
--int __wrap_printf(const char *format, ...)
-+__attribute__((used)) int __wrap_printf(const char *format, ...)
- {
- int res;
- va_list va;
-@@ -355,42 +355,42 @@
- return res;
- }
-
--int __wrap_fgetc(FILE *stream)
-+__attribute__((used)) int __wrap_fgetc(FILE *stream)
- {
- return dll_fgetc(stream);
- }
-
--char *__wrap_fgets(char *s, int size, FILE *stream)
-+__attribute__((used)) char *__wrap_fgets(char *s, int size, FILE *stream)
- {
- return dll_fgets(s, size, stream);
- }
-
--int __wrap__IO_getc(FILE *stream)
-+__attribute__((used)) int __wrap__IO_getc(FILE *stream)
- {
- return dll_getc(stream);
- }
-
--int __wrap__IO_getc_unlocked(FILE *stream)
-+__attribute__((used)) int __wrap__IO_getc_unlocked(FILE *stream)
- {
- return dll_getc(stream);
- }
-
--int __wrap_getc_unlocked(FILE *stream)
-+__attribute__((used)) int __wrap_getc_unlocked(FILE *stream)
- {
- return dll_getc(stream);
- }
-
--int __wrap_ungetc(int c, FILE *stream)
-+__attribute__((used)) int __wrap_ungetc(int c, FILE *stream)
- {
- return dll_ungetc(c, stream);
- }
-
--int __wrap_getc(FILE *stream)
-+__attribute__((used)) int __wrap_getc(FILE *stream)
- {
- return dll_getc(stream);
- }
-
--int __wrap_ioctl(int d, unsigned long int request, ...)
-+__attribute__((used)) int __wrap_ioctl(int d, unsigned long int request, ...)
- {
- int res;
- va_list va;
-@@ -400,57 +400,57 @@
- return res;
- }
-
--int __wrap__stat(const char *path, struct _stat *buffer)
-+__attribute__((used)) int __wrap__stat(const char *path, struct _stat *buffer)
- {
- return dll_stat(path, buffer);
- }
-
--int __wrap_stat(const char *path, struct _stat *buffer)
-+__attribute__((used)) int __wrap_stat(const char *path, struct _stat *buffer)
- {
- return dll_stat(path, buffer);
- }
-
--int __wrap___xstat64(int __ver, const char *__filename, struct stat64 *__stat_buf)
-+__attribute__((used)) int __wrap___xstat64(int __ver, const char *__filename, struct stat64 *__stat_buf)
- {
- return dll_stat64(__filename, __stat_buf);
- }
-
--int __wrap___lxstat64(int __ver, const char *__filename, struct stat64 *__stat_buf)
-+__attribute__((used)) int __wrap___lxstat64(int __ver, const char *__filename, struct stat64 *__stat_buf)
- {
- return dll_stat64(__filename, __stat_buf);
- }
-
--void __wrap_flockfile(FILE *file)
-+__attribute__((used)) void __wrap_flockfile(FILE *file)
- {
- dll_flockfile(file);
- }
-
--int __wrap_ftrylockfile(FILE *file)
-+__attribute__((used)) int __wrap_ftrylockfile(FILE *file)
- {
- return dll_ftrylockfile(file);
- }
-
--void __wrap_funlockfile(FILE *file)
-+__attribute__((used)) void __wrap_funlockfile(FILE *file)
- {
- dll_funlockfile(file);
- }
-
--int __wrap___fxstat64(int ver, int fd, struct stat64 *buf)
-+__attribute__((used)) int __wrap___fxstat64(int ver, int fd, struct stat64 *buf)
- {
- return dll_fstat64(fd, buf);
- }
-
--int __wrap_fstat(int fd, struct _stat *buf)
-+__attribute__((used)) int __wrap_fstat(int fd, struct _stat *buf)
- {
- return dll_fstat(fd, buf);
- }
-
--int __wrap_setvbuf(FILE *stream, char *buf, int type, size_t size)
-+__attribute__((used)) int __wrap_setvbuf(FILE *stream, char *buf, int type, size_t size)
- {
- return dll_setvbuf(stream, buf, type, size);
- }
-
--struct mntent *__wrap_getmntent(FILE *fp)
-+__attribute__((used)) struct mntent *__wrap_getmntent(FILE *fp)
- {
- #ifdef _LINUX
- return dll_getmntent(fp);
-@@ -464,12 +464,12 @@
- // thing to actually call our wrapped functions.
- #if _FORTIFY_SOURCE > 1
-
--size_t __wrap___fread_chk(void * ptr, size_t ptrlen, size_t size, size_t n, FILE * stream)
-+__attribute__((used)) size_t __wrap___fread_chk(void * ptr, size_t ptrlen, size_t size, size_t n, FILE * stream)
- {
- return dll_fread(ptr, size, n, stream);
- }
-
--int __wrap___printf_chk(int flag, const char *format, ...)
-+__attribute__((used)) int __wrap___printf_chk(int flag, const char *format, ...)
- {
- int res;
- va_list va;
-@@ -479,12 +479,12 @@
- return res;
- }
-
--int __wrap___vfprintf_chk(FILE* stream, int flag, const char *format, _G_va_list ap)
-+__attribute__((used)) int __wrap___vfprintf_chk(FILE* stream, int flag, const char *format, _G_va_list ap)
- {
- return dll_vfprintf(stream, format, ap);
- }
-
--int __wrap___fprintf_chk(FILE * stream, int flag, const char *format, ...)
-+__attribute__((used)) int __wrap___fprintf_chk(FILE * stream, int flag, const char *format, ...)
- {
- int res;
- va_list va;
-@@ -494,12 +494,12 @@
- return res;
- }
-
--char *__wrap___fgets_chk(char *s, size_t size, int n, FILE *stream)
-+__attribute__((used)) char *__wrap___fgets_chk(char *s, size_t size, int n, FILE *stream)
- {
- return dll_fgets(s, n, stream);
- }
-
--size_t __wrap___read_chk(int fd, void *buf, size_t nbytes, size_t buflen)
-+__attribute__((used)) size_t __wrap___read_chk(int fd, void *buf, size_t nbytes, size_t buflen)
- {
- return dll_read(fd, buf, nbytes);
- }
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.01-fernetmenta.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-995.01-fernetmenta.patch
deleted file mode 100644
index 9b4386061b..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.01-fernetmenta.patch
+++ /dev/null
@@ -1,3420 +0,0 @@
-From 653f57ae1d9895d66a0a4a188607ae9f93db7022 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Mon, 28 May 2012 10:34:39 +0200
-Subject: [PATCH 09/35] 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 | 38 +++-
- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 41 +++++
- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 +
- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 197 +++++++++++++++++----
- xbmc/cores/dvdplayer/DVDPlayerVideo.h | 22 +++
- 7 files changed, 295 insertions(+), 38 deletions(-)
-
-diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
-index 6832721..f4b381e 100644
---- a/xbmc/cores/VideoRenderers/RenderManager.cpp
-+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
-@@ -286,6 +286,8 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
- m_bIsStarted = true;
- m_bReconfigured = true;
- m_presentstep = PRESENT_IDLE;
-+ m_presentpts = DVD_NOPTS_VALUE;
-+ m_sleeptime = 1.0;
- m_presentevent.notifyAll();
-
- m_firstFlipPage = false; // tempfix
-@@ -629,7 +631,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode)
- m_pRenderer->SetViewMode(iViewMode);
- }
-
--void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/)
-+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/)
- {
- { CSharedLock lock(m_sharedSection);
-
-@@ -697,6 +699,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L
- m.timestamp = timestamp;
- m.presentfield = sync;
- m.presentmethod = presentmethod;
-+ m.pts = pts;
- requeue(m_queued, m_free);
-
- /* signal to any waiters to check state */
-@@ -1065,6 +1068,8 @@ void CXBMCRenderManager::PrepareNextRender()
- m_discard.push_back(m_presentsource);
- m_presentsource = idx;
- m_queued.pop_front();
-+ m_sleeptime = m_Queue[idx].timestamp - clocktime;
-+ m_presentpts = m_Queue[idx].pts;
- m_presentevent.notifyAll();
- }
- }
-@@ -1081,3 +1086,12 @@ void CXBMCRenderManager::DiscardBuffer()
- m_presentstep = PRESENT_IDLE;
- m_presentevent.notifyAll();
- }
-+
-+bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel)
-+{
-+ CSingleLock lock(m_presentlock);
-+ sleeptime = m_sleeptime;
-+ pts = m_presentpts;
-+ bufferLevel = m_queued.size() + m_discard.size();
-+ return true;
-+}
-diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
-index c469795..949c652b 100644
---- a/xbmc/cores/VideoRenderers/RenderManager.h
-+++ b/xbmc/cores/VideoRenderers/RenderManager.h
-@@ -98,10 +98,11 @@ class CXBMCRenderManager
- *
- * @param bStop reference to stop flag of calling thread
- * @param timestamp of frame delivered with AddVideoPicture
-+ * @param pts used for lateness detection
- * @param source depreciated
- * @param sync signals frame, top, or bottom field
- */
-- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE);
-+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE);
- unsigned int PreInit();
- void UnInit();
- bool Flush();
-@@ -176,6 +177,12 @@ class CXBMCRenderManager
- int WaitForBuffer(volatile bool& bStop, int timeout = 100);
-
- /**
-+ * Can be called by player for lateness detection. This is done best by
-+ * looking at the end of the queue.
-+ */
-+ bool GetStats(double &sleeptime, double &pts, int &bufferLevel);
-+
-+ /**
- * Video player call this on flush in oder to discard any queued frames
- */
- void DiscardBuffer();
-@@ -222,6 +229,7 @@ class CXBMCRenderManager
-
- struct SPresent
- {
-+ double pts;
- double timestamp;
- EFIELDSYNC presentfield;
- EPRESENTMETHOD presentmethod;
-@@ -233,6 +241,8 @@ class CXBMCRenderManager
-
- ERenderFormat m_format;
-
-+ double m_sleeptime;
-+ double m_presentpts;
- double m_presentcorr;
- double m_presenterr;
- double m_errorbuff[ERRORBUFFSIZE];
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-index 741017d..c5b24d6 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-@@ -136,6 +136,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 // see GetCodecStats
-+#define DVP_FLAG_DRAIN 0x00000200 // see GetCodecStats
-+
- // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2!
-
- #define DVP_QSCALE_UNKNOWN 0
-@@ -153,6 +157,8 @@ 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
-+
- class CDVDVideoCodec
- {
- public:
-@@ -270,7 +276,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
-@@ -287,4 +292,35 @@ class CDVDVideoCodec
- * Interact with user settings so that user disabled codecs are disabled
- */
- static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id);
-+
-+ /* For calculation of dropping requirements player asks for some information.
-+ *
-+ * - pts : right after decoder, used to detect gaps (dropped frames in decoder)
-+ * - droppedPics : indicates if decoder has dropped a picture
-+ * -1 means that decoder has no info on this.
-+ *
-+ * If codec does not implement this method, pts of decoded frame at input
-+ * video player is used. In case decoder 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 &droppedPics)
-+ {
-+ droppedPics= -1;
-+ 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 b6c1e04..c48108f 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-@@ -167,6 +167,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
- m_iLastKeyframe = 0;
- m_dts = DVD_NOPTS_VALUE;
- m_started = false;
-+ m_decoderPts = DVD_NOPTS_VALUE;
- }
-
- CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
-@@ -342,6 +343,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
-@@ -543,6 +552,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);
-
-@@ -640,6 +650,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;
-
-@@ -821,3 +847,18 @@ unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
- else
- return 0;
- }
-+
-+bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &droppedPics)
-+{
-+ pts = m_decoderPts;
-+ if (m_skippedDeint)
-+ droppedPics = m_skippedDeint;
-+ else
-+ droppedPics = -1;
-+ 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 75ac0f2..1a80a48 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 GetCodecStats(double &pts, int &droppedPics);
-+ 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 633e333..09b7772 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
-@@ -319,8 +320,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)
- {
-@@ -432,6 +435,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())
- {
-@@ -444,6 +448,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;
-@@ -463,6 +468,7 @@ void CDVDPlayerVideo::Process()
- m_iNrOfPicturesNotToSkip = 0;
- if (m_pVideoCodec)
- m_pVideoCodec->SetSpeed(m_speed);
-+ m_droppingStats.Reset();
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
- {
-@@ -508,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)
- {
-@@ -560,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;
-@@ -1182,33 +1202,12 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
- m_FlipTimeStamp += max(0.0, iSleepTime);
- m_FlipTimePts = pts;
-
-- 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;
-@@ -1241,7 +1240,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
-@@ -1541,3 +1540,131 @@ void CDVDPlayerVideo::CalcFrameRate()
- m_iFrameRateCount = 0;
- }
- }
-+
-+int CDVDPlayerVideo::CalcDropRequirement(double pts)
-+{
-+ int result = 0;
-+ double iSleepTime;
-+ double iDecoderPts, iRenderPts;
-+ double iInterval;
-+ double iGain;
-+ double iLateness;
-+ bool bNewFrame;
-+ int iDroppedPics = -1;
-+ int iBufferLevel;
-+
-+ // get decoder stats
-+ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iDroppedPics))
-+ 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;
-+
-+ 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)
-+ {
-+ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE;
-+ if (iDroppedPics > 0)
-+ {
-+ CDroppingStats::CGain gain;
-+ gain.gain = iDroppedPics * 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 pictures, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain);
-+ }
-+ else if (iDroppedPics < 0 && 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)
-+ {
-+ if (bNewFrame || m_droppingStats.m_dropRequests < 5)
-+ {
-+ result |= EOS_VERYLATE;
-+ }
-+ 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 296cae6..328edbf 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-@@ -37,6 +37,24 @@ 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 IDVDStreamPlayer
- {
- public:
-@@ -105,6 +123,7 @@ class CDVDPlayerVideo : public CThread, public IDVDStreamPlayer
- #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);
-@@ -131,6 +150,7 @@ class CDVDPlayerVideo : public CThread, public IDVDStreamPlayer
-
- 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
-@@ -184,5 +204,7 @@ class CDVDPlayerVideo : public CThread, public IDVDStreamPlayer
- CPullupCorrection m_pullupCorrection;
-
- std::list m_packets;
-+
-+ CDroppingStats m_droppingStats;
- };
-
---
-1.9.3
-
-
-From 2efc326a47e290a801cd835296b6045e72d0e212 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Sun, 2 Sep 2012 16:05:21 +0200
-Subject: [PATCH 10/35] video player: present correct pts to user for a/v sync
- (after buffering in renderer)
-
----
- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 16 ++++++++++++++++
- xbmc/cores/dvdplayer/DVDPlayerVideo.h | 2 +-
- 2 files changed, 17 insertions(+), 1 deletion(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-index 09b7772..24282cc 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-@@ -1460,6 +1460,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
-
-diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-index 328edbf..1cca436 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-@@ -100,7 +100,7 @@ class CDVDPlayerVideo : public CThread, public IDVDStreamPlayer
-
- bool InitializedOutputDevice();
-
-- double GetCurrentPts() { return m_iCurrentPts; }
-+ double GetCurrentPts();
- int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); }
-
- double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */
---
-1.9.3
-
-
-From 5f08b21d01b7c74e78024485a2b2d5874804b5f7 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Sat, 1 Jun 2013 11:21:19 +0200
-Subject: [PATCH 11/35] 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 fb41ccf..f5e5677 100644
---- a/xbmc/cores/VideoRenderers/BaseRenderer.h
-+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h
-@@ -29,7 +29,7 @@
-
- #define MAX_PLANES 3
- #define MAX_FIELDS 3
--#define NUM_BUFFERS 3
-+#define NUM_BUFFERS 5
-
- class CSetting;
-
---
-1.9.3
-
-
-From 5e1bf08878926117994fc7e4ef011b0592bdd309 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Mon, 28 May 2012 10:41:31 +0200
-Subject: [PATCH 12/35] 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 24282cc..5c219d6 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-@@ -708,6 +708,8 @@ void CDVDPlayerVideo::Process()
-
- int iResult = OutputPicture(&picture, pts);
-
-+ frametime = (double)DVD_TIME_BASE/m_fFrameRate;
-+
- if(m_started == false)
- {
- m_codecname = m_pVideoCodec->GetName();
---
-1.9.3
-
-
-From a4f5190b81b1e1f46771282f4520e50256fc67c5 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Mon, 28 May 2012 10:43:06 +0200
-Subject: [PATCH 13/35] 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 5c219d6..767f6bd 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-@@ -1502,7 +1502,7 @@ void CDVDPlayerVideo::CalcFrameRate()
- double frameduration = m_pullupCorrection.GetFrameDuration();
-
- if (frameduration == DVD_NOPTS_VALUE ||
-- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1))
-+ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid)))
- {
- //reset the stored framerates if no good framerate was detected
- m_fStableFrameRate = 0.0;
---
-1.9.3
-
-
-From 6706086f632fb0a291e007851bedb8a1673c3cdb Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Mon, 28 May 2012 10:49:05 +0200
-Subject: [PATCH 14/35] 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 85b9f1c..1b2f820 100644
---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
-@@ -1595,7 +1595,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())
- {
-@@ -2219,6 +2219,12 @@ void CDVDPlayer::HandleMessages()
- pvrinputstream->Pause( speed == 0 );
- }
-
-+ // do a seek after rewind, clock is not in sync with current pts
-+ if (m_playSpeed < 0 && speed >= 0)
-+ {
-+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true));
-+ }
-+
- // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE
- // audioplayer, stops outputing audio to audiorendere, but still tries to
- // sleep an correct amount for each packet
---
-1.9.3
-
-
-From ece66466f1d6666816db1631a5be2b4c505fa926 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Mon, 20 Aug 2012 16:06:39 +0200
-Subject: [PATCH 15/35] 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 710482f..49eff5c 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"
-@@ -427,6 +427,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
-
- CreateStreams();
-
-+ m_bPtsWrapChecked = false;
-+ m_bPtsWrap = false;
-+
- return true;
- }
-
-@@ -568,6 +571,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;
-@@ -707,6 +716,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;
-
-@@ -840,7 +867,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)
-@@ -859,6 +895,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
- return (ret >= 0);
- }
-
-+bool CDVDDemuxFFmpeg::SeekTimeDiscont(int64_t pts, bool backwards)
-+{
-+ // this code is taken from ffmpeg function ff_gen_search
-+ // it is modified to assume a pts overflow if timestamp < start_time
-+ if (!m_pFormatContext->iformat->read_timestamp)
-+ return false;
-+
-+ int defaultStream = av_find_default_stream_index(m_pFormatContext);
-+
-+ if (defaultStream < 0)
-+ {
-+ return false;
-+ }
-+
-+ // timestamp for default must be expressed in AV_TIME_BASE units
-+ pts = av_rescale_rnd(pts, m_pFormatContext->streams[defaultStream]->time_base.den,
-+ AV_TIME_BASE * (int64_t)m_pFormatContext->streams[defaultStream]->time_base.num,
-+ AV_ROUND_NEAR_INF);
-+
-+ int64_t pos, pos_min, pos_max, pos_limit, ts, ts_min, ts_max;
-+ int64_t start_pos, filesize;
-+ int no_change;
-+
-+ pos_min = m_pFormatContext->data_offset;
-+ ts_min = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
-+ &pos_min, INT64_MAX);
-+ if (ts_min == AV_NOPTS_VALUE)
-+ return false;
-+
-+ if(ts_min >= pts)
-+ {
-+ pos = pos_min;
-+ return true;
-+ }
-+
-+ int step= 1024;
-+ filesize = m_pInput->GetLength();
-+ pos_max = filesize - 1;
-+ do
-+ {
-+ pos_max -= step;
-+ ts_max = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
-+ &pos_max, pos_max + step);
-+ step += step;
-+ }while (ts_max == AV_NOPTS_VALUE && pos_max >= step);
-+
-+ if (ts_max == AV_NOPTS_VALUE)
-+ return false;
-+
-+ if (ts_max < m_iStartTime && ts_max < m_iEndTime)
-+ ts_max += m_iMaxTime;
-+
-+ for(;;)
-+ {
-+ int64_t tmp_pos = pos_max + 1;
-+ int64_t tmp_ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
-+ &tmp_pos, INT64_MAX);
-+ if(tmp_ts == AV_NOPTS_VALUE)
-+ break;
-+
-+ if (tmp_ts < m_iStartTime && tmp_ts < m_iEndTime)
-+ tmp_ts += m_iMaxTime;
-+
-+ ts_max = tmp_ts;
-+ pos_max = tmp_pos;
-+ if (tmp_pos >= filesize)
-+ break;
-+ }
-+ pos_limit = pos_max;
-+
-+ if(ts_max <= pts)
-+ {
-+ bool ret = SeekByte(pos_max);
-+ if (ret)
-+ {
-+ m_iCurrentPts = ConvertTimestamp(ts_max, m_pFormatContext->streams[defaultStream]->time_base.den,
-+ m_pFormatContext->streams[defaultStream]->time_base.num);
-+ }
-+ return ret;
-+ }
-+
-+ if(ts_min > ts_max)
-+ {
-+ return false;
-+ }
-+ else if (ts_min == ts_max)
-+ {
-+ pos_limit = pos_min;
-+ }
-+
-+ no_change=0;
-+ while (pos_min < pos_limit)
-+ {
-+ if (no_change == 0)
-+ {
-+ int64_t approximate_keyframe_distance= pos_max - pos_limit;
-+ // interpolate position (better than dichotomy)
-+ pos = av_rescale_rnd(pts - ts_min, pos_max - pos_min,
-+ ts_max - ts_min, AV_ROUND_NEAR_INF)
-+ + pos_min - approximate_keyframe_distance;
-+ }
-+ else if (no_change == 1)
-+ {
-+ // bisection, if interpolation failed to change min or max pos last time
-+ pos = (pos_min + pos_limit) >> 1;
-+ }
-+ else
-+ {
-+ /* linear search if bisection failed, can only happen if there
-+ are very few or no keyframes between min/max */
-+ pos = pos_min;
-+ }
-+ if (pos <= pos_min)
-+ pos= pos_min + 1;
-+ else if (pos > pos_limit)
-+ pos= pos_limit;
-+ start_pos = pos;
-+
-+ ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream,
-+ &pos, INT64_MAX);
-+ if (pos == pos_max)
-+ no_change++;
-+ else
-+ no_change=0;
-+
-+ if (ts == AV_NOPTS_VALUE)
-+ {
-+ return false;
-+ }
-+
-+ if (ts < m_iStartTime && ts < m_iEndTime)
-+ ts += m_iMaxTime;
-+
-+ if (pts <= ts)
-+ {
-+ pos_limit = start_pos - 1;
-+ pos_max = pos;
-+ ts_max = ts;
-+ }
-+ if (pts >= ts)
-+ {
-+ pos_min = pos;
-+ ts_min = ts;
-+ }
-+ }
-+
-+ pos = (backwards) ? pos_min : pos_max;
-+ ts = (backwards) ? ts_min : ts_max;
-+
-+ bool ret = SeekByte(pos);
-+ if (ret)
-+ {
-+ m_iCurrentPts = ConvertTimestamp(ts, m_pFormatContext->streams[defaultStream]->time_base.den,
-+ m_pFormatContext->streams[defaultStream]->time_base.num);
-+ }
-+
-+ return ret;
-+}
-+
- bool CDVDDemuxFFmpeg::SeekByte(int64_t pos)
- {
- CSingleLock lock(m_critSection);
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-index 44e101c..3b0f615 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-@@ -99,6 +99,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- DemuxPacket* Read();
-
- bool SeekTime(int time, bool backwords = false, double* startpts = NULL);
-+ bool SeekTimeDiscont(int64_t pts, bool backwards);
- bool SeekByte(int64_t pos);
- int GetStreamLength();
- CDemuxStream* GetStream(int iStreamId);
-@@ -153,5 +154,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- AVPacket pkt; // packet ffmpeg returned
- int result; // result from av_read_packet
- }m_pkt;
-+
-+ bool m_bPtsWrap, m_bPtsWrapChecked;
-+ int64_t m_iStartTime, m_iMaxTime, m_iEndTime;
- };
-
---
-1.9.3
-
-
-From d976c334c57f17e91c35a43af189ee43ffcfb56a Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Tue, 2 Oct 2012 13:02:10 +0200
-Subject: [PATCH 16/35] 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 767f6bd..f905008 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-@@ -1054,13 +1054,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
-
- #ifdef HAS_VIDEO_PLAYBACK
- double config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate;
-+ double render_framerate = g_graphicsContext.GetFPS();
-+ if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") == ADJUST_REFRESHRATE_OFF)
-+ render_framerate = config_framerate;
- /* check so that our format or aspect has changed. if it has, reconfigure renderer */
- if (!g_renderManager.IsConfigured()
- || ( m_output.width != pPicture->iWidth )
- || ( m_output.height != pPicture->iHeight )
- || ( m_output.dwidth != pPicture->iDisplayWidth )
- || ( m_output.dheight != pPicture->iDisplayHeight )
-- || ( m_output.framerate != config_framerate )
-+ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 && render_framerate != config_framerate)
- || ( m_output.color_format != (unsigned int)pPicture->format )
- || ( m_output.extended_format != pPicture->extended_format )
- || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified
---
-1.9.3
-
-
-From abb0d4888fd5467b44e67d2050d06f33eb7bb2f3 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Thu, 11 Oct 2012 12:05:50 +0200
-Subject: [PATCH 17/35] vdpau: advanced settings for auto deinterlacing
-
----
- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++----
- xbmc/settings/AdvancedSettings.cpp | 4 ++++
- xbmc/settings/AdvancedSettings.h | 2 ++
- 3 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-index e58681b..3f87a7d 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-@@ -1970,10 +1970,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */)
- if (method == VS_INTERLACEMETHOD_AUTO)
- {
- int deint = -1;
--// if (m_config.outHeight >= 720)
--// deint = g_advancedSettings.m_videoVDPAUdeintHD;
--// else
--// deint = g_advancedSettings.m_videoVDPAUdeintSD;
-+ if (m_config.outHeight >= 720)
-+ deint = g_advancedSettings.m_videoVDPAUdeintHD;
-+ else
-+ deint = g_advancedSettings.m_videoVDPAUdeintSD;
-
- if (deint != -1)
- {
-diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
-index 6835504..7d50649 100644
---- a/xbmc/settings/AdvancedSettings.cpp
-+++ b/xbmc/settings/AdvancedSettings.cpp
-@@ -157,6 +157,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;
-@@ -596,6 +598,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
- 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);
-+ 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 c57a9fb..6c505a8 100644
---- a/xbmc/settings/AdvancedSettings.h
-+++ b/xbmc/settings/AdvancedSettings.h
-@@ -163,6 +163,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
- int m_videoPercentSeekBackwardBig;
- CStdString m_videoPPFFmpegDeint;
- CStdString m_videoPPFFmpegPostProc;
-+ int m_videoVDPAUdeintHD;
-+ int m_videoVDPAUdeintSD;
- bool m_videoVDPAUtelecine;
- bool m_videoVDPAUdeintSkipChromaHD;
- bool m_musicUseTimeSeeking;
---
-1.9.3
-
-
-From 4c23dd583f32e1e9a4327ccc910873163628cb9e Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Fri, 2 Nov 2012 13:20:03 +0100
-Subject: [PATCH 18/35] 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 be6603a..6ff2400 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 1b2f820..018f4f7 100644
---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
-@@ -1596,11 +1596,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
-@@ -1619,7 +1621,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));
- }
- }
- }
-@@ -2068,7 +2070,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");
-@@ -2204,9 +2206,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();
- }
-
-@@ -2222,7 +2225,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
-@@ -3120,7 +3124,7 @@ void CDVDPlayer::UpdateClockMaster()
- }
- }
-
--void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
-+void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync)
- {
- double startpts;
- if(accurate)
-@@ -3132,19 +3136,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;
-
-@@ -3188,7 +3196,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 bf73d27..91f63c0 100644
---- a/xbmc/cores/dvdplayer/DVDPlayer.h
-+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
-@@ -302,7 +302,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();
-@@ -355,8 +355,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 f905008..3eb6315 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-@@ -1475,7 +1475,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;
-@@ -1574,6 +1574,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts)
- int iDroppedPics = -1;
- int iBufferLevel;
-
-+ m_droppingStats.m_lastPts = pts;
-+
- // get decoder stats
- if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iDroppedPics))
- iDecoderPts = pts;
-diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-index 1cca436..e8e382a 100644
---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
-@@ -51,6 +51,7 @@ class CDroppingStats
- double m_totalGain;
- double m_lastDecoderPts;
- double m_lastRenderPts;
-+ double m_lastPts;
- unsigned int m_lateFrames;
- unsigned int m_dropRequests;
- };
---
-1.9.3
-
-
-From bb97ddfbeecb72e6067b13bce8f517819cfbe8a3 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Thu, 28 Mar 2013 15:18:53 +0100
-Subject: [PATCH 19/35] 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 80fe7c1..31b432f 100644
---- a/xbmc/cores/omxplayer/OMXPlayer.cpp
-+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp
-@@ -2548,7 +2548,8 @@ void COMXPlayer::HandleMessages()
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true));
-
- m_playSpeed = speed;
-- m_caching = CACHESTATE_DONE;
-+ if (m_caching != CACHESTATE_PVR && m_playSpeed != DVD_PLAYSPEED_NORMAL)
-+ m_caching = CACHESTATE_DONE;
- m_clock.SetSpeed(speed);
- m_av_clock.OMXSetSpeed(speed);
- m_av_clock.OMXPause();
---
-1.9.3
-
-
-From 337b26bc138f08f17481b4c299d95dfc25a08eb9 Mon Sep 17 00:00:00 2001
-From: xbmc
-Date: Thu, 28 Mar 2013 20:50:59 +0100
-Subject: [PATCH 20/35] 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 748b529..bb28233 100644
---- a/xbmc/Application.cpp
-+++ b/xbmc/Application.cpp
-@@ -2299,10 +2299,11 @@ void CApplication::Render()
- if (frameTime < singleFrameTime)
- Sleep(singleFrameTime - frameTime);
- }
-- m_lastFrameTime = XbmcThreads::SystemClockMillis();
-
- if (flip)
- g_graphicsContext.Flip(dirtyRegions);
-+
-+ m_lastFrameTime = XbmcThreads::SystemClockMillis();
- CTimeUtils::UpdateFrameTime(flip);
-
- g_renderManager.UpdateResolution();
---
-1.9.3
-
-
-From 02b1fb56e7a8c2ccd2ad9ae141bd8ec94cfe1240 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Tue, 11 Jun 2013 16:20:29 +0200
-Subject: [PATCH 21/35] renderer: allow some lateness within vblank interval
-
----
- xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++--
- xbmc/cores/VideoRenderers/RenderManager.h | 1 +
- 2 files changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
-index f4b381e..5e9f666 100644
---- a/xbmc/cores/VideoRenderers/RenderManager.cpp
-+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
-@@ -380,6 +380,8 @@ void CXBMCRenderManager::FrameFinish()
- if(g_graphicsContext.IsFullScreenVideo())
- WaitPresentTime(m.timestamp);
-
-+ m_clock_framefinish = GetPresentTime();
-+
- { CSingleLock lock(m_presentlock);
-
- if(m_presentstep == PRESENT_FRAME)
-@@ -1032,6 +1034,12 @@ void CXBMCRenderManager::PrepareNextRender()
-
- double clocktime = GetPresentTime();
- double frametime = 1.0 / GetMaximumFPS();
-+ double correction = 0.0;
-+ int fps = g_VideoReferenceClock.GetRefreshRate();
-+ if((fps > 0) && g_graphicsContext.IsFullScreenVideo() && (clocktime != m_clock_framefinish))
-+ {
-+ correction = frametime;
-+ }
-
- /* see if any future queued frames are already due */
- std::deque::reverse_iterator curr, prev;
-@@ -1040,8 +1048,8 @@ void CXBMCRenderManager::PrepareNextRender()
- ++prev;
- while (prev != m_queued.rend())
- {
-- if(clocktime > m_Queue[*prev].timestamp /* previous frame is late */
-- && clocktime > m_Queue[*curr].timestamp - frametime) /* selected frame is close to it's display time */
-+ if(clocktime > m_Queue[*prev].timestamp + correction /* previous frame is late */
-+ && clocktime > m_Queue[*curr].timestamp - frametime + correction) /* selected frame is close to it's display time */
- break;
- ++curr;
- ++prev;
-diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
-index 949c652b..d84ff6c 100644
---- a/xbmc/cores/VideoRenderers/RenderManager.h
-+++ b/xbmc/cores/VideoRenderers/RenderManager.h
-@@ -252,6 +252,7 @@ class CXBMCRenderManager
- XbmcThreads::ConditionVariable m_presentevent;
- CCriticalSection m_presentlock;
- CEvent m_flushEvent;
-+ double m_clock_framefinish;
-
-
- OVERLAY::CRenderer m_overlays;
---
-1.9.3
-
-
-From d43d32bd23616abac9e76713bf0c4bf71661c9dd Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Thu, 25 Jul 2013 17:18:13 +0200
-Subject: [PATCH 22/35] 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 2f71051..a824056 100644
---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
-+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
-@@ -32,8 +32,8 @@ using namespace ActiveAE;
-
- #include "utils/TimeUtils.h"
-
--#define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds
--#define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds
-+#define MAX_CACHE_LEVEL 0.4 // total cache time of stream in seconds
-+#define MAX_WATER_LEVEL 0.2 // buffered time after stream stages in seconds
- #define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds
-
- void CEngineStats::Reset(unsigned int sampleRate)
---
-1.9.3
-
-
-From b32c6b6c720383e8f87137508d196fce0ebbe058 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Sun, 4 Aug 2013 10:11:16 +0200
-Subject: [PATCH 23/35] Revert "vdpau: comment some features that will be added
- later"
-
-This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf.
----
- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 12 ++++--------
- 1 file changed, 4 insertions(+), 8 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-index 3f87a7d..f7418e8 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
-@@ -1097,8 +1097,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame)
- m_bufferStats.IncDecoded();
- m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic));
-
-- //TODO
-- // m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC);
-+ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC);
- }
-
- int retval = 0;
-@@ -2294,8 +2293,7 @@ void CMixer::InitCycle()
- int flags;
- uint64_t latency;
- m_config.stats->GetParams(latency, flags);
-- // TODO
-- if (0) //flags & DVP_FLAG_NO_POSTPROC)
-+ if (flags & DVP_FLAG_NO_POSTPROC)
- SetPostProcFeatures(false);
- else
- SetPostProcFeatures(true);
-@@ -2307,8 +2305,7 @@ void CMixer::InitCycle()
- bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED;
- m_SeenInterlaceFlag |= interlaced;
-
-- // TODO
-- if (//!(flags & DVP_FLAG_NO_POSTPROC) &&
-+ if (!(flags & DVP_FLAG_NO_POSTPROC) &&
- (mode == VS_DEINTERLACEMODE_FORCE ||
- (mode == VS_DEINTERLACEMODE_AUTO && interlaced)))
- {
-@@ -2330,8 +2327,7 @@ void CMixer::InitCycle()
- m_config.stats->SetCanSkipDeint(true);
- }
-
-- // TODO
-- if (0) //m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT)
-+ if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT)
- {
- m_mixersteps = 1;
- }
---
-1.9.3
-
-
-From a0300251e43a107fdfac49f59e6456512f0de77a Mon Sep 17 00:00:00 2001
-From: Marcel Groothuis
-Date: Thu, 5 Dec 2013 22:02:50 +0100
-Subject: [PATCH 24/35] 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 49eff5c..4d4be02 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();
-@@ -388,13 +390,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)
-@@ -414,6 +415,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();
-
-@@ -467,7 +471,7 @@ void CDVDDemuxFFmpeg::Reset()
- {
- CDVDInputStream* pInputStream = m_pInput;
- Dispose();
-- Open(pInputStream);
-+ Open(pInputStream, m_streaminfo);
- }
-
- void CDVDDemuxFFmpeg::Flush()
-@@ -662,25 +666,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)
- {
-@@ -1623,3 +1634,101 @@ bool CDVDDemuxFFmpeg::IsProgramChange()
- }
- return false;
- }
-+
-+void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt)
-+{
-+ AVStream *st = m_pFormatContext->streams[pkt->stream_index];
-+ CDemuxStream *stream = GetStreamInternal(pkt->stream_index);
-+
-+ // if the stream is new, tell ffmpeg to parse the stream
-+ if (!stream && !st->parser)
-+ {
-+ st->need_parsing = AVSTREAM_PARSE_FULL;
-+ }
-+
-+ // split extradata
-+ if(st->parser && st->parser->parser->split && !st->codec->extradata)
-+ {
-+ int i = st->parser->parser->split(st->codec, pkt->data, pkt->size);
-+ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE)
-+ {
-+ // Found extradata, fill it in. This will cause
-+ // a new stream to be created and used.
-+ st->codec->extradata_size = i;
-+ st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-+ if (st->codec->extradata)
-+ {
-+ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size);
-+ memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);
-+ memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-+ }
-+ else
-+ {
-+ st->codec->extradata_size = 0;
-+ }
-+ }
-+ }
-+
-+ // for video we need a decoder to get desired information into codec context
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
-+ {
-+ // open a decoder, it will be cleared down by ffmpeg on closing the stream
-+ if (!st->codec->codec)
-+ {
-+ const AVCodec* codec;
-+ AVDictionary *thread_opt = NULL;
-+ codec = avcodec_find_decoder(st->codec->codec_id);
-+ // Force thread count to 1 since the h264 decoder will not extract
-+ // SPS and PPS to extradata during multi-threaded decoding
-+ av_dict_set(&thread_opt, "threads", "1", 0);
-+ avcodec_open2(st->codec, codec, &thread_opt);
-+
-+ av_dict_free(&thread_opt);
-+ }
-+
-+ // We don't need to actually decode here
-+ // we just want to transport SPS data into codec context
-+ st->codec->skip_idct = AVDISCARD_ALL;
-+ st->codec->skip_frame = AVDISCARD_ALL;
-+ st->codec->skip_loop_filter = AVDISCARD_ALL;
-+
-+ // We are looking for an IDR frame
-+ AVFrame picture;
-+ memset(&picture, 0, sizeof(AVFrame));
-+ picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE;
-+ picture.pkt_pos = -1;
-+ picture.key_frame = 1;
-+ picture.format = -1;
-+
-+ int got_picture = 0;
-+ avcodec_decode_video2(st->codec, &picture, &got_picture, pkt);
-+ }
-+}
-+
-+bool CDVDDemuxFFmpeg::IsVideoReady()
-+{
-+ AVStream *st;
-+ if(m_program != UINT_MAX)
-+ {
-+ for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
-+ {
-+ int idx = m_pFormatContext->programs[m_program]->stream_index[i];
-+ st = m_pFormatContext->streams[idx];
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
-+ return false;
-+ }
-+ }
-+ else
-+ {
-+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
-+ {
-+ st = m_pFormatContext->streams[i];
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-+ (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
-+ return false;
-+ }
-+ }
-+ return true;
-+}
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-index 3b0f615..083182e 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-@@ -88,7 +88,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- CDVDDemuxFFmpeg();
- virtual ~CDVDDemuxFFmpeg();
-
-- bool Open(CDVDInputStream* pInput);
-+ bool Open(CDVDInputStream* pInput, bool streaminfo = true);
- void Dispose();
- void Reset();
- void Flush();
-@@ -127,6 +127,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- CDemuxStream* GetStreamInternal(int iStreamId);
- void CreateStreams(unsigned int program = UINT_MAX);
- void DisposeStreams();
-+ void ParsePacket(AVPacket *pkt);
-+ bool IsVideoReady();
-
- AVDictionary *GetFFMpegOptionsFromURL(const CURL &url);
- double ConvertTimestamp(int64_t pts, int den, int num);
-@@ -157,5 +159,6 @@ class CDVDDemuxFFmpeg : public CDVDDemux
-
- bool m_bPtsWrap, m_bPtsWrapChecked;
- int64_t m_iStartTime, m_iMaxTime, m_iEndTime;
-+ bool m_streaminfo;
- };
-
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-index ca689d0..f383563 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-@@ -99,26 +99,31 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
- }
- #endif
-
-+ bool streaminfo = true; /* Look for streams before playback */
- if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER))
- {
- CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream;
- CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream();
-+
-+ /* Don't parse the streaminfo for live streams to reduce the channel switch time */
-+ bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels");
-+ streaminfo = !liveStream;
-+
- if(pOtherStream)
- {
- /* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */
- if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
- {
- auto_ptr demuxer(new CDVDDemuxFFmpeg());
-- if(demuxer->Open(pOtherStream))
-+ if(demuxer->Open(pOtherStream, streaminfo))
- return demuxer.release();
- else
- return NULL;
- }
- }
-
-- std::string filename = pInputStream->GetFileName();
- /* Use PVR demuxer only for live streams */
-- if (filename.substr(0, 14) == "pvr://channels")
-+ if (liveStream)
- {
- boost::shared_ptr client;
- if (g_PVRClients->GetPlayingClient(client) &&
-@@ -134,7 +139,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
- }
-
- auto_ptr demuxer(new CDVDDemuxFFmpeg());
-- if(demuxer->Open(pInputStream))
-+ if(demuxer->Open(pInputStream, streaminfo))
- return demuxer.release();
- else
- return NULL;
---
-1.9.3
-
-
-From cffbdb13512718b083e6e49d7625efefcff1dc7c Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Thu, 14 Nov 2013 20:35:04 +0100
-Subject: [PATCH 25/35] 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 4d4be02..56eaccc 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-@@ -386,6 +386,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;
-@@ -414,6 +421,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;
-@@ -1670,7 +1683,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
-@@ -1732,3 +1745,19 @@ bool CDVDDemuxFFmpeg::IsVideoReady()
- }
- return true;
- }
-+
-+void CDVDDemuxFFmpeg::ResetVideoStreams()
-+{
-+ AVStream *st;
-+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
-+ {
-+ st = m_pFormatContext->streams[i];
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-+ {
-+ if (st->codec->extradata)
-+ m_dllAvUtil.av_free(st->codec->extradata);
-+ st->codec->extradata = NULL;
-+ st->codec->width = 0;
-+ }
-+ }
-+}
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-index 083182e..26ee264 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-@@ -129,6 +129,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- void DisposeStreams();
- void ParsePacket(AVPacket *pkt);
- bool IsVideoReady();
-+ void ResetVideoStreams();
-
- AVDictionary *GetFFMpegOptionsFromURL(const CURL &url);
- double ConvertTimestamp(int64_t pts, int den, int num);
---
-1.9.3
-
-
-From 6db875e37a4c23952ed114482ab4ec1e57941ba5 Mon Sep 17 00:00:00 2001
-From: Wolfgang Haupt
-Date: Thu, 5 Dec 2013 22:11:57 +0100
-Subject: [PATCH 26/35] DVDFactoryDemuxer: skip streaminfo for udp tcp and
- pvr-channels
-
----
- .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 14 ++++++---
- xbmc/utils/URIUtils.cpp | 35 ++++++++++++++++++++++
- xbmc/utils/URIUtils.h | 4 +++
- 3 files changed, 49 insertions(+), 4 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-index f383563..d6580fd 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp
-@@ -105,9 +105,9 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
- CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream;
- CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream();
-
-- /* Don't parse the streaminfo for live streams to reduce the channel switch time */
-- bool liveStream = (pInputStream->GetFileName().substr(0, 14) == "pvr://channels");
-- streaminfo = !liveStream;
-+ /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */
-+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName());
-+ streaminfo = !useFastswitch;
-
- if(pOtherStream)
- {
-@@ -123,7 +123,7 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
- }
-
- /* Use PVR demuxer only for live streams */
-- if (liveStream)
-+ if (URIUtils::IsPVRChannel(pInputStream->GetFileName()))
- {
- boost::shared_ptr client;
- if (g_PVRClients->GetPlayingClient(client) &&
-@@ -138,6 +138,12 @@ CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream)
- }
- }
-
-+ if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
-+ {
-+ bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName());
-+ streaminfo = !useFastswitch;
-+ }
-+
- auto_ptr demuxer(new CDVDDemuxFFmpeg());
- if(demuxer->Open(pInputStream, streaminfo))
- return demuxer.release();
-diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
-index fd2eb5a..22932b7 100644
---- a/xbmc/utils/URIUtils.cpp
-+++ b/xbmc/utils/URIUtils.cpp
-@@ -788,6 +788,36 @@ bool URIUtils::IsFTP(const CStdString& strFile)
- StringUtils::StartsWithNoCase(strFile2, "ftps:");
- }
-
-+bool URIUtils::IsUDP(const CStdString& strFile)
-+{
-+ CStdString strFile2(strFile);
-+
-+ if (IsStack(strFile))
-+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
-+
-+ return StringUtils::StartsWithNoCase(strFile2, "udp:");
-+}
-+
-+bool URIUtils::IsTCP(const CStdString& strFile)
-+{
-+ CStdString strFile2(strFile);
-+
-+ if (IsStack(strFile))
-+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
-+
-+ return StringUtils::StartsWithNoCase(strFile2, "tcp:");
-+}
-+
-+bool URIUtils::IsPVRChannel(const CStdString& strFile)
-+{
-+ CStdString strFile2(strFile);
-+
-+ if (IsStack(strFile))
-+ strFile2 = CStackDirectory::GetFirstStackedFile(strFile);
-+
-+ return StringUtils::StartsWithNoCase(strFile2, "pvr://channels");
-+}
-+
- bool URIUtils::IsDAV(const CStdString& strFile)
- {
- CStdString strFile2(strFile);
-@@ -1284,3 +1314,8 @@ bool URIUtils::UpdateUrlEncoding(std::string &strFilename)
- strFilename = newFilename;
- return true;
- }
-+
-+bool URIUtils::IsUsingFastSwitch(const CStdString& strFile)
-+{
-+ return IsUDP(strFile) || IsTCP(strFile) || IsPVRChannel(strFile);
-+}
-diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h
-index b94e94c..b45630f 100644
---- a/xbmc/utils/URIUtils.h
-+++ b/xbmc/utils/URIUtils.h
-@@ -88,6 +88,8 @@ class URIUtils
- static bool IsDOSPath(const CStdString &path);
- static bool IsDVD(const CStdString& strFile);
- static bool IsFTP(const CStdString& strFile);
-+ static bool IsUDP(const CStdString& strFile);
-+ static bool IsTCP(const CStdString& strFile);
- static bool IsHD(const CStdString& strFileName);
- static bool IsHDHomeRun(const CStdString& strFile);
- static bool IsSlingbox(const CStdString& strFile);
-@@ -127,6 +129,8 @@ class URIUtils
- static bool IsAndroidApp(const CStdString& strFile);
- static bool IsLibraryFolder(const CStdString& strFile);
- static bool IsLibraryContent(const std::string& strFile);
-+ static bool IsPVRChannel(const CStdString& strFile);
-+ static bool IsUsingFastSwitch(const CStdString& strFile);
-
- static void AddSlashAtEnd(std::string& strFolder);
- static bool HasSlashAtEnd(const std::string& strFile, bool checkURL = false);
---
-1.9.3
-
-
-From 9ab279173cd4b4b750028f2ef3f4bd1a61a38bf5 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Tue, 28 Jan 2014 08:43:29 +0100
-Subject: [PATCH 27/35] squash fast switch
-
----
- .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 23 ++++++++++++++--------
- 1 file changed, 15 insertions(+), 8 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-index 56eaccc..d0f13a1 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-@@ -1722,15 +1722,19 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt)
- bool CDVDDemuxFFmpeg::IsVideoReady()
- {
- AVStream *st;
-+ bool hasVideo = false;
- if(m_program != UINT_MAX)
- {
- for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
- {
- int idx = m_pFormatContext->programs[m_program]->stream_index[i];
- st = m_pFormatContext->streams[idx];
-- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
-- return false;
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-+ {
-+ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE)
-+ return true;
-+ hasVideo = true;
-+ }
- }
- }
- else
-@@ -1738,12 +1742,15 @@ bool CDVDDemuxFFmpeg::IsVideoReady()
- for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
- {
- st = m_pFormatContext->streams[i];
-- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-- (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE))
-- return false;
-+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-+ {
-+ if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE)
-+ return true;
-+ hasVideo = true;
-+ }
- }
- }
-- return true;
-+ return !hasVideo;
- }
-
- void CDVDDemuxFFmpeg::ResetVideoStreams()
-@@ -1755,7 +1762,7 @@ void CDVDDemuxFFmpeg::ResetVideoStreams()
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- if (st->codec->extradata)
-- m_dllAvUtil.av_free(st->codec->extradata);
-+ av_free(st->codec->extradata);
- st->codec->extradata = NULL;
- st->codec->width = 0;
- }
---
-1.9.3
-
-
-From 08634b062976edb8f7740b364e66017a1870756d Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Sun, 13 Apr 2014 10:52:26 +0200
-Subject: [PATCH 28/35] squash fast channel
-
----
- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 13 ++++++++++---
- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 1 +
- 2 files changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-index d0f13a1..1aeae2b 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
-@@ -156,6 +156,7 @@ CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux()
- m_pkt.result = -1;
- memset(&m_pkt.pkt, 0, sizeof(AVPacket));
- m_streaminfo = true; /* set to true if we want to look for streams before playback */
-+ m_checkvideo = false;
- }
-
- CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg()
-@@ -386,11 +387,10 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo)
- if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0)
- m_pFormatContext->max_analyze_duration = 500000;
-
-- bool short_analyze = false;
- if (iformat && (strcmp(iformat->name, "mpegts") == 0))
- {
- m_pFormatContext->max_analyze_duration = 500000;
-- short_analyze = true;
-+ m_checkvideo = true;
- }
-
- // we need to know if this is matroska or avi later
-@@ -422,14 +422,17 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo)
- }
- CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__);
-
-- if (short_analyze)
-+ if (m_checkvideo)
- {
- // make sure we start video with an i-frame
- ResetVideoStreams();
- }
- }
- else
-+ {
- m_program = 0;
-+ m_checkvideo = true;
-+ }
-
- // reset any timeout
- m_timeout.SetInfinite();
-@@ -1723,6 +1726,10 @@ bool CDVDDemuxFFmpeg::IsVideoReady()
- {
- AVStream *st;
- bool hasVideo = false;
-+
-+ if(!m_checkvideo)
-+ return true;
-+
- if(m_program != UINT_MAX)
- {
- for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
-diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-index 26ee264..322a3b8 100644
---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h
-@@ -161,5 +161,6 @@ class CDVDDemuxFFmpeg : public CDVDDemux
- bool m_bPtsWrap, m_bPtsWrapChecked;
- int64_t m_iStartTime, m_iMaxTime, m_iEndTime;
- bool m_streaminfo;
-+ bool m_checkvideo;
- };
-
---
-1.9.3
-
-
-From 7110f52260049d39134a6d5e102b67803994371d Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Sun, 22 Dec 2013 14:52:29 +0100
-Subject: [PATCH 29/35] 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 8642922..0988e60 100644
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -314,6 +314,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)
-@@ -441,7 +447,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 1766ce1..abbfcdf 100644
---- a/configure.in
-+++ b/configure.in
-@@ -832,6 +832,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
-@@ -2583,6 +2596,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"
-@@ -2661,6 +2678,7 @@ AC_SUBST(GTEST_CONFIGURED)
- AC_SUBST(USE_DOXYGEN)
- AC_SUBST(USE_PVR_ADDONS)
- AC_SUBST(UPNP_DEFINES)
-+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 baebb4d..dacbbd6 100644
---- a/xbmc/DllPaths_generated.h.in
-+++ b/xbmc/DllPaths_generated.h.in
-@@ -92,4 +92,7 @@
- /* xkbcommon */
- #define DLL_PATH_XKBCOMMON "@XKBCOMMON_LIBRARY_SONAME@"
-
-+/* sse4 */
-+#define DLL_PATH_LIBSSE4 "special://xbmcbin/system/libsse4-@ARCH@.so"
-+
- #endif
-diff --git a/xbmc/linux/sse4/CopyFrame.cpp b/xbmc/linux/sse4/CopyFrame.cpp
-new file mode 100644
-index 0000000..6d23d83
---- /dev/null
-+++ b/xbmc/linux/sse4/CopyFrame.cpp
-@@ -0,0 +1,115 @@
-+/*
-+ * Copyright (C) 2005-2013 Team XBMC
-+ * http://xbmc.org
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with XBMC; see the file COPYING. If not, see
-+ * .
-+ *
-+ */
-+
-+#include "smmintrin.h"
-+
-+#define CACHED_BUFFER_SIZE 4096
-+typedef unsigned int UINT;
-+
-+extern "C"
-+{
-+
-+/*
-+ * http://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers
-+ * COPIES VIDEO FRAMES FROM USWC MEMORY TO WB SYSTEM MEMORY VIA CACHED BUFFER
-+ * ASSUMES PITCH IS A MULTIPLE OF 64B CACHE LINE SIZE, WIDTH MAY NOT BE
-+ */
-+void copy_frame( void * pSrc, void * pDest, void * pCacheBlock,
-+ UINT width, UINT height, UINT pitch )
-+{
-+ __m128i x0, x1, x2, x3;
-+ __m128i *pLoad;
-+ __m128i *pStore;
-+ __m128i *pCache;
-+ UINT x, y, yLoad, yStore;
-+ UINT rowsPerBlock;
-+ UINT width64;
-+ UINT extraPitch;
-+
-+
-+ rowsPerBlock = CACHED_BUFFER_SIZE / pitch;
-+ width64 = (width + 63) & ~0x03f;
-+ extraPitch = (pitch - width64) / 16;
-+
-+ pLoad = (__m128i *)pSrc;
-+ pStore = (__m128i *)pDest;
-+
-+ // COPY THROUGH 4KB CACHED BUFFER
-+ for( y = 0; y < height; y += rowsPerBlock )
-+ {
-+ // ROWS LEFT TO COPY AT END
-+ if( y + rowsPerBlock > height )
-+ rowsPerBlock = height - y;
-+
-+ pCache = (__m128i *)pCacheBlock;
-+
-+ _mm_mfence();
-+
-+ // LOAD ROWS OF PITCH WIDTH INTO CACHED BLOCK
-+ for( yLoad = 0; yLoad < rowsPerBlock; yLoad++ )
-+ {
-+ // COPY A ROW, CACHE LINE AT A TIME
-+ for( x = 0; x < pitch; x +=64 )
-+ {
-+ x0 = _mm_stream_load_si128( pLoad +0 );
-+ x1 = _mm_stream_load_si128( pLoad +1 );
-+ x2 = _mm_stream_load_si128( pLoad +2 );
-+ x3 = _mm_stream_load_si128( pLoad +3 );
-+
-+ _mm_store_si128( pCache +0, x0 );
-+ _mm_store_si128( pCache +1, x1 );
-+ _mm_store_si128( pCache +2, x2 );
-+ _mm_store_si128( pCache +3, x3 );
-+
-+ pCache += 4;
-+ pLoad += 4;
-+ }
-+ }
-+
-+ _mm_mfence();
-+
-+ pCache = (__m128i *)pCacheBlock;
-+
-+ // STORE ROWS OF FRAME WIDTH FROM CACHED BLOCK
-+ for( yStore = 0; yStore < rowsPerBlock; yStore++ )
-+ {
-+ // copy a row, cache line at a time
-+ for( x = 0; x < width64; x +=64 )
-+ {
-+ x0 = _mm_load_si128( pCache );
-+ x1 = _mm_load_si128( pCache +1 );
-+ x2 = _mm_load_si128( pCache +2 );
-+ x3 = _mm_load_si128( pCache +3 );
-+
-+ _mm_stream_si128( pStore, x0 );
-+ _mm_stream_si128( pStore +1, x1 );
-+ _mm_stream_si128( pStore +2, x2 );
-+ _mm_stream_si128( pStore +3, x3 );
-+
-+ pCache += 4;
-+ pStore += 4;
-+ }
-+
-+ pCache += extraPitch;
-+ pStore += extraPitch;
-+ }
-+ }
-+}
-+}
-diff --git a/xbmc/linux/sse4/DllLibSSE4.h b/xbmc/linux/sse4/DllLibSSE4.h
-new file mode 100644
-index 0000000..01424ac
---- /dev/null
-+++ b/xbmc/linux/sse4/DllLibSSE4.h
-@@ -0,0 +1,43 @@
-+#pragma once
-+/*
-+ * Copyright (C) 2005-2013 Team XBMC
-+ * http://xbmc.org
-+ *
-+ * This Program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This Program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with XBMC; see the file COPYING. If not, see
-+ * .
-+ *
-+ */
-+
-+#include "DynamicDll.h"
-+
-+extern "C" {
-+
-+}
-+
-+class DllLibSSE4Interface
-+{
-+public:
-+ virtual ~DllLibSSE4Interface() {}
-+ virtual void copy_frame(void * pSrc, void * pDest, void * pCacheBlock, UINT width, UINT height, UINT pitch) = 0;
-+};
-+
-+class DllLibSSE4 : public DllDynamic, DllLibSSE4Interface
-+{
-+ DECLARE_DLL_WRAPPER(DllLibSSE4, DLL_PATH_LIBSSE4)
-+ DEFINE_METHOD6(void, copy_frame, (void *p1, void *p2, void *p3, UINT p4, UINT p5, UINT p6))
-+
-+ BEGIN_METHOD_RESOLVE()
-+ RESOLVE_METHOD(copy_frame)
-+ END_METHOD_RESOLVE()
-+};
-diff --git a/xbmc/linux/sse4/Makefile.in b/xbmc/linux/sse4/Makefile.in
-new file mode 100644
-index 0000000..45aa826
---- /dev/null
-+++ b/xbmc/linux/sse4/Makefile.in
-@@ -0,0 +1,20 @@
-+ARCH=@ARCH@
-+DEFINES+=
-+CXXFLAGS=-fPIC -msse4.1
-+LIBNAME=libsse4
-+OBJS=CopyFrame.o
-+
-+LIB_SHARED=@abs_top_srcdir@/system/$(LIBNAME)-$(ARCH).so
-+
-+all: $(LIB_SHARED)
-+
-+$(LIB_SHARED): $(OBJS)
-+ $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS)
-+
-+CLEAN_FILES = \
-+ $(LIB_SHARED) \
-+
-+DISTCLEAN_FILES= \
-+ Makefile \
-+
-+include ../../../Makefile.include
---
-1.9.3
-
-
-From 1cb3a7dbbf78eb6c7967700fc33806e33265ff6f Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Thu, 19 Dec 2013 15:36:11 +0100
-Subject: [PATCH 30/35] vaapi: option to enable sw filters
-
----
- language/English/strings.po | 17 ++-
- system/settings/settings.xml | 15 ++
- xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +-
- xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp | 1 +
- .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 2 +
- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 71 ++++++++--
- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 4 +
- xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 152 +++++++++++++++++++++
- xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 31 +++++
- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 30 ++--
- 10 files changed, 290 insertions(+), 37 deletions(-)
-
-diff --git a/language/English/strings.po b/language/English/strings.po
-index fb26ead..c6822b1 100755
---- a/language/English/strings.po
-+++ b/language/English/strings.po
-@@ -6162,7 +6162,13 @@ msgctxt "#13456"
- msgid "Hardware accelerated"
- msgstr ""
-
--#empty strings from id 13457 to 13499
-+#. Option for video related setting #13454: sw filter
-+#: system/settings/settings.xml
-+msgctxt "#13457"
-+msgid "Use SW Filter for VAAPI"
-+msgstr ""
-+
-+#empty strings from id 13458 to 13499
-
- #: system/settings/settings.xml
- msgctxt "#13500"
-@@ -15279,7 +15285,14 @@ msgctxt "#36431"
- msgid "Defines whether video decoding should be performed in software (requires more CPU) or with hardware acceleration where possible."
- msgstr ""
-
--#empty strings from id 36432 to 36499
-+#. Description for video related setting #13457: vaapi sw filter
-+#: system/settings/settings.xml
-+msgctxt "#36432"
-+msgid "This option enables the deinterlacing methods available for software decoding. It gives the possiblity to use high quality deinterlacers in combination with VAAPI."
-+msgstr ""
-+
-+#empty strings from id 36433 to 36499
-+
- #end reservation
-
- #: system/settings/settings.xml
-diff --git a/system/settings/settings.xml b/system/settings/settings.xml
-index 391bcee..c0f64ab 100644
---- a/system/settings/settings.xml
-+++ b/system/settings/settings.xml
-@@ -715,6 +715,21 @@
- false
-
-
-+
-+ HAVE_LIBVA
-+
-+
-+
-+ true
-+ 1
-+
-+
-+ true
-+
-+ 3
-+ false
-+
-+
-
- HasDXVA2
-
-diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
-index 5e9f666..32ce5bb 100644
---- a/xbmc/cores/VideoRenderers/RenderManager.cpp
-+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
-@@ -988,10 +988,10 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO
- if (mInt == VS_INTERLACEMETHOD_NONE)
- return VS_INTERLACEMETHOD_NONE;
-
-- if(!m_pRenderer->Supports(mInt))
-+ if(m_pRenderer && !m_pRenderer->Supports(mInt))
- mInt = VS_INTERLACEMETHOD_AUTO;
-
-- if (mInt == VS_INTERLACEMETHOD_AUTO)
-+ if (m_pRenderer && mInt == VS_INTERLACEMETHOD_AUTO)
- return m_pRenderer->AutoInterlaceMethod();
-
- return mInt;
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
-index 2958d43..06e0010 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp
-@@ -464,6 +464,7 @@ static const EFormatMap g_format_map[] = {
- , { PIX_FMT_YUV420P16, RENDER_FMT_YUV420P16 }
- , { PIX_FMT_UYVY422, RENDER_FMT_UYVY422 }
- , { PIX_FMT_YUYV422, RENDER_FMT_YUYV422 }
-+, { PIX_FMT_NV12, RENDER_FMT_NV12 }
- , { PIX_FMT_VAAPI_VLD, RENDER_FMT_VAAPI }
- , { PIX_FMT_DXVA2_VLD, RENDER_FMT_DXVA }
- , { PIX_FMT_NONE , RENDER_FMT_NONE }
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-index c5b24d6..3efc007 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
-@@ -323,4 +323,6 @@ class CDVDVideoCodec
- *
- */
- virtual void SetCodecControl(int flags) {}
-+
-+ virtual bool IsInterlaced() { return false; }
- };
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-index c48108f..3b70aa0 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-@@ -38,6 +38,7 @@
- #include "utils/log.h"
- #include "boost/shared_ptr.hpp"
- #include "threads/Atomics.h"
-+#include "settings/MediaSettings.h"
-
- #ifndef TARGET_POSIX
- #define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
-@@ -168,6 +169,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
- m_dts = DVD_NOPTS_VALUE;
- m_started = false;
- m_decoderPts = DVD_NOPTS_VALUE;
-+ m_interlace = false;
- }
-
- CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
-@@ -375,7 +377,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)
-@@ -449,10 +451,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)
-@@ -507,19 +509,60 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p
- || m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3)
- m_started = true;
-
-- if(m_pHardware == NULL)
-+ m_interlace = m_pFrame->interlaced_frame;
-+
-+ if(m_pHardware == NULL || m_pHardware->UseFilter())
- {
-+ if (m_pHardware)
-+ {
-+ m_pFrame->pkt_dts = pts_dtoi(m_dts);
-+ int result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
-+ if (result == VC_BUFFER || result == VC_ERROR)
-+ return result;
-+ m_pHardware->MapFrame(m_pCodecContext, m_pFrame);
-+ m_dts = pts_itod(m_pFrame->pkt_dts);
-+ m_pFrame->pkt_dts = 0;
-+ }
-+
- bool need_scale = std::find( m_formats.begin()
- , m_formats.end()
-- , m_pCodecContext->pix_fmt) == m_formats.end();
-+ , m_pFrame->format) == m_formats.end();
-
- bool need_reopen = false;
-+
-+
-+ // ask codec to do deinterlacing if possible
-+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
-+ EINTERLACEMETHOD mInt = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
-+
-+ unsigned int mFilters = 0;
-+
-+ if (mDeintMode != VS_DEINTERLACEMODE_OFF)
-+ {
-+ if (mDeintMode == VS_DEINTERLACEMODE_FORCE ||
-+ m_pFrame->interlaced_frame)
-+ {
-+ if (mInt == VS_INTERLACEMETHOD_DEINTERLACE)
-+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY;
-+ else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
-+ mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED;
-+
-+ if (mDeintMode == VS_DEINTERLACEMODE_AUTO && mFilters)
-+ mFilters |= CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;
-+ }
-+ }
-+
-+ if (!g_renderManager.Supports(RENDERFEATURE_ROTATION))
-+ mFilters |= CDVDVideoCodec::FILTER_ROTATE;
-+
-+ SetFilters(mFilters);
-+
- if(!m_filters.Equals(m_filters_next))
- need_reopen = true;
-
- if(m_pFilterIn)
- {
-- if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt
-+ if(m_pFilterIn->outputs[0]->format != m_pFrame->format
- || m_pFilterIn->outputs[0]->w != m_pCodecContext->width
- || m_pFilterIn->outputs[0]->h != m_pCodecContext->height)
- need_reopen = true;
-@@ -536,7 +579,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);
-@@ -620,6 +663,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;
-@@ -643,7 +687,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);
-@@ -674,7 +722,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))
-@@ -694,6 +742,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
- pix_fmt = (PixelFormat)m_pFrame->format;
-
- pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);
-+
- return true;
- }
-
-@@ -707,7 +756,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;
-@@ -725,7 +774,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,
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
-index 1a80a48..25f1d25 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();
-@@ -70,6 +72,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec
- virtual unsigned GetAllowedReferences();
- virtual bool GetCodecStats(double &pts, int &droppedPics);
- virtual void SetCodecControl(int flags);
-+ virtual bool IsInterlaced() { return m_interlace; }
-
- bool IsHardwareAllowed() { return !m_bSoftware; }
- IHardwareDecoder * GetHardware() { return m_pHardware; };
-@@ -129,4 +132,5 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec
- int m_skippedDeint;
- bool m_requestSkipDeint;
- int m_codecControlFlags;
-+ bool m_interlace;
- };
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-index 386d50a..315f3ca 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-@@ -26,6 +26,15 @@
- #include
- #include "utils/log.h"
- #include "threads/SingleLock.h"
-+#include "XMemUtils.h"
-+#include "utils/CPUInfo.h"
-+#include "settings/Settings.h"
-+
-+extern "C" {
-+#include "libavutil/avutil.h"
-+}
-+
-+#define CACHED_BUFFER_SIZE 4096
-
- #define CHECK(a) \
- do { \
-@@ -168,12 +177,17 @@ CDecoder::CDecoder()
- m_context = 0;
- m_hwaccel = (vaapi_context*)calloc(1, sizeof(vaapi_context));
- memset(m_surfaces, 0, sizeof(*m_surfaces));
-+ m_frame_buffer = NULL;
-+ m_cache = NULL;
- }
-
- CDecoder::~CDecoder()
- {
- Close();
- free(m_hwaccel);
-+ _aligned_free(m_frame_buffer);
-+ _aligned_free(m_cache);
-+ m_dllSSE4.Unload();
- }
-
- void CDecoder::RelBuffer(uint8_t *data)
-@@ -393,6 +407,11 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su
- if (!EnsureContext(avctx))
- return false;
-
-+ if (avctx->width <= 1920 && avctx->height <= 1088)
-+ CheckUseFilter();
-+ else
-+ m_use_filter = false;
-+
- m_hwaccel->display = m_display->get();
-
- avctx->hwaccel_context = m_hwaccel;
-@@ -475,7 +494,35 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
- return status;
-
- if(frame)
-+ {
-+ if (m_use_filter)
-+ {
-+ VASurfaceID surface = GetSurfaceID(frame);
-+ std::list::iterator it;
-+ for(it = m_surfaces_used.begin(); it != m_surfaces_used.end(); ++it)
-+ {
-+ if((*it)->m_id == surface)
-+ {
-+ m_holder.surface = *it;
-+ break;
-+ }
-+ }
-+ if (it == m_surfaces_used.end())
-+ {
-+ CLog::Log(LOGERROR, "VAAPI::Decode - surface not found");
-+ return VC_ERROR;
-+ }
-+ CProcPic pic;
-+ memset(&pic.frame, 0, sizeof(AVFrame));
-+ av_frame_ref(&pic.frame, frame);
-+ pic.surface = *it;
-+ m_surfaces_proc.push_back(pic);
-+ if (m_surfaces_proc.size() < m_renderbuffers_count)
-+ return VC_BUFFER;
-+ }
-+
- return VC_BUFFER | VC_PICTURE;
-+ }
- else
- return VC_BUFFER;
- }
-@@ -553,4 +600,109 @@ unsigned CDecoder::GetAllowedReferences()
- return m_renderbuffers_count;
- }
-
-+void CDecoder::Reset()
-+{
-+ m_surfaces_proc.clear();
-+}
-+
-+void CDecoder::CheckUseFilter()
-+{
-+ m_use_filter = true;
-+ _aligned_free(m_frame_buffer);
-+ _aligned_free(m_cache);
-+ if (CSettings::Get().GetBool("videoplayer.usevaapiswfilter"))
-+ {
-+ if (!(g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE4))
-+ {
-+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter cpu does not support SSE4");
-+ m_use_filter = false;
-+ return;
-+ }
-+ if (!m_dllSSE4.Load())
-+ {
-+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter failed loading sse4 lib");
-+ m_use_filter = false;
-+ return;
-+ }
-+ VAImage image;
-+ VASurfaceID surface = m_surfaces_free.front()->m_id;
-+ VAStatus status = vaDeriveImage(m_display->get(), surface, &image);
-+ m_use_filter = true;
-+ if (status != VA_STATUS_SUCCESS)
-+ {
-+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter vaDeriveImage not supported");
-+ m_use_filter = false;
-+ }
-+ if (image.format.fourcc != VA_FOURCC_NV12)
-+ {
-+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter image format not NV12");
-+ m_use_filter = false;
-+ }
-+ if ((image.pitches[0] % 64) || (image.pitches[1] % 64))
-+ {
-+ CLog::Log(LOGNOTICE,"VAAPI::CheckUseFilter patches no multiple of 64");
-+ m_use_filter = false;
-+ }
-+ if (m_use_filter)
-+ {
-+ m_frame_buffer = (uint8_t*)_aligned_malloc(image.height*image.width*2 + 256, 64);
-+ m_cache = (uint8_t*)_aligned_malloc(CACHED_BUFFER_SIZE, 64);
-+ }
-+ vaDestroyImage(m_display->get(),image.image_id);
-+ }
-+ else
-+ {
-+ m_use_filter = false;
-+ }
-+}
-+
-+bool CDecoder::MapFrame(AVCodecContext* avctx, AVFrame* frame)
-+{
-+ if (m_surfaces_proc.empty())
-+ {
-+ return false;
-+ }
-+ if(frame)
-+ {
-+ CProcPic pic = m_surfaces_proc.front();
-+ m_surfaces_proc.pop_front();
-+ VASurfaceID surface = pic.surface->m_id;
-+ VASurfaceStatus surf_status;
-+ VAImage image;
-+ uint8_t *buf;
-+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status))
-+ while (surf_status != VASurfaceReady)
-+ {
-+ Sleep(1);
-+ CHECK(vaQuerySurfaceStatus(m_display->get(), surface, &surf_status))
-+ }
-+ CHECK(vaDeriveImage(m_display->get(), surface, &image));
-+ CHECK(vaMapBuffer(m_display->get(), image.buf, (void**)&buf))
-+
-+ uint8_t *src, *dst;
-+ src = buf + image.offsets[0];
-+ dst = m_frame_buffer + image.offsets[0];
-+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height, image.pitches[0]);
-+ src = buf + image.offsets[1];
-+ dst = m_frame_buffer + image.offsets[1];
-+ m_dllSSE4.copy_frame(src, dst, m_cache, image.width, image.height/2, image.pitches[1]);
-+
-+ av_frame_unref(frame);
-+ av_frame_move_ref(frame, &pic.frame);
-+
-+ frame->format = AV_PIX_FMT_NV12;
-+ frame->data[0] = m_frame_buffer + image.offsets[0];
-+ frame->linesize[0] = image.pitches[0];
-+ frame->data[1] = m_frame_buffer + image.offsets[1];
-+ frame->linesize[1] = image.pitches[1];
-+ frame->data[2] = NULL;
-+ frame->data[3] = NULL;
-+ frame->pkt_size = image.data_size;
-+
-+ CHECK(vaUnmapBuffer(m_display->get(), image.buf))
-+ CHECK(vaDestroyImage(m_display->get(),image.image_id))
-+ }
-+ return true;
-+}
-+
- #endif
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
-index ec99162..616b124 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h
-@@ -27,9 +27,11 @@
- #include
- #include
- #include
-+#include "linux/sse4/DllLibSSE4.h"
-
- extern "C" {
- #include "libavcodec/vaapi.h"
-+#include "libavcodec/avcodec.h"
- }
-
- namespace VAAPI {
-@@ -102,11 +104,31 @@ struct CHolder
- {}
- };
-
-+struct CProcPic
-+{
-+ AVFrame frame;
-+ CSurfacePtr surface;
-+ CProcPic()
-+ {}
-+ CProcPic(const CProcPic &other)
-+ {
-+ memcpy(&this->frame, &other.frame, sizeof(AVFrame));
-+ surface = other.surface;
-+ }
-+ CProcPic & operator= (const CProcPic &other)
-+ {
-+ memcpy(&this->frame, &other.frame, sizeof(AVFrame));
-+ surface = other.surface;
-+ return *this;
-+ }
-+};
-+
- class CDecoder
- : public CDVDVideoCodecFFmpeg::IHardwareDecoder
- {
- bool EnsureContext(AVCodecContext *avctx);
- bool EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count);
-+ void CheckUseFilter();
- public:
- CDecoder();
- ~CDecoder();
-@@ -115,9 +137,12 @@ class CDecoder
- virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture);
- virtual int Check (AVCodecContext* avctx);
- virtual void Close();
-+ virtual void Reset();
- virtual const std::string Name() { return "vaapi"; }
- virtual CCriticalSection* Section() { if(m_display) return m_display.get(); else return NULL; }
- virtual unsigned GetAllowedReferences();
-+ virtual bool UseFilter() { return m_use_filter; }
-+ virtual bool MapFrame(AVCodecContext* avctx, AVFrame* frame);
-
- int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags);
- void RelBuffer(uint8_t *data);
-@@ -133,14 +158,20 @@ class CDecoder
- int m_refs;
- std::list m_surfaces_used;
- std::list m_surfaces_free;
-+ std::list m_surfaces_proc;
-
- CDisplayPtr m_display;
- VAConfigID m_config;
- VAContextID m_context;
-+ bool m_use_filter;
-+ uint8_t *m_frame_buffer;
-+ uint8_t *m_cache;
-
- vaapi_context *m_hwaccel;
-
- CHolder m_holder; // silly struct to pass data to renderer
-+
-+ DllLibSSE4 m_dllSSE4;
- };
-
- }
-diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
-index 3eb6315..e17c712 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,13 @@ void CDVDPlayerVideo::Process()
- }
-
- if (picture.iRepeatPicture)
-+ {
-+ bool deint = m_pVideoCodec->IsInterlaced();
-+ picture.iDuration = frametime;
-+ if (deint && (frametime <= 0.02*DVD_TIME_BASE))
-+ picture.iDuration *= 2;
- picture.iDuration *= picture.iRepeatPicture + 1;
-+ }
-
- int iResult = OutputPicture(&picture, pts);
-
---
-1.9.3
-
-
-From 9cca95f06d9c4416b6d6aa99c4be3edf049bb16d Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Tue, 28 Jan 2014 10:05:26 +0100
-Subject: [PATCH 31/35] 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 3b70aa0..80915d4 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-@@ -477,6 +477,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;
-@@ -693,8 +701,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
- pDvdVideoPicture->dts = m_dts;
-
- m_dts = DVD_NOPTS_VALUE;
-- if (m_pFrame->reordered_opaque)
-- pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
-+
-+ int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame);
-+ if(bpts != AV_NOPTS_VALUE)
-+ pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;
- else
- pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
-
---
-1.9.3
-
-
-From c72261a920896f3df7bd50464f696e4d2e74d850 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Tue, 28 Jan 2014 17:24:58 +0100
-Subject: [PATCH 32/35] 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 80915d4..ab36704 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
-@@ -704,7 +704,15 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
-
- int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame);
- if(bpts != AV_NOPTS_VALUE)
-+ {
- pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;
-+ if (pDvdVideoPicture->pts == m_decoderPts)
-+ {
-+ pDvdVideoPicture->iRepeatPicture = -0.5;
-+ pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
-+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
-+ }
-+ }
- else
- pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
-
---
-1.9.3
-
-
-From d8f5bf2f3100616d3c47c4e17c8598318d9cb501 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Tue, 11 Feb 2014 18:15:06 +0100
-Subject: [PATCH 33/35] 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 ce67a31..58c8776 100644
---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
-+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
-@@ -263,7 +263,13 @@ unsigned int CActiveAEStream::AddData(uint8_t* const *data, unsigned int offset,
- }
- }
- if (!m_inMsgEvent.WaitMSec(200))
-+ {
-+ double cachetime = GetCacheTime();
-+ CSingleLock lock(m_streamLock);
-+ CLog::Log(LOGWARNING, "CActiveAEStream::AddData - timeout waiting for buffer, paused: %d, cache time: %f, free buffers: %d",
-+ m_paused, cachetime, m_streamFreeBuffers);
- break;
-+ }
- }
- return copied;
- }
---
-1.9.3
-
-
-From a9d54ec6a768420d9582784bfeb39e72c1e9f774 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Sun, 25 May 2014 21:25:31 +0200
-Subject: [PATCH 34/35] squash swfilter
-
----
- xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-index 315f3ca..4452cfb 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-@@ -519,6 +519,8 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
- m_surfaces_proc.push_back(pic);
- if (m_surfaces_proc.size() < m_renderbuffers_count)
- return VC_BUFFER;
-+
-+ return VC_PICTURE;
- }
-
- return VC_BUFFER | VC_PICTURE;
---
-1.9.3
-
-
-From d69f623bea5e2b08ff0ad02fe573188842258164 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker
-Date: Mon, 26 May 2014 08:07:39 +0200
-Subject: [PATCH 35/35] swfilter, squash me too
-
----
- xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-index 4452cfb..befb6d6 100644
---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
-@@ -517,7 +517,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
- av_frame_ref(&pic.frame, frame);
- pic.surface = *it;
- m_surfaces_proc.push_back(pic);
-- if (m_surfaces_proc.size() < m_renderbuffers_count)
-+ if (m_surfaces_proc.size() < m_renderbuffers_count + 1)
- return VC_BUFFER;
-
- return VC_PICTURE;
-@@ -526,7 +526,15 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
- return VC_BUFFER | VC_PICTURE;
- }
- else
-- return VC_BUFFER;
-+ {
-+ if (m_use_filter)
-+ {
-+ if (m_surfaces_proc.size() < m_renderbuffers_count + 1)
-+ return VC_BUFFER;
-+ }
-+ else
-+ return VC_BUFFER;
-+ }
- }
-
- bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture)
---
-1.9.3
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch
deleted file mode 100644
index 3f331b1574..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 4f6188bc2bcee52ab3a150fff336b58c11f8928a Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Sat, 22 Mar 2014 22:18:28 +0200
-Subject: [PATCH] dont set _NET_WM_STATE_FULLSCREEN
-
----
- xbmc/windowing/X11/WinSystemX11.cpp | 6 ------
- 1 files changed, 0 insertions(+), 6 deletions(-)
-
-diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
-index c95f4ec..d12e050 100644
---- a/xbmc/windowing/X11/WinSystemX11.cpp
-+++ b/xbmc/windowing/X11/WinSystemX11.cpp
-@@ -903,12 +903,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
- InputOutput, vi->visual,
- mask, &swa);
-
-- if (fullscreen && hasWM)
-- {
-- Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True);
-- XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
-- }
--
- // define invisible cursor
- Pixmap bitmapNoData;
- XColor black;
---
-1.7.2.5
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.10-disable-minimize.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-995.10-disable-minimize.patch
deleted file mode 100644
index c0fe5a62ab..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.10-disable-minimize.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-commit 17807066bc04cd28bba89fd176d4d0f69ead9728
-Author: Stefan Saraev
-Date: Sat Oct 12 16:18:50 2013 +0300
-
- disable minimize
-
-diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
-index b5d40c0..18bea9d 100644
---- a/xbmc/Application.cpp
-+++ b/xbmc/Application.cpp
-@@ -5448,7 +5448,6 @@ bool CApplication::SwitchToFullScreen()
-
- void CApplication::Minimize()
- {
-- g_Windowing.Minimize();
- }
-
- PLAYERCOREID CApplication::GetCurrentPlayer()
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.12-run-tzdata-setup-on-timezone-change.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-995.12-run-tzdata-setup-on-timezone-change.patch
deleted file mode 100644
index 51a7e52381..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-995.12-run-tzdata-setup-on-timezone-change.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 25be1b385303a8114d7e227ffab52a22de42ccd1 Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Tue, 26 Nov 2013 20:53:08 +0200
-Subject: [PATCH] run tzdata-setup on timezone change
-
----
- xbmc/linux/LinuxTimezone.cpp | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/xbmc/linux/LinuxTimezone.cpp b/xbmc/linux/LinuxTimezone.cpp
-index be7bce6..4000181 100644
---- a/xbmc/linux/LinuxTimezone.cpp
-+++ b/xbmc/linux/LinuxTimezone.cpp
-@@ -158,6 +158,9 @@ void CLinuxTimezone::OnSettingChanged(const CSetting *setting)
- const std::string &settingId = setting->GetId();
- if (settingId == "locale.timezone")
- {
-+ const std::string cmd = std::string("sh /usr/lib/openelec/tzdata-setup ") + ((CSettingString*)setting)->GetValue().c_str();
-+ system(cmd.c_str());
-+
- SetTimezone(((CSettingString*)setting)->GetValue());
-
- CDateTime::ResetTimezoneBias();
---
-1.8.3.2
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch
deleted file mode 100644
index d81adcd3f1..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 9c1dea43c9b9b66c48d057d3c0e44cd4a807e4dc Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Fri, 20 Dec 2013 00:36:34 +0200
-Subject: [PATCH] service addons: use a wrapper to setup systemd
-
----
- xbmc/addons/AddonDatabase.cpp | 3 +++
- xbmc/addons/AddonInstaller.cpp | 10 ++++++++++
- xbmc/addons/AddonInstaller.h | 2 ++
- 3 files changed, 15 insertions(+)
-
-diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp
-index 4202363..105749f 100644
---- a/xbmc/addons/AddonDatabase.cpp
-+++ b/xbmc/addons/AddonDatabase.cpp
-@@ -20,6 +20,7 @@
-
- #include "AddonDatabase.h"
- #include "addons/AddonManager.h"
-+#include "addons/AddonInstaller.h"
- #include "utils/log.h"
- #include "utils/Variant.h"
- #include "utils/StringUtils.h"
-@@ -581,6 +582,7 @@ bool CAddonDatabase::DisableAddon(const CStdString &addonID, bool disable /* = t
- boost::shared_ptr service = boost::dynamic_pointer_cast(addon);
- if (service)
- service->Stop();
-+ CAddonInstaller::Get().CallOEWrapper(addonID, true);
- }
- // restart the pvr manager when disabling a pvr add-on with the pvr manager enabled
- else if (CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false) && addon &&
-@@ -601,6 +603,7 @@ bool CAddonDatabase::DisableAddon(const CStdString &addonID, bool disable /* = t
- // If the addon is a service, start it
- if (CAddonMgr::Get().GetAddon(addonID, addon, ADDON_SERVICE, false) && addon && disabled)
- {
-+ CAddonInstaller::Get().CallOEWrapper(addonID, false);
- boost::shared_ptr service = boost::dynamic_pointer_cast(addon);
- if (service)
- service->Start();
-diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp
-index 8c9f241..d2f4610 100644
---- a/xbmc/addons/AddonInstaller.cpp
-+++ b/xbmc/addons/AddonInstaller.cpp
-@@ -70,6 +70,13 @@ CAddonInstaller &CAddonInstaller::Get()
- return addonInstaller;
- }
-
-+void CAddonInstaller::CallOEWrapper(const std::string& ID, bool disable)
-+{
-+ char cmd[255];
-+ snprintf(cmd, sizeof(cmd), "/usr/lib/openelec/systemd-addon-wrapper %s %d", ID.c_str(), disable);
-+ system(cmd);
-+}
-+
- void CAddonInstaller::OnJobComplete(unsigned int jobID, bool success, CJob* job)
- {
- if (success)
-@@ -586,6 +593,7 @@ bool CAddonInstallJob::OnPreInstall()
- boost::shared_ptr service = boost::dynamic_pointer_cast(addon);
- if (service)
- service->Stop();
-+ CAddonInstaller::Get().CallOEWrapper(m_addon->ID(), true);
- CAddonMgr::Get().RemoveAddon(m_addon->ID()); // remove it
- return running;
- }
-@@ -713,6 +721,7 @@ void CAddonInstallJob::OnPostInstall(bool reloadAddon)
- AddonPtr addon;
- CAddonMgr::Get().GetAddon(m_addon->ID(), addon);
- boost::shared_ptr service = boost::dynamic_pointer_cast(addon);
-+ CAddonInstaller::Get().CallOEWrapper(m_addon->ID(), false);
- if (service)
- service->Start();
- }
-@@ -794,6 +803,7 @@ bool CAddonUnInstallJob::DoWork()
- boost::shared_ptr service = boost::dynamic_pointer_cast(m_addon);
- if (service)
- service->Stop();
-+ CAddonInstaller::Get().CallOEWrapper(m_addon->ID(), true);
- }
-
- AddonPtr repoPtr = CAddonInstallJob::GetRepoForAddon(m_addon);
-diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h
-index 39cab93..2938c7f 100644
---- a/xbmc/addons/AddonInstaller.h
-+++ b/xbmc/addons/AddonInstaller.h
-@@ -29,6 +29,8 @@ class CAddonInstaller : public IJobCallback
- public:
- static CAddonInstaller &Get();
-
-+ void CallOEWrapper(const std::string& ID, bool disable);
-+
- bool IsDownloading() const;
- void GetInstallList(ADDON::VECADDONS &addons) const;
- bool GetProgress(const CStdString &addonID, unsigned int &percent) const;
---
-1.8.3.2
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.03-0001-handle-SIGTERM.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-999.03-0001-handle-SIGTERM.patch
deleted file mode 100644
index 6f86040bf5..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.03-0001-handle-SIGTERM.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From dbc86891d089a2a871be5a8663e8a5a9a1cffb53 Mon Sep 17 00:00:00 2001
-From: Stefan Saraev
-Date: Thu, 5 Jun 2014 18:50:04 +0300
-Subject: [PATCH] handle SIGTERM
-
-In some situations, due to deadlocks or crashes, xbmc fails to exit properly in
-CApplication::Stop(), so g_powerManager.Reboot() / g_powerManager.Powerdown() never gets
-called, that's a big no-no for openelec as our users can't shutdown or reboot.
-There are few addons reported to cause this behaviour: trakkt.tv, watchdog, weather.underground.
-
-I've also noticed that sometimes new threads (FileCache ??) get started AFTER
-CApplication::Stop() is called, delaying shutdown with 1+ minute (2 curl timeoouts?).
-The problem seems to be in CJobManager::CancelJobs() but I am too lame to understand where,
-why, and how to fix it.
-
-To me, it seems best to let systemd handle it. systemd sends SIGTERM, then waits
-TimeoutStopSec=xx seconds then sends SIGKILL,s so dont call g_application.Stop() from
-ApplicationMessenger as it can not be trusted. save the requested exitcode instead
-(that's required for CEC to switch off the tv) and do it from a simple SIGTERM handler instead.
-
-CEC thread has enough time (5 seconds in xbmc.service) to switch of the TV after receiving OnQuit.
-As a side "effect", now guisettings.xml will ALWAYS be saved, even if shutdown / rebooot
-is requested externaly (ssh, 3rdparty script).
----
- xbmc/Application.cpp | 10 ++++++++--
- xbmc/Application.h | 1 +
- xbmc/ApplicationMessenger.cpp | 6 ++++--
- xbmc/XBApplicationEx.cpp | 1 +
- xbmc/XBApplicationEx.h | 1 +
- xbmc/main/main.cpp | 15 +++++++++++++++
- 6 files changed, 30 insertions(+), 4 deletions(-)
-
-diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
-index 7f1b764..4441969 100644
---- a/xbmc/Application.cpp
-+++ b/xbmc/Application.cpp
-@@ -3493,11 +3493,18 @@ bool CApplication::Cleanup()
- }
- }
-
-+void CApplication::SetExitCode(int exitCode)
-+{
-+ // save it for CEC
-+ m_ExitCode = exitCode;
-+ m_ExitCodeSet = true;
-+}
-+
- void CApplication::Stop(int exitCode)
- {
- try
- {
-- CVariant vExitCode(exitCode);
-+ CVariant vExitCode(m_ExitCode);
- CAnnouncementManager::Get().Announce(System, "xbmc", "OnQuit", vExitCode);
-
- SaveFileState(true);
-@@ -3521,7 +3528,6 @@ void CApplication::Stop(int exitCode)
-
- m_bStop = true;
- m_AppFocused = false;
-- m_ExitCode = exitCode;
- CLog::Log(LOGNOTICE, "stop all");
-
- // cancel any jobs from the jobmanager
-diff --git a/xbmc/Application.h b/xbmc/Application.h
-index 2243f15..97fb316 100644
---- a/xbmc/Application.h
-+++ b/xbmc/Application.h
-@@ -149,6 +149,7 @@ public:
- void StartPVRManager(bool bOpenPVRWindow = false);
- void StopPVRManager();
- bool IsCurrentThread() const;
-+ void SetExitCode(int exitCode);
- void Stop(int exitCode);
- void RestartApp();
- void UnloadSkin(bool forReload = false);
-diff --git a/xbmc/ApplicationMessenger.cpp b/xbmc/ApplicationMessenger.cpp
-index 3524e89..54a15da 100644
---- a/xbmc/ApplicationMessenger.cpp
-+++ b/xbmc/ApplicationMessenger.cpp
-@@ -259,13 +259,14 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
-
- case TMSG_POWERDOWN:
- {
-- g_application.Stop(EXITCODE_POWERDOWN);
-+ g_application.SetExitCode(EXITCODE_POWERDOWN);
- g_powerManager.Powerdown();
- }
- break;
-
- case TMSG_QUIT:
- {
-+ g_application.SetExitCode(EXITCODE_QUIT);
- g_application.Stop(EXITCODE_QUIT);
- }
- break;
-@@ -287,7 +288,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
- case TMSG_RESTART:
- case TMSG_RESET:
- {
-- g_application.Stop(EXITCODE_REBOOT);
-+ g_application.SetExitCode(EXITCODE_REBOOT);
- g_powerManager.Reboot();
- }
- break;
-@@ -295,6 +296,7 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
- case TMSG_RESTARTAPP:
- {
- #if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
-+ g_application.SetExitCode(EXITCODE_RESTARTAPP);
- g_application.Stop(EXITCODE_RESTARTAPP);
- #endif
- }
-diff --git a/xbmc/XBApplicationEx.cpp b/xbmc/XBApplicationEx.cpp
-index ad6a145..6058938 100644
---- a/xbmc/XBApplicationEx.cpp
-+++ b/xbmc/XBApplicationEx.cpp
-@@ -40,6 +40,7 @@ CXBApplicationEx::CXBApplicationEx()
- m_bStop = false;
- m_AppFocused = true;
- m_ExitCode = EXITCODE_QUIT;
-+ m_ExitCodeSet = false;
- m_renderGUI = false;
- }
-
-diff --git a/xbmc/XBApplicationEx.h b/xbmc/XBApplicationEx.h
-index c46cba1..ed3f35f 100644
---- a/xbmc/XBApplicationEx.h
-+++ b/xbmc/XBApplicationEx.h
-@@ -40,6 +40,7 @@ public:
- // Variables for timing
- bool m_bStop;
- int m_ExitCode;
-+ bool m_ExitCodeSet;
- bool m_AppFocused;
- bool m_renderGUI;
-
-diff --git a/xbmc/main/main.cpp b/xbmc/main/main.cpp
-index ec86426..ad8fe6e 100644
---- a/xbmc/main/main.cpp
-+++ b/xbmc/main/main.cpp
-@@ -40,9 +40,24 @@
- #include "input/linux/LIRC.h"
- #endif
- #include "XbmcContext.h"
-+#include "Application.h"
-+
-+void xbmc_term_handler(int signum)
-+{
-+ CLog::Log(LOGINFO, "Received SIGTERM...");
-+ if (!g_application.m_ExitCodeSet)
-+ g_application.SetExitCode(EXITCODE_RESTARTAPP);
-+ g_application.Stop(EXITCODE_RESTARTAPP);
-+}
-
- int main(int argc, char* argv[])
- {
-+ // SIGTERM handler
-+ struct sigaction action;
-+ memset(&action, 0, sizeof(struct sigaction));
-+ action.sa_handler = xbmc_term_handler;
-+ sigaction(SIGTERM, &action, NULL);
-+
- // set up some xbmc specific relationships
- XBMC::Context context;
-
---
-1.9.1
-
diff --git a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.90-show_rss-setting_in_standard_group.patch b/packages/mediacenter/xbmc-master/patches/xbmc-master-999.90-show_rss-setting_in_standard_group.patch
deleted file mode 100644
index 50186d7813..0000000000
--- a/packages/mediacenter/xbmc-master/patches/xbmc-master-999.90-show_rss-setting_in_standard_group.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -Naur xbmc-13.alpha-536cf62/system/settings/settings.xml xbmc-13.alpha-536cf62.patch/system/settings/settings.xml
---- xbmc-13.alpha-536cf62/system/settings/settings.xml 2014-01-29 18:31:46.000000000 +0100
-+++ xbmc-13.alpha-536cf62.patch/system/settings/settings.xml 2014-01-31 13:12:46.789297639 +0100
-@@ -91,7 +91,7 @@
-
-
-
-- 1
-+ 0
- true
-
-
diff --git a/packages/mediacenter/xbmc-master/profile.d/02-xbmc.conf b/packages/mediacenter/xbmc-master/profile.d/02-xbmc.conf
deleted file mode 100644
index 882e7d0f0a..0000000000
--- a/packages/mediacenter/xbmc-master/profile.d/02-xbmc.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-# PATH
-for addon in /storage/.xbmc/addons/*/bin /usr/lib/xbmc/addons/*/bin; do
- [ -d "$addon" ] && PATH="$PATH:$addon"
-done
-export PATH
-
-# LD_LIBRARY_PATH
-for addon in /storage/.xbmc/addons/*/lib /usr/lib/xbmc/addons/*/lib; do
- [ -d "$addon" ] && LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$addon"
-done
-export LD_LIBRARY_PATH
diff --git a/packages/mediacenter/xbmc-master/profile.d/03-addons.conf b/packages/mediacenter/xbmc-master/profile.d/03-addons.conf
deleted file mode 100644
index bdd7525920..0000000000
--- a/packages/mediacenter/xbmc-master/profile.d/03-addons.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-oe_setup_addon() {
- if [ ! -z $1 ] ; then
- DEF="/storage/.xbmc/addons/$1/settings-default.xml"
- CUR="/storage/.xbmc/userdata/addon_data/$1/settings.xml"
-
- # copy defaults
- if [ -f "$DEF" -a ! -f "$CUR" ] ; then
- cp "$DEF" "$CUR"
- fi
-
- # parse config
- [ -f "$DEF" ] && eval $(cat "$DEF" | awk -F\" '{print $2"=\""$4"\""}' | sed '/^=/d')
- [ -f "$CUR" ] && eval $(cat "$CUR" | awk -F\" '{print $2"=\""$4"\""}' | sed '/^=/d')
-
- # export some useful variables
- ADDON_DIR="$HOME/.xbmc/addons/$1"
- ADDON_HOME="$HOME/.xbmc/userdata/addon_data/$1"
- ADDON_LOG_FILE="$ADDON_HOME/service.log"
-
- [ ! -d $ADDON_HOME ] && mkdir -p $ADDON_HOME
- fi
-}
diff --git a/packages/mediacenter/xbmc-master/scripts/cputemp b/packages/mediacenter/xbmc-master/scripts/cputemp
deleted file mode 100755
index 1136827f2d..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/cputemp
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/sh
-
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-# inspired by
-# https://github.com/xtranophilist/gnome-shell-extension-cpu-temperature/blob/master/extension.js
-
-TEMP=0
-
-if [ $(basename "$0") = "gputemp" -o "$1" = "gpu" ]; then
- if which lspci >/dev/null; then
- if lspci -n | grep 0300 | grep -q 10de; then
- [ -x /usr/bin/nvidia-smi ] && TEMP=`/usr/bin/nvidia-smi -q -x | grep 'gpu_temp' | awk '{ print $1 }' | sed 's,,,g'`
- fi
- fi
-fi
-
-if [ "$1" = "cpu" -o "$TEMP" = "0" ]; then
- if [ -f /sys/class/hwmon/hwmon1/temp1_input ]; then
- # used on Asus systems (ie. AT5IONT-I)
- TEMP=`cat /sys/class/hwmon/hwmon1/temp1_input`
- elif [ -f /sys/devices/platform/coretemp.0/temp1_input ]; then
- # used with coretemp
- TEMP=`cat /sys/devices/platform/coretemp.0/temp1_input`
- elif [ -f /sys/devices/platform/coretemp.0/temp2_input ]; then
- # used with coretemp
- TEMP=`cat /sys/devices/platform/coretemp.0/temp2_input`
- elif [ -f /sys/bus/acpi/devices/LNXTHERM\:00/thermal_zone/temp ]; then
- # used on some intel systems
- TEMP=`cat /sys/bus/acpi/devices/LNXTHERM\:00/thermal_zone/temp`
- elif [ -f /sys/devices/virtual/thermal/thermal_zone0/temp ]; then
- # used on some intel systems
- TEMP=`cat /sys/devices/virtual/thermal/thermal_zone0/temp`
- elif [ -f /sys/class/hwmon/hwmon0/temp1_input ]; then
- # hwmon for new 2.6.39, 3.0 linux kernels
- TEMP=`cat /sys/class/hwmon/hwmon0/temp1_input`
- elif [ -f /sys/class/hwmon/hwmon0/device/temp1_input ]; then
- # used on AMD systems
- TEMP=`cat /sys/class/hwmon/hwmon0/device/temp1_input`
- elif [ -f /sys/class/hwmon/hwmon0/device/temp2_input ]; then
- # used on ION systems
- TEMP=`cat /sys/class/hwmon/hwmon0/device/temp2_input`
- elif [ -f /sys/class/thermal/thermal_zone0/temp ]; then
- # used on RaspberryPi
- TEMP=`cat /sys/class/thermal/thermal_zone0/temp`
- fi
-
- TEMP="$(( $TEMP / 1000 ))"
-fi
-
-echo "${TEMP} C"
diff --git a/packages/mediacenter/xbmc-master/scripts/setwakeup.sh b/packages/mediacenter/xbmc-master/scripts/setwakeup.sh
deleted file mode 100755
index 76aa3d7c26..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/setwakeup.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-if [ -f /sys/class/rtc/rtc0/wakealarm ]; then
- logger -t setwakeup.sh "### Setting system wakeup time ###"
- echo 0 > /sys/class/rtc/rtc0/wakealarm
- echo $1 > /sys/class/rtc/rtc0/wakealarm
- logger -t setwakeup.sh "### $(cat /proc/driver/rtc) ###"
-fi
diff --git a/packages/mediacenter/xbmc-master/scripts/systemd-addon-wrapper b/packages/mediacenter/xbmc-master/scripts/systemd-addon-wrapper
deleted file mode 100755
index e963c61af9..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/systemd-addon-wrapper
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-if [ ! -d /storage/.config/system.d ] ; then
- mkdir -p /storage/.config/system.d
-fi
-
-if [ -f "/storage/.xbmc/addons/$1/system.d/$1.service" ] ; then
- if [ $2 -eq 1 ] ; then
- # disable = true: cleanup
- systemctl stop "$1.service"
- systemctl disable "/storage/.xbmc/addons/$1/system.d/$1.service"
- else
- # disable = false: setup
- systemctl enable "/storage/.xbmc/addons/$1/system.d/$1.service"
- systemctl start "$1.service"
- fi
-fi
diff --git a/packages/mediacenter/xbmc-master/scripts/xbmc-config b/packages/mediacenter/xbmc-master/scripts/xbmc-config
deleted file mode 100755
index 1ad05bf38e..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/xbmc-config
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-if [ -e /run/lirc/lircd.irtrans ]; then
- XBMC_ARGS="--lircdev /run/lirc/lircd.irtrans"
-else
- XBMC_ARGS="--lircdev /run/lirc/lircd"
-fi
-
-echo "XBMC_ARGS=\"$XBMC_ARGS\"" > /run/openelec/xbmc.conf
diff --git a/packages/mediacenter/xbmc-master/scripts/xbmc-hacks b/packages/mediacenter/xbmc-master/scripts/xbmc-hacks
deleted file mode 100755
index 2fabd47a19..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/xbmc-hacks
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-# hack: make addon-bins executable
- chmod +x /storage/.xbmc/addons/*/bin/*
-
-# hack: update RSSnews.xml in userdata
- if [ -f /storage/.xbmc/userdata/RssFeeds.xml ]; then
- sed -e "s,http://openelec.tv/news?format=feed&type=rss,http://feeds.openelec.tv/news,g" \
- -i /storage/.xbmc/userdata/RssFeeds.xml
- fi
diff --git a/packages/mediacenter/xbmc-master/scripts/xbmc-sources b/packages/mediacenter/xbmc-master/scripts/xbmc-sources
deleted file mode 100755
index 12fa659a8f..0000000000
--- a/packages/mediacenter/xbmc-master/scripts/xbmc-sources
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-. /etc/profile
-
-#
-# setup XBMC sources
-#
-
- if [ ! -f $HOME/.xbmc/userdata/sources.xml ]; then
- if [ -f /usr/share/xbmc/config/sources.xml ]; then
- # include project specific sources
- cp /usr/share/xbmc/config/sources.xml $HOME/.xbmc/userdata
- else
- cat > $HOME/.xbmc/userdata/sources.xml << EOF
-
-
-
-
-
- Music
- $HOME/music/
-
-
-
-
-
- Pictures
- $HOME/pictures/
-
-
-
-EOF
- fi
- fi
-
-#
-# common setup guisettings
-#
-
- if [ ! -f $HOME/.xbmc/userdata/guisettings.xml ] ; then
- echo "" > $HOME/.xbmc/userdata/guisettings.xml
-
- cat >> $HOME/.xbmc/userdata/guisettings.xml << EOF
-
- $HOME/screenshots/
-
-EOF
-
- #
- # include project specific options
- #
-
- if [ -f /usr/share/xbmc/config/guisettings.xml ]; then
- cat /usr/share/xbmc/config/guisettings.xml >> $HOME/.xbmc/userdata/guisettings.xml
- fi
-
- echo "" >> $HOME/.xbmc/userdata/guisettings.xml
- fi
diff --git a/packages/mediacenter/xbmc-master/sleep.d.serial/10-addon-sleep.sh b/packages/mediacenter/xbmc-master/sleep.d.serial/10-addon-sleep.sh
deleted file mode 100755
index e44529791e..0000000000
--- a/packages/mediacenter/xbmc-master/sleep.d.serial/10-addon-sleep.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-. /etc/profile
-
-# see https://wiki.archlinux.org/index.php/Power_Management#Hooks_in_.2Fusr.2Flib.2Fsystemd.2Fsystem-sleep
-
-for script in $HOME/.xbmc/addons/*/sleep.d/*.power; do
- progress "running addon sleep script $script ($@)..."
- sh $script $@
-done
-
-exit 0
\ No newline at end of file
diff --git a/packages/mediacenter/xbmc-master/sleep.d.serial/20-custon-sleep.sh b/packages/mediacenter/xbmc-master/sleep.d.serial/20-custon-sleep.sh
deleted file mode 100755
index 3ad0e0c04e..0000000000
--- a/packages/mediacenter/xbmc-master/sleep.d.serial/20-custon-sleep.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2013 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-. /etc/profile
-
-# see https://wiki.archlinux.org/index.php/Power_Management#Hooks_in_.2Fusr.2Flib.2Fsystemd.2Fsystem-sleep
-
-for script in $HOME/.config/sleep.d/*.power; do
- if [ -f $script ]; then
- progress "running custom sleep script $script ($@)..."
- sh $script $@
- fi
-done
-
-exit 0
\ No newline at end of file
diff --git a/packages/mediacenter/xbmc-master/sleep.d/openelec-sleep.sh b/packages/mediacenter/xbmc-master/sleep.d/openelec-sleep.sh
deleted file mode 100755
index 6b314cd7bd..0000000000
--- a/packages/mediacenter/xbmc-master/sleep.d/openelec-sleep.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-. /etc/profile
-
-run_scripts()
-{
- list_scripts $1
- for script in $SCRIPTS ; do
- progress "running sleep script $script ($1)..."
- sh /usr/lib/systemd/system-sleep.serial/$script $1
- done
-}
-
-list_scripts()
-{
- case $1 in
- pre)
- SCRIPTS=$(ls /usr/lib/systemd/system-sleep.serial/ | sort)
- ;;
- post)
- SCRIPTS=$(ls /usr/lib/systemd/system-sleep.serial/ | sort -r)
- ;;
- esac
-}
-
-run_scripts $1
-
-exit 0
diff --git a/packages/mediacenter/xbmc-master/splash/splash.png b/packages/mediacenter/xbmc-master/splash/splash.png
deleted file mode 100644
index 6b2897b0a1..0000000000
Binary files a/packages/mediacenter/xbmc-master/splash/splash.png and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/splash/splash1.png b/packages/mediacenter/xbmc-master/splash/splash1.png
deleted file mode 100644
index ac0aa0052f..0000000000
Binary files a/packages/mediacenter/xbmc-master/splash/splash1.png and /dev/null differ
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-autostart.service b/packages/mediacenter/xbmc-master/system.d/xbmc-autostart.service
deleted file mode 100644
index 2e98307e0f..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-autostart.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=XBMC user autostart script
-Before=xbmc.service
-After=graphical.target
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=-/bin/sh -c ". /etc/profile; exec /bin/sh /storage/.config/autostart.sh"
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-cleanlogs.service b/packages/mediacenter/xbmc-master/system.d/xbmc-cleanlogs.service
deleted file mode 100644
index 9faab0eec2..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-cleanlogs.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=XBMC clean debug logs
-ConditionKernelCommandLine=!debugging
-ConditionPathExists=!/storage/.cache/debug.openelec
-Before=xbmc.service
-
-[Service]
-Type=oneshot
-ExecStart=-/bin/sh -c 'rm -rf /storage/.xbmc/userdata/addon_data/*/*.log /storage/.xbmc/userdata/addon_data/*/log/*'
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-config.service b/packages/mediacenter/xbmc-master/system.d/xbmc-config.service
deleted file mode 100644
index cb0f33faf8..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-config.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=XBMC configfile writer
-Before=xbmc.service
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=/usr/lib/xbmc/xbmc-config
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-hacks.service b/packages/mediacenter/xbmc-master/system.d/xbmc-hacks.service
deleted file mode 100644
index efb48a6ac3..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-hacks.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=XBMC hacks
-Before=xbmc.service
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=/usr/lib/xbmc/xbmc-hacks
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-halt.service b/packages/mediacenter/xbmc-master/system.d/xbmc-halt.service
deleted file mode 100644
index 16ab30c50e..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-halt.service
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=XBMC halt script
-After=xbmc.service
-Before=systemd-halt.service
-DefaultDependencies=no
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=-/bin/sh /storage/.config/shutdown.sh halt
-RemainAfterExit=yes
-
-[Install]
-WantedBy=halt.target
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-lirc-suspend.service b/packages/mediacenter/xbmc-master/system.d/xbmc-lirc-suspend.service
deleted file mode 100644
index f229b6b193..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-lirc-suspend.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=LIRC sleep hook
-Before=sleep.target
-StopWhenUnneeded=yes
-
-[Service]
-Type=oneshot
-RemainAfterExit=yes
-ExecStart=-/usr/bin/xbmc-send --host=127.0.0.1 -a "LIRC.Stop"
-ExecStop=-/usr/bin/xbmc-send --host=127.0.0.1 -a "LIRC.Start"
-
-[Install]
-WantedBy=sleep.target
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-poweroff.service b/packages/mediacenter/xbmc-master/system.d/xbmc-poweroff.service
deleted file mode 100644
index 8a607da56a..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-poweroff.service
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=XBMC poweroff script
-After=xbmc.service
-Before=systemd-poweroff.service
-DefaultDependencies=no
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=-/bin/sh /storage/.config/shutdown.sh poweroff
-RemainAfterExit=yes
-
-[Install]
-WantedBy=poweroff.target
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-reboot.service b/packages/mediacenter/xbmc-master/system.d/xbmc-reboot.service
deleted file mode 100644
index 7ee1d5dabe..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-reboot.service
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=XBMC reboot script
-After=xbmc.service
-Before=systemd-reboot.service
-DefaultDependencies=no
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=-/bin/sh /storage/.config/shutdown.sh reboot
-RemainAfterExit=yes
-
-[Install]
-WantedBy=reboot.target
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-sources.service b/packages/mediacenter/xbmc-master/system.d/xbmc-sources.service
deleted file mode 100644
index 48e6dfb8a7..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-sources.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=XBMC sources Setup
-Before=xbmc.service
-
-[Service]
-Type=oneshot
-Environment=HOME=/storage
-ExecStart=/usr/lib/xbmc/xbmc-sources
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc-waitonnetwork.service b/packages/mediacenter/xbmc-master/system.d/xbmc-waitonnetwork.service
deleted file mode 100644
index dc27a793ee..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc-waitonnetwork.service
+++ /dev/null
@@ -1,17 +0,0 @@
-[Unit]
-Description=Wait on network
-After=connman.service
-Before=xorg.service fbset.service
-
-ConditionPathExists=/storage/.cache/openelec/network_wait
-
-[Service]
-Type=oneshot
-EnvironmentFile=/storage/.cache/openelec/network_wait
-ExecStartPre=/bin/sh -c 'echo "waiting on Network to come online ... (max. $WAIT_NETWORK_TIME sec.)"
-ExecStart=/usr/bin/cm-online ${WAIT_NETWORK_TIME}
-StandardOutput=tty
-RemainAfterExit=yes
-
-[Install]
-WantedBy=xbmc.service
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc.service b/packages/mediacenter/xbmc-master/system.d/xbmc.service
deleted file mode 100644
index 545d31c62e..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc.service
+++ /dev/null
@@ -1,21 +0,0 @@
-[Unit]
-Description=XBMC Media Center
-After=graphical.target
-Requires=graphical.target
-
-[Service]
-Environment=DISPLAY=:0.0
-Environment=SDL_MOUSE_RELATIVE=0
-Environment=HOME=/storage
-EnvironmentFile=-/run/openelec/xbmc.conf
-EnvironmentFile=-/run/openelec/debug/xbmc.conf
-ExecStart=/bin/sh -c ". /etc/profile; exec /usr/lib/xbmc/xbmc.bin --standalone -fs $XBMC_ARGS $XBMC_DEBUG"
-# keep KillMode=process unless there is no good reason to switch to cgroup
-KillMode=process
-TimeoutStopSec=5
-Restart=always
-RestartSec=2
-StartLimitInterval=0
-
-[Install]
-WantedBy=xbmc.target
diff --git a/packages/mediacenter/xbmc-master/system.d/xbmc.target b/packages/mediacenter/xbmc-master/system.d/xbmc.target
deleted file mode 100644
index 02e0fc0c82..0000000000
--- a/packages/mediacenter/xbmc-master/system.d/xbmc.target
+++ /dev/null
@@ -1,9 +0,0 @@
-[Unit]
-Description=XBMC Mediacenter Interface
-Requires=multi-user.target graphical.target
-After=graphical.target
-Conflicts=rescue.target
-AllowIsolate=yes
-
-[Install]
-Alias=default.target
diff --git a/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc-userdirs.conf b/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc-userdirs.conf
deleted file mode 100644
index 62552cdc49..0000000000
--- a/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc-userdirs.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-d /storage/.xbmc/userdata 0755 root root - -
-d /storage/music 0755 root root - -
-d /storage/pictures 0755 root root - -
-d /storage/tvshows 0755 root root - -
-d /storage/videos 0755 root root - -
-d /storage/screenshots 0755 root root - -
diff --git a/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc.conf b/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc.conf
deleted file mode 100644
index 24bcf7a5b7..0000000000
--- a/packages/mediacenter/xbmc-master/tmpfiles.d/xbmc.conf
+++ /dev/null
@@ -1,19 +0,0 @@
-################################################################################
-# This file is part of OpenELEC - http://www.openelec.tv
-# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv)
-#
-# OpenELEC is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# OpenELEC 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 OpenELEC. If not, see .
-################################################################################
-
-d /run/xbmc 0755 root root - -
diff --git a/projects/ATV/options b/projects/ATV/options
index 5beebc11c5..a71fa07480 100644
--- a/projects/ATV/options
+++ b/projects/ATV/options
@@ -1,8 +1,5 @@
# Name of the Distro to build (full name, without special characters)
DISTRONAME="OpenELEC"
- if [ "$XBMC" = master ]; then
- DISTRONAME="OpenELEC_Helix"
- fi
# short project description
DESCRIPTION="OpenELEC is a fast and userfriendly XBMC Mediacenter distribution."
@@ -119,9 +116,6 @@
# Mediacenter to use (xbmc / no)
MEDIACENTER="xbmc"
- if [ "$XBMC" = master ]; then
- MEDIACENTER="xbmc-master"
- fi
# Skins to install (Confluence)
# Space separated list is supported,
diff --git a/projects/Generic/options b/projects/Generic/options
index 12bcc590d2..676b19f79f 100644
--- a/projects/Generic/options
+++ b/projects/Generic/options
@@ -1,8 +1,5 @@
# Name of the Distro to build (full name, without special characters)
DISTRONAME="OpenELEC"
- if [ "$XBMC" = master ]; then
- DISTRONAME="OpenELEC_Helix"
- fi
# short project description
DESCRIPTION="OpenELEC is a fast and userfriendly XBMC Mediacenter distribution."
@@ -119,9 +116,6 @@
# Mediacenter to use (xbmc / no)
MEDIACENTER="xbmc"
- if [ "$XBMC" = master ]; then
- MEDIACENTER="xbmc-master"
- fi
# Skins to install (Confluence)
# Space separated list is supported,
diff --git a/projects/RPi/options b/projects/RPi/options
index 3c743b69ec..4ed0b43394 100644
--- a/projects/RPi/options
+++ b/projects/RPi/options
@@ -1,8 +1,5 @@
# Name of the Distro to build (full name, without special characters)
DISTRONAME="OpenELEC"
- if [ "$XBMC" = master ]; then
- DISTRONAME="OpenELEC_Helix"
- fi
# short project description
DESCRIPTION="OpenELEC is a fast and userfriendly XBMC Mediacenter distribution."
@@ -119,9 +116,6 @@
# Mediacenter to use (xbmc / no)
MEDIACENTER="xbmc"
- if [ "$XBMC" = master ]; then
- MEDIACENTER="xbmc-master"
- fi
# Skins to install (Confluence)
# Space separated list is supported,
diff --git a/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch b/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch
deleted file mode 100644
index 4d28fc7311..0000000000
--- a/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch
+++ /dev/null
@@ -1,16213 +0,0 @@
-From 35419e975b9616f614faf987889361755b9a49d9 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Thu, 14 Nov 2013 19:48:41 +0000
-Subject: [PATCH 01/82] More efficient infobool expression evaluator
-
-Expession infobools are evaluated at runtime from one or more single infobools
-and a combination of boolean NOT, AND and OR operators. Previously, parsing
-produced a vector of operands (leaf nodes) and operators in postfix
-(reverse-Polish) form, and evaluated all leaf nodes every time the expression
-was evaluated. But this ignores the fact that in many cases, once one operand
-of an AND or OR operation has been evaluated, there is no need to evaluate the
-other operand because its value can have no effect on the ultimate result. It
-is also worth noting that AND and OR operations are associative, meaning they
-can be rearranged at runtime to better suit the selected skin.
-
-This patch rewrites the expression parsing and evaluation code. Now the
-internal repreentation is in the form of a tree where leaf nodes represent a
-single infobool, and branch nodes represent either an AND or an OR operation
-on two or more child nodes.
-
-Expressions are rewritten at parse time into a form which favours the
-formation of groups of associative nodes. These groups are then reordered at
-evaluation time such that nodes whose value renders the evaluation of the
-remainder of the group unnecessary tend to be evaluated first (these are
-true nodes for OR subexpressions, or false nodes for AND subexpressions).
-The end effect is to minimise the number of leaf nodes that need to be
-evaluated in order to determine the value of the expression. The runtime
-adaptability has the advantage of not being customised for any particular skin.
-
-The modifications to the expression at parse time fall into two groups:
-1) Moving logical NOTs so that they are only applied to leaf nodes.
- For example, rewriting ![A+B]|C as !A|!B|C allows reordering such that
- any of the three leaves can be evaluated first.
-2) Combining adjacent AND or OR operations such that each path from the root
- to a leaf encounters a strictly alternating pattern of AND and OR
- operations. So [A|B]|[C|D+[[E|F]|G] becomes A|B|C|[D+[E|F|G]].
-
-I measured the effect while the Videos window of the default skin was open
-(but idle) on a Raspberry Pi, and this reduced the CPU usage by 2.8% from
-41.9% to 39.1%:
-
- Before After
- Mean StdDev Mean StdDev Confidence Change
-IdleCPU% 41.9 0.5 39.1 0.9 100.0% +7.0%
----
- xbmc/interfaces/info/InfoExpression.cpp | 313 +++++++++++++++++++++-----------
- xbmc/interfaces/info/InfoExpression.h | 63 ++++++-
- 2 files changed, 269 insertions(+), 107 deletions(-)
-
-diff --git a/xbmc/interfaces/info/InfoExpression.cpp b/xbmc/interfaces/info/InfoExpression.cpp
-index f4d32c1..db461dd 100644
---- a/xbmc/interfaces/info/InfoExpression.cpp
-+++ b/xbmc/interfaces/info/InfoExpression.cpp
-@@ -22,6 +22,9 @@
- #include
- #include "utils/log.h"
- #include "GUIInfoManager.h"
-+#include
-+#include
-+#include
-
- using namespace std;
- using namespace INFO;
-@@ -40,21 +43,89 @@ void InfoSingle::Update(const CGUIListItem *item)
- InfoExpression::InfoExpression(const std::string &expression, int context)
- : InfoBool(expression, context)
- {
-- Parse(expression);
-+ if (!Parse(expression))
-+ CLog::Log(LOGERROR, "Error parsing boolean expression %s", expression.c_str());
- }
-
- void InfoExpression::Update(const CGUIListItem *item)
- {
-- Evaluate(item, m_value);
-+ m_value = m_expression_tree->Evaluate(item);
- }
-
--#define OPERATOR_LB 5
--#define OPERATOR_RB 4
--#define OPERATOR_NOT 3
--#define OPERATOR_AND 2
--#define OPERATOR_OR 1
-+/* Expressions are rewritten at parse time into a form which favours the
-+ * formation of groups of associative nodes. These groups are then reordered at
-+ * evaluation time such that nodes whose value renders the evaluation of the
-+ * remainder of the group unnecessary tend to be evaluated first (these are
-+ * true nodes for OR subexpressions, or false nodes for AND subexpressions).
-+ * The end effect is to minimise the number of leaf nodes that need to be
-+ * evaluated in order to determine the value of the expression. The runtime
-+ * adaptability has the advantage of not being customised for any particular skin.
-+ *
-+ * The modifications to the expression at parse time fall into two groups:
-+ * 1) Moving logical NOTs so that they are only applied to leaf nodes.
-+ * For example, rewriting ![A+B]|C as !A|!B|C allows reordering such that
-+ * any of the three leaves can be evaluated first.
-+ * 2) Combining adjacent AND or OR operations such that each path from the root
-+ * to a leaf encounters a strictly alternating pattern of AND and OR
-+ * operations. So [A|B]|[C|D+[[E|F]|G] becomes A|B|C|[D+[E|F|G]].
-+ */
-+
-+bool InfoExpression::InfoLeaf::Evaluate(const CGUIListItem *item)
-+{
-+ return m_invert ^ m_info->Get(item);
-+}
-
--short InfoExpression::GetOperator(const char ch) const
-+InfoExpression::InfoAssociativeGroup::InfoAssociativeGroup(
-+ bool and_not_or,
-+ const InfoSubexpressionPtr &left,
-+ const InfoSubexpressionPtr &right)
-+ : m_and_not_or(and_not_or)
-+{
-+ AddChild(right);
-+ AddChild(left);
-+}
-+
-+void InfoExpression::InfoAssociativeGroup::AddChild(const InfoSubexpressionPtr &child)
-+{
-+ m_children.push_front(child); // largely undoes the effect of parsing right-associative
-+}
-+
-+void InfoExpression::InfoAssociativeGroup::Merge(InfoAssociativeGroup *other)
-+{
-+ m_children.splice(m_children.end(), other->m_children);
-+}
-+
-+bool InfoExpression::InfoAssociativeGroup::Evaluate(const CGUIListItem *item)
-+{
-+ /* Handle either AND or OR by using the relation
-+ * A AND B == !(!A OR !B)
-+ * to convert ANDs into ORs
-+ */
-+ std::list::iterator last = m_children.end();
-+ std::list::iterator it = m_children.begin();
-+ bool result = m_and_not_or ^ (*it)->Evaluate(item);
-+ while (!result && ++it != last)
-+ {
-+ result = m_and_not_or ^ (*it)->Evaluate(item);
-+ if (result)
-+ {
-+ /* Move this child to the head of the list so we evaluate faster next time */
-+ InfoSubexpressionPtr p = *it;
-+ m_children.erase(it);
-+ m_children.push_front(p);
-+ }
-+ }
-+ return m_and_not_or ^ result;
-+}
-+
-+/* Expressions are parsed using the shunting-yard algorithm. Binary operators
-+ * (AND/OR) are treated as right-associative so that we don't need to make a
-+ * special case for the unary NOT operator. This has no effect upon the answers
-+ * generated, though the initial sequence of evaluation of leaves may be
-+ * different from what you might expect.
-+ */
-+
-+InfoExpression::operator_t InfoExpression::GetOperator(char ch)
- {
- if (ch == '[')
- return OPERATOR_LB;
-@@ -67,122 +138,160 @@ short InfoExpression::GetOperator(const char ch) const
- else if (ch == '|')
- return OPERATOR_OR;
- else
-- return 0;
-+ return OPERATOR_NONE;
- }
-
--void InfoExpression::Parse(const std::string &expression)
-+void InfoExpression::OperatorPop(std::stack &operator_stack, bool &invert, std::stack &node_types, std::stack &nodes)
- {
-- stack operators;
-- std::string operand;
-- for (unsigned int i = 0; i < expression.size(); i++)
-+ operator_t op2 = operator_stack.top();
-+ operator_stack.pop();
-+ if (op2 == OPERATOR_NOT)
- {
-- if (GetOperator(expression[i]))
-+ invert = !invert;
-+ }
-+ else
-+ {
-+ // At this point, it can only be OPERATOR_AND or OPERATOR_OR
-+ if (invert)
-+ op2 = (operator_t) (OPERATOR_AND ^ OPERATOR_OR ^ op2);
-+ node_type_t new_type = op2 == OPERATOR_AND ? NODE_AND : NODE_OR;
-+
-+ InfoSubexpressionPtr right = nodes.top();
-+ nodes.pop();
-+ InfoSubexpressionPtr left = nodes.top();
-+
-+ node_type_t right_type = node_types.top();
-+ node_types.pop();
-+ node_type_t left_type = node_types.top();
-+
-+ // Combine associative operations into the same node where possible
-+ if (left_type == new_type && right_type == new_type)
-+ (static_cast(left.get()))->Merge(static_cast(right.get()));
-+ else if (left_type == new_type)
-+ (static_cast(left.get()))->AddChild(right);
-+ else
- {
-- // cleanup any operand, translate and put into our expression list
-- if (!operand.empty())
-+ nodes.pop();
-+ node_types.pop();
-+ if (right_type == new_type)
- {
-- InfoPtr info = g_infoManager.Register(operand, m_context);
-- if (info)
-- {
-- m_listItemDependent |= info->ListItemDependent();
-- m_postfix.push_back(m_operands.size());
-- m_operands.push_back(info);
-- }
-- operand.clear();
-+ (static_cast(right.get()))->AddChild(left);
-+ nodes.push(right);
- }
-- // handle closing parenthesis
-- if (expression[i] == ']')
-- {
-- while (!operators.empty())
-- {
-- char oper = operators.top();
-- operators.pop();
-+ else
-+ nodes.push(boost::make_shared(new_type == NODE_AND, left, right));
-+ node_types.push(new_type);
-+ }
-+ }
-+}
-+
-+void InfoExpression::ProcessOperator(operator_t op, std::stack &operator_stack, bool &invert, std::stack &node_types, std::stack &nodes)
-+{
-+ // Handle any higher-priority stacked operators, except when the new operator is left-bracket.
-+ // For a right-bracket, this will stop with the matching left-bracket at the top of the operator stack.
-+ if (op != OPERATOR_LB)
-+ {
-+ while (operator_stack.size() > 0 && operator_stack.top() > op)
-+ OperatorPop(operator_stack, invert, node_types, nodes);
-+ }
-+ if (op == OPERATOR_RB)
-+ operator_stack.pop(); // remove the matching left-bracket
-+ else
-+ operator_stack.push(op);
-+ if (op == OPERATOR_NOT)
-+ invert = !invert;
-+}
-
-- if (oper == '[')
-- break;
-+bool InfoExpression::ProcessOperand(std::string &operand, bool invert, std::stack &node_types, std::stack &nodes)
-+{
-+ InfoPtr info = g_infoManager.Register(operand, m_context);
-+ if (!info)
-+ return false;
-+ m_listItemDependent |= info->ListItemDependent();
-+ nodes.push(boost::make_shared(info, invert));
-+ node_types.push(NODE_LEAF);
-+ operand.clear();
-+ return true;
-+}
-
-- m_postfix.push_back(-GetOperator(oper)); // negative denotes operator
-- }
-+bool InfoExpression::Parse(const std::string &expression)
-+{
-+ const char *s = expression.c_str();
-+ std::string operand;
-+ std::stack operator_stack;
-+ bool invert = false;
-+ std::stack node_types;
-+ std::stack nodes;
-+ // The next two are for syntax-checking purposes
-+ bool after_binaryoperator = true;
-+ int bracket_count = 0;
-+
-+ char c;
-+ // Skip leading whitespace - don't want it to count as an operand if that's all there is
-+ do
-+ {
-+ c = *s++;
-+ } while (c == ' ' || c == '\t' || c == '\r' || c == '\n');
-+ s--;
-+ while ((c = *s++) != '\0')
-+ {
-+ operator_t op;
-+ if ((op = GetOperator(c)) != OPERATOR_NONE)
-+ {
-+ // Character is an operator
-+ if ((!after_binaryoperator && (c == '!' || c == '[')) ||
-+ (after_binaryoperator && (c == ']' || c == '+' || c == '|')))
-+ {
-+ CLog::Log(LOGERROR, "Misplaced %c", c);
-+ return false;
- }
-- else
-+ if (c == '[')
-+ bracket_count++;
-+ else if (c == ']' && bracket_count-- == 0)
-+ {
-+ CLog::Log(LOGERROR, "Unmatched ]");
-+ return false;
-+ }
-+ if (operand.size() > 0 && !ProcessOperand(operand, invert, node_types, nodes))
- {
-- // all other operators we pop off the stack any operator
-- // that has a higher priority than the one we have.
-- while (!operators.empty() && GetOperator(operators.top()) > GetOperator(expression[i]))
-- {
-- // only handle parenthesis once they're closed.
-- if (operators.top() == '[' && expression[i] != ']')
-- break;
--
-- m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
-- operators.pop();
-- }
-- operators.push(expression[i]);
-+ CLog::Log(LOGERROR, "Bad operand '%s'", operand.c_str());
-+ return false;
- }
-+ ProcessOperator(op, operator_stack, invert, node_types, nodes);
-+ if (c == '+' || c == '|')
-+ after_binaryoperator = true;
-+ // Skip trailing whitespace - don't want it to count as an operand if that's all there is
-+ do
-+ {
-+ c = *s++;
-+ } while (c == ' ' || c == '\t' || c == '\r' || c == '\n');
-+ s--;
- }
- else
- {
-- operand += expression[i];
-+ // Character is part of operand
-+ operand += c;
-+ after_binaryoperator = false;
- }
- }
--
-- if (!operand.empty())
-+ if (bracket_count > 0)
- {
-- InfoPtr info = g_infoManager.Register(operand, m_context);
-- if (info)
-- {
-- m_listItemDependent |= info->ListItemDependent();
-- m_postfix.push_back(m_operands.size());
-- m_operands.push_back(info);
-- }
-+ CLog::Log(LOGERROR, "Unmatched [");
-+ return false;
- }
--
-- // finish up by adding any operators
-- while (!operators.empty())
-+ if (after_binaryoperator)
- {
-- m_postfix.push_back(-GetOperator(operators.top())); // negative denotes operator
-- operators.pop();
-+ CLog::Log(LOGERROR, "Missing operand");
-+ return false;
- }
--
-- // test evaluate
-- bool test;
-- if (!Evaluate(NULL, test))
-- CLog::Log(LOGERROR, "Error evaluating boolean expression %s", expression.c_str());
--}
--
--bool InfoExpression::Evaluate(const CGUIListItem *item, bool &result)
--{
-- stack save;
-- for (vector::const_iterator it = m_postfix.begin(); it != m_postfix.end(); ++it)
-+ if (operand.size() > 0 && !ProcessOperand(operand, invert, node_types, nodes))
- {
-- short expr = *it;
-- if (expr == -OPERATOR_NOT)
-- { // NOT the top item on the stack
-- if (save.empty()) return false;
-- bool expr = save.top();
-- save.pop();
-- save.push(!expr);
-- }
-- else if (expr == -OPERATOR_AND)
-- { // AND the top two items on the stack
-- if (save.size() < 2) return false;
-- bool right = save.top(); save.pop();
-- bool left = save.top(); save.pop();
-- save.push(left && right);
-- }
-- else if (expr == -OPERATOR_OR)
-- { // OR the top two items on the stack
-- if (save.size() < 2) return false;
-- bool right = save.top(); save.pop();
-- bool left = save.top(); save.pop();
-- save.push(left || right);
-- }
-- else if (expr >= 0) // operand
-- save.push(m_operands[expr]->Get(item));
-- }
-- if (save.size() != 1)
-+ CLog::Log(LOGERROR, "Bad operand '%s'", operand.c_str());
- return false;
-- result = save.top();
-+ }
-+ while (operator_stack.size() > 0)
-+ OperatorPop(operator_stack, invert, node_types, nodes);
-+
-+ m_expression_tree = nodes.top();
- return true;
- }
--
-diff --git a/xbmc/interfaces/info/InfoExpression.h b/xbmc/interfaces/info/InfoExpression.h
-index 4e0faee..0a91399 100644
---- a/xbmc/interfaces/info/InfoExpression.h
-+++ b/xbmc/interfaces/info/InfoExpression.h
-@@ -21,6 +21,8 @@
- #pragma once
-
- #include
-+#include
-+#include
- #include "InfoBool.h"
-
- class CGUIListItem;
-@@ -50,12 +52,63 @@ class InfoExpression : public InfoBool
-
- virtual void Update(const CGUIListItem *item);
- private:
-- void Parse(const std::string &expression);
-- bool Evaluate(const CGUIListItem *item, bool &result);
-- short GetOperator(const char ch) const;
-+ typedef enum
-+ {
-+ OPERATOR_NONE = 0,
-+ OPERATOR_LB, // 1
-+ OPERATOR_RB, // 2
-+ OPERATOR_OR, // 3
-+ OPERATOR_AND, // 4
-+ OPERATOR_NOT, // 5
-+ } operator_t;
-
-- std::vector m_postfix; ///< the postfix form of the expression (operators and operand indicies)
-- std::vector m_operands; ///< the operands in the expression
-+ typedef enum
-+ {
-+ NODE_LEAF,
-+ NODE_AND,
-+ NODE_OR,
-+ } node_type_t;
-+
-+ // An abstract base class for nodes in the expression tree
-+ class InfoSubexpression
-+ {
-+ public:
-+ virtual ~InfoSubexpression(void) {}; // so we can destruct derived classes using a pointer to their base class
-+ virtual bool Evaluate(const CGUIListItem *item) = 0;
-+ };
-+
-+ typedef boost::shared_ptr InfoSubexpressionPtr;
-+
-+ // A leaf node in the expression tree
-+ class InfoLeaf : public InfoSubexpression
-+ {
-+ public:
-+ InfoLeaf(InfoPtr info, bool invert) : m_info(info), m_invert(invert) {};
-+ virtual bool Evaluate(const CGUIListItem *item);
-+ private:
-+ InfoPtr m_info;
-+ bool m_invert;
-+ };
-+
-+ // A branch node in the expression tree
-+ class InfoAssociativeGroup : public InfoSubexpression
-+ {
-+ public:
-+ InfoAssociativeGroup(bool and_not_or, const InfoSubexpressionPtr &left, const InfoSubexpressionPtr &right);
-+ void AddChild(const InfoSubexpressionPtr &child);
-+ void Merge(InfoAssociativeGroup *other);
-+ virtual bool Evaluate(const CGUIListItem *item);
-+ private:
-+ bool m_and_not_or;
-+ std::list m_children;
-+ };
-+
-+ static operator_t GetOperator(char ch);
-+ static void OperatorPop(std::stack &operator_stack, bool &invert, std::stack &node_types, std::stack &nodes);
-+ static void ProcessOperator(operator_t op, std::stack &operator_stack, bool &invert, std::stack &node_types, std::stack &nodes);
-+ bool ProcessOperand(std::string &operand, bool invert, std::stack &node_types, std::stack &nodes);
-+ bool Parse(const std::string &expression);
-+ InfoSubexpressionPtr m_expression_tree;
- };
-
- };
---
-1.9.3
-
-
-From 3ea2259e88b2b1b5036b6db81ec7b16bf505497f Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Mon, 24 Mar 2014 22:26:21 +0000
-Subject: [PATCH 02/82] Where an infobool expression failed to parse, evaluate
- the infobool as false. Previously, this would result in a segfault due to the
- dereferencing of an uninitialised pointer to the head of the expression tree.
-
----
- xbmc/interfaces/info/InfoExpression.cpp | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/xbmc/interfaces/info/InfoExpression.cpp b/xbmc/interfaces/info/InfoExpression.cpp
-index db461dd..7c54064 100644
---- a/xbmc/interfaces/info/InfoExpression.cpp
-+++ b/xbmc/interfaces/info/InfoExpression.cpp
-@@ -44,7 +44,10 @@ InfoExpression::InfoExpression(const std::string &expression, int context)
- : InfoBool(expression, context)
- {
- if (!Parse(expression))
-+ {
- CLog::Log(LOGERROR, "Error parsing boolean expression %s", expression.c_str());
-+ m_expression_tree = boost::make_shared(g_infoManager.Register("false", 0), false);
-+ }
- }
-
- void InfoExpression::Update(const CGUIListItem *item)
---
-1.9.3
-
-
-From 89f7abbd454aa88156ba54da164bde33992f7d5b Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Tue, 26 Nov 2013 20:09:48 +0000
-Subject: [PATCH 03/82] Add caching of infolabels
-
-The functions CGUIInfoLabel::GetLabel and CGUIInfoLabel::GetItemLabel take
-a number of strings returned from CGUIInfoManager::GetImage or
-CGUIInfoManager::GetLabel, and combine them with various constant strings
-which were determined during CGUIInfoLabel::Parse.
-
-Rather than perform all the string operations on every call, this patch
-changes to use a two-pass process: first it queries all the GetImage/GetLabel
-strings, and then only if at least one of them has changed does it bother
-rebuilding the resultant string - otherwise it re-uses the copy built on a
-preceding call.
-
-CGUIInfoLabel::GetLabel/GetItemLabel are also changed to return string
-references, rather than forcing an additional string copy.
-
-I have measured the effect while the Videos window of the default skin was
-open (but idle) on a Raspberry Pi, and this reduced the CPU usage by 0.8%
-from 36.2% to 35.4%:
-
- Before After
- Mean StdDev Mean StdDev Confidence Change
-IdleCPU% 36.2 0.5 35.4 0.5 99.9% +2.2%
----
- xbmc/guilib/GUIInfoTypes.cpp | 102 +++++++++++++++++++++++++++++++++----------
- xbmc/guilib/GUIInfoTypes.h | 11 ++++-
- 2 files changed, 87 insertions(+), 26 deletions(-)
-
-diff --git a/xbmc/guilib/GUIInfoTypes.cpp b/xbmc/guilib/GUIInfoTypes.cpp
-index 6977e0f..d78c26a 100644
---- a/xbmc/guilib/GUIInfoTypes.cpp
-+++ b/xbmc/guilib/GUIInfoTypes.cpp
-@@ -136,37 +136,64 @@ void CGUIInfoLabel::SetLabel(const CStdString &label, const CStdString &fallback
- Parse(label, context);
- }
-
--CStdString CGUIInfoLabel::GetLabel(int contextWindow, bool preferImage, CStdString *fallback /*= NULL*/) const
-+const std::string &CGUIInfoLabel::GetLabel(int contextWindow, bool preferImage, CStdString *fallback /*= NULL*/) const
- {
-- CStdString label;
-- for (unsigned int i = 0; i < m_info.size(); i++)
-+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
- {
- const CInfoPortion &portion = m_info[i];
- if (portion.m_info)
- {
-- CStdString infoLabel;
-+ std::string infoLabel;
- if (preferImage)
- infoLabel = g_infoManager.GetImage(portion.m_info, contextWindow, fallback);
- if (infoLabel.empty())
- infoLabel = g_infoManager.GetLabel(portion.m_info, contextWindow, fallback);
-- if (!infoLabel.empty())
-- label += portion.GetLabel(infoLabel);
-+ if (j == m_labelPortions.size())
-+ m_labelPortions.push_back(infoLabel);
-+ else if (infoLabel != m_labelPortions[j])
-+ {
-+ m_labelPortions[j] = infoLabel;
-+ m_labelDirty = true;
-+ }
-+ j++;
- }
-- else
-- { // no info, so just append the prefix
-- label += portion.m_prefix;
-+ }
-+ if (m_labelDirty)
-+ {
-+ m_label.clear();
-+ for (unsigned int i = 0, j= 0; i < m_info.size(); i++)
-+ {
-+ const CInfoPortion &portion = m_info[i];
-+ if (portion.m_info)
-+ {
-+ if (!m_labelPortions[j].empty())
-+ m_label += portion.GetLabel(m_labelPortions[j]);
-+ j++;
-+ }
-+ else
-+ { // no info, so just append the prefix
-+ m_label += portion.m_prefix;
-+ }
- }
-+ if (m_label.empty()) // empty label, use the fallback
-+ m_label = m_fallback;
-+ m_labelDirty = false;
- }
-- if (label.empty()) // empty label, use the fallback
-- return m_fallback;
-- return label;
-+ return m_label;
- }
-
--CStdString CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImages, CStdString *fallback /*= NULL*/) const
-+const std::string &CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImages, CStdString *fallback /*= NULL*/) const
- {
-- if (!item->IsFileItem()) return "";
-- CStdString label;
-- for (unsigned int i = 0; i < m_info.size(); i++)
-+ if (!item->IsFileItem())
-+ {
-+ if (m_itemLabelDirty)
-+ {
-+ m_itemLabel = "";
-+ m_itemLabelDirty = false;
-+ }
-+ return m_itemLabel;
-+ }
-+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
- {
- const CInfoPortion &portion = m_info[i];
- if (portion.m_info)
-@@ -176,17 +203,38 @@ CStdString CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImag
- infoLabel = g_infoManager.GetItemImage((const CFileItem *)item, portion.m_info, fallback);
- else
- infoLabel = g_infoManager.GetItemLabel((const CFileItem *)item, portion.m_info, fallback);
-- if (!infoLabel.empty())
-- label += portion.GetLabel(infoLabel);
-+ if (j == m_itemLabelPortions.size())
-+ m_itemLabelPortions.push_back(infoLabel);
-+ else if (infoLabel != m_itemLabelPortions[j])
-+ {
-+ m_itemLabelPortions[j] = infoLabel;
-+ m_itemLabelDirty = true;
-+ }
-+ j++;
- }
-- else
-- { // no info, so just append the prefix
-- label += portion.m_prefix;
-+ }
-+ if (m_itemLabelDirty)
-+ {
-+ m_itemLabel.clear();
-+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
-+ {
-+ const CInfoPortion &portion = m_info[i];
-+ if (portion.m_info)
-+ {
-+ if (!m_itemLabelPortions[j].empty())
-+ m_itemLabel += portion.GetLabel(m_itemLabelPortions[j]);
-+ j++;
-+ }
-+ else
-+ { // no info, so just append the prefix
-+ m_itemLabel += portion.m_prefix;
-+ }
- }
-+ if (m_itemLabel.empty())
-+ m_itemLabel = m_fallback;
-+ m_itemLabelDirty = false;
- }
-- if (label.empty())
-- return m_fallback;
-- return label;
-+ return m_itemLabel;
- }
-
- bool CGUIInfoLabel::IsEmpty() const
-@@ -277,6 +325,12 @@ const static infoformat infoformatmap[] = {{ "$INFO[", FORMATINFO },
- void CGUIInfoLabel::Parse(const CStdString &label, int context)
- {
- m_info.clear();
-+ m_labelDirty = true;
-+ m_label.clear();
-+ m_labelPortions.clear();
-+ m_itemLabelDirty = true;
-+ m_itemLabel.clear();
-+ m_itemLabelPortions.clear();
- // Step 1: Replace all $LOCALIZE[number] with the real string
- CStdString work = ReplaceLocalize(label);
- // Step 2: Replace all $ADDON[id number] with the real string
-diff --git a/xbmc/guilib/GUIInfoTypes.h b/xbmc/guilib/GUIInfoTypes.h
-index 8c1c1dc..418b2c4 100644
---- a/xbmc/guilib/GUIInfoTypes.h
-+++ b/xbmc/guilib/GUIInfoTypes.h
-@@ -83,7 +83,7 @@ class CGUIInfoLabel
- \param fallback if non-NULL, is set to an alternate value to use should the actual value be not appropriate. Defaults to NULL.
- \return label (or image).
- */
-- CStdString GetLabel(int contextWindow, bool preferImage = false, CStdString *fallback = NULL) const;
-+ const std::string &GetLabel(int contextWindow, bool preferImage = false, CStdString *fallback = NULL) const;
-
- /*!
- \brief Gets a label (or image) for a given listitem from the info manager.
-@@ -92,7 +92,7 @@ class CGUIInfoLabel
- \param fallback if non-NULL, is set to an alternate value to use should the actual value be not appropriate. Defaults to NULL.
- \return label (or image).
- */
-- CStdString GetItemLabel(const CGUIListItem *item, bool preferImage = false, CStdString *fallback = NULL) const;
-+ const std::string &GetItemLabel(const CGUIListItem *item, bool preferImage = false, CStdString *fallback = NULL) const;
-
- bool IsConstant() const;
- bool IsEmpty() const;
-@@ -132,6 +132,13 @@ class CGUIInfoLabel
-
- CStdString m_fallback;
- std::vector m_info;
-+
-+ mutable bool m_labelDirty;
-+ mutable std::string m_label;
-+ mutable std::vector m_labelPortions;
-+ mutable bool m_itemLabelDirty;
-+ mutable std::string m_itemLabel;
-+ mutable std::vector m_itemLabelPortions;
- };
-
- #endif
---
-1.9.3
-
-
-From 431ad06ca8c0299645f6fc79a6960199589748c7 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Tue, 10 Dec 2013 01:12:31 +0000
-Subject: [PATCH 04/82] De-duplication of string cache for non-item and item
- labels
-
----
- xbmc/guilib/GUIInfoTypes.cpp | 50 +++++++++++++++++++++++++-------------------
- xbmc/guilib/GUIInfoTypes.h | 4 +---
- 2 files changed, 29 insertions(+), 25 deletions(-)
-
-diff --git a/xbmc/guilib/GUIInfoTypes.cpp b/xbmc/guilib/GUIInfoTypes.cpp
-index d78c26a..8bd131f 100644
---- a/xbmc/guilib/GUIInfoTypes.cpp
-+++ b/xbmc/guilib/GUIInfoTypes.cpp
-@@ -121,7 +121,7 @@ void CGUIInfoColor::Parse(const CStdString &label, int context)
- m_color = g_colorManager.GetColor(label);
- }
-
--CGUIInfoLabel::CGUIInfoLabel()
-+CGUIInfoLabel::CGUIInfoLabel() : m_labelDirty(true)
- {
- }
-
-@@ -178,7 +178,10 @@ const std::string &CGUIInfoLabel::GetLabel(int contextWindow, bool preferImage,
- if (m_label.empty()) // empty label, use the fallback
- m_label = m_fallback;
- m_labelDirty = false;
-+ m_isLabelOfListItem = false;
- }
-+ else
-+ assert(m_isLabelOfListItem == false);
- return m_label;
- }
-
-@@ -186,12 +189,15 @@ const std::string &CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool pr
- {
- if (!item->IsFileItem())
- {
-- if (m_itemLabelDirty)
-+ if (m_labelDirty)
- {
-- m_itemLabel = "";
-- m_itemLabelDirty = false;
-+ m_label = "";
-+ m_labelDirty = false;
-+ m_isLabelOfListItem = true;
- }
-- return m_itemLabel;
-+ else
-+ assert(m_isLabelOfListItem == true);
-+ return m_label;
- }
- for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
- {
-@@ -203,38 +209,41 @@ const std::string &CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool pr
- infoLabel = g_infoManager.GetItemImage((const CFileItem *)item, portion.m_info, fallback);
- else
- infoLabel = g_infoManager.GetItemLabel((const CFileItem *)item, portion.m_info, fallback);
-- if (j == m_itemLabelPortions.size())
-- m_itemLabelPortions.push_back(infoLabel);
-- else if (infoLabel != m_itemLabelPortions[j])
-+ if (j == m_labelPortions.size())
-+ m_labelPortions.push_back(infoLabel);
-+ else if (infoLabel != m_labelPortions[j])
- {
-- m_itemLabelPortions[j] = infoLabel;
-- m_itemLabelDirty = true;
-+ m_labelPortions[j] = infoLabel;
-+ m_labelDirty = true;
- }
- j++;
- }
- }
-- if (m_itemLabelDirty)
-+ if (m_labelDirty)
- {
-- m_itemLabel.clear();
-+ m_label.clear();
- for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
- {
- const CInfoPortion &portion = m_info[i];
- if (portion.m_info)
- {
-- if (!m_itemLabelPortions[j].empty())
-- m_itemLabel += portion.GetLabel(m_itemLabelPortions[j]);
-+ if (!m_labelPortions[j].empty())
-+ m_label += portion.GetLabel(m_labelPortions[j]);
- j++;
- }
- else
- { // no info, so just append the prefix
-- m_itemLabel += portion.m_prefix;
-+ m_label += portion.m_prefix;
- }
- }
-- if (m_itemLabel.empty())
-- m_itemLabel = m_fallback;
-- m_itemLabelDirty = false;
-+ if (m_label.empty())
-+ m_label = m_fallback;
-+ m_labelDirty = false;
-+ m_isLabelOfListItem = true;
- }
-- return m_itemLabel;
-+ else
-+ assert(m_isLabelOfListItem == true);
-+ return m_label;
- }
-
- bool CGUIInfoLabel::IsEmpty() const
-@@ -328,9 +337,6 @@ void CGUIInfoLabel::Parse(const CStdString &label, int context)
- m_labelDirty = true;
- m_label.clear();
- m_labelPortions.clear();
-- m_itemLabelDirty = true;
-- m_itemLabel.clear();
-- m_itemLabelPortions.clear();
- // Step 1: Replace all $LOCALIZE[number] with the real string
- CStdString work = ReplaceLocalize(label);
- // Step 2: Replace all $ADDON[id number] with the real string
-diff --git a/xbmc/guilib/GUIInfoTypes.h b/xbmc/guilib/GUIInfoTypes.h
-index 418b2c4..6d9ebf7 100644
---- a/xbmc/guilib/GUIInfoTypes.h
-+++ b/xbmc/guilib/GUIInfoTypes.h
-@@ -133,12 +133,10 @@ class CGUIInfoLabel
- CStdString m_fallback;
- std::vector m_info;
-
-+ mutable bool m_isLabelOfListItem;
- mutable bool m_labelDirty;
- mutable std::string m_label;
- mutable std::vector m_labelPortions;
-- mutable bool m_itemLabelDirty;
-- mutable std::string m_itemLabel;
-- mutable std::vector m_itemLabelPortions;
- };
-
- #endif
---
-1.9.3
-
-
-From aac04a3876e7a79c126cc55f52d64ecfa6820c3b Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 11 Dec 2013 17:21:54 +0000
-Subject: [PATCH 05/82] Move the reference-counting of Begin and End calls from
- DX and GL source files into GUIFontTTF.cpp.
-
----
- xbmc/guilib/GUIFontTTF.cpp | 21 ++++++++
- xbmc/guilib/GUIFontTTF.h | 6 ++-
- xbmc/guilib/GUIFontTTFDX.cpp | 79 +++++++++++++----------------
- xbmc/guilib/GUIFontTTFDX.h | 4 +-
- xbmc/guilib/GUIFontTTFGL.cpp | 118 +++++++++++++++++++------------------------
- xbmc/guilib/GUIFontTTFGL.h | 4 +-
- 6 files changed, 117 insertions(+), 115 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 9c8e516..90b9c4a 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -309,6 +309,27 @@ bool CGUIFontTTFBase::Load(const CStdString& strFilename, float height, float as
- return true;
- }
-
-+void CGUIFontTTFBase::Begin()
-+{
-+ if (m_nestedBeginCount == 0 && m_texture != NULL && FirstBegin())
-+ {
-+ m_vertex_count = 0;
-+ }
-+ // Keep track of the nested begin/end calls.
-+ m_nestedBeginCount++;
-+}
-+
-+void CGUIFontTTFBase::End()
-+{
-+ if (m_nestedBeginCount == 0)
-+ return;
-+
-+ if (--m_nestedBeginCount > 0)
-+ return;
-+
-+ LastEnd();
-+}
-+
- void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors, const vecText &text, uint32_t alignment, float maxPixelWidth, bool scrolling)
- {
- Begin();
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index 9723a43..c1c4507 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -77,8 +77,8 @@ class CGUIFontTTFBase
-
- bool Load(const CStdString& strFilename, float height = 20.0f, float aspect = 1.0f, float lineSpacing = 1.0f, bool border = false);
-
-- virtual void Begin() = 0;
-- virtual void End() = 0;
-+ void Begin();
-+ void End();
-
- const CStdString& GetFileName() const { return m_strFileName; };
-
-@@ -169,6 +169,8 @@ class CGUIFontTTFBase
- CStdString m_strFileName;
-
- private:
-+ virtual bool FirstBegin() = 0;
-+ virtual void LastEnd() = 0;
- CGUIFontTTFBase(const CGUIFontTTFBase&);
- CGUIFontTTFBase& operator=(const CGUIFontTTFBase&);
- int m_referenceCount;
-diff --git a/xbmc/guilib/GUIFontTTFDX.cpp b/xbmc/guilib/GUIFontTTFDX.cpp
-index e3eba24..2f90668 100644
---- a/xbmc/guilib/GUIFontTTFDX.cpp
-+++ b/xbmc/guilib/GUIFontTTFDX.cpp
-@@ -51,65 +51,56 @@ CGUIFontTTFDX::~CGUIFontTTFDX(void)
- free(m_index);
- }
-
--void CGUIFontTTFDX::Begin()
-+bool CGUIFontTTFDX::FirstBegin()
- {
- LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
-
- if (pD3DDevice == NULL)
-+ {
- CLog::Log(LOGERROR, __FUNCTION__" - failed to get Direct3D device");
-+ return false;
-+ }
-
-- if (m_nestedBeginCount == 0 && pD3DDevice != NULL && m_texture != NULL)
-+ int unit = 0;
-+ // just have to blit from our texture.
-+ m_texture->BindToUnit(unit);
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); // only use diffuse
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
-+ unit++;
-+
-+ if(g_Windowing.UseLimitedColor())
- {
-- int unit = 0;
-- // just have to blit from our texture.
-- m_texture->BindToUnit(unit);
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); // only use diffuse
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP , D3DTOP_ADD );
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_CURRENT) ;
-+ pD3DDevice->SetRenderState( D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(16,16,16,0) );
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_TFACTOR );
- unit++;
--
-- if(g_Windowing.UseLimitedColor())
-- {
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP , D3DTOP_ADD );
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_CURRENT) ;
-- pD3DDevice->SetRenderState( D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(16,16,16,0) );
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_TFACTOR );
-- unit++;
-- }
--
-- // no other texture stages needed
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_DISABLE);
-- pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
--
-- pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
-- pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
-- pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
-- pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
-- pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
-- pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
-- pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
-- pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);
--
-- pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
-- m_vertex_count = 0;
- }
-
-- // Keep track of the nested begin/end calls.
-- m_nestedBeginCount++;
-+ // no other texture stages needed
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_DISABLE);
-+ pD3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
-+
-+ pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
-+ pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
-+ pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
-+ pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
-+ pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
-+ pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
-+ pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
-+ pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);
-+
-+ pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
-+ return true;
- }
-
--void CGUIFontTTFDX::End()
-+void CGUIFontTTFDX::LastEnd()
- {
- LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
-
-- if (m_nestedBeginCount == 0)
-- return;
--
-- if (--m_nestedBeginCount > 0)
-- return;
--
- if (m_vertex_count == 0)
- return;
-
-diff --git a/xbmc/guilib/GUIFontTTFDX.h b/xbmc/guilib/GUIFontTTFDX.h
-index 0431085..17dfefe 100644
---- a/xbmc/guilib/GUIFontTTFDX.h
-+++ b/xbmc/guilib/GUIFontTTFDX.h
-@@ -41,8 +41,8 @@ class CGUIFontTTFDX : public CGUIFontTTFBase
- CGUIFontTTFDX(const CStdString& strFileName);
- virtual ~CGUIFontTTFDX(void);
-
-- virtual void Begin();
-- virtual void End();
-+ virtual bool FirstBegin();
-+ virtual void LastEnd();
-
- protected:
- virtual CBaseTexture* ReallocTexture(unsigned int& newHeight);
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index 3358a5a..93b7ea6 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -50,90 +50,78 @@ CGUIFontTTFGL::~CGUIFontTTFGL(void)
- {
- }
-
--void CGUIFontTTFGL::Begin()
-+bool CGUIFontTTFGL::FirstBegin()
- {
-- if (m_nestedBeginCount == 0 && m_texture != NULL)
-+ if (!m_bTextureLoaded)
- {
-- if (!m_bTextureLoaded)
-- {
-- // Have OpenGL generate a texture object handle for us
-- glGenTextures(1, (GLuint*) &m_nTexture);
-+ // Have OpenGL generate a texture object handle for us
-+ glGenTextures(1, (GLuint*) &m_nTexture);
-
-- // Bind the texture object
-- glBindTexture(GL_TEXTURE_2D, m_nTexture);
-+ // Bind the texture object
-+ glBindTexture(GL_TEXTURE_2D, m_nTexture);
- #ifdef HAS_GL
-- glEnable(GL_TEXTURE_2D);
-+ glEnable(GL_TEXTURE_2D);
- #endif
-- // Set the texture's stretching properties
-- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-+ // Set the texture's stretching properties
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-- // Set the texture image -- THIS WORKS, so the pixels must be wrong.
-- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_texture->GetWidth(), m_texture->GetHeight(), 0,
-- GL_ALPHA, GL_UNSIGNED_BYTE, m_texture->GetPixels());
-+ // Set the texture image -- THIS WORKS, so the pixels must be wrong.
-+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_texture->GetWidth(), m_texture->GetHeight(), 0,
-+ GL_ALPHA, GL_UNSIGNED_BYTE, m_texture->GetPixels());
-
-- VerifyGLState();
-- m_bTextureLoaded = true;
-- }
-+ VerifyGLState();
-+ m_bTextureLoaded = true;
-+ }
-
-- // Turn Blending On
-- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
-- glEnable(GL_BLEND);
-+ // Turn Blending On
-+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
-+ glEnable(GL_BLEND);
- #ifdef HAS_GL
-- glEnable(GL_TEXTURE_2D);
-+ glEnable(GL_TEXTURE_2D);
- #endif
-- glBindTexture(GL_TEXTURE_2D, m_nTexture);
-+ glBindTexture(GL_TEXTURE_2D, m_nTexture);
-
- #ifdef HAS_GL
-- glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
-- glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
-- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
-- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
-- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
-- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0);
-- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
-- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR);
-- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
-- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-- VerifyGLState();
-+ glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
-+ glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR);
-+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
-+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-+ VerifyGLState();
-+
-+ if(g_Windowing.UseLimitedColor())
-+ {
-+ glActiveTexture(GL_TEXTURE1);
-+ glBindTexture(GL_TEXTURE_2D, m_nTexture); // dummy bind
-+ glEnable(GL_TEXTURE_2D);
-
-- if(g_Windowing.UseLimitedColor())
-- {
-- glActiveTexture(GL_TEXTURE1);
-- glBindTexture(GL_TEXTURE_2D, m_nTexture); // dummy bind
-- glEnable(GL_TEXTURE_2D);
--
-- const GLfloat rgba[4] = {16.0f / 255.0f, 16.0f / 255.0f, 16.0f / 255.0f, 0.0f};
-- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE , GL_COMBINE);
-- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba);
-- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB , GL_ADD);
-- glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB , GL_PREVIOUS);
-- glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB , GL_CONSTANT);
-- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB , GL_SRC_COLOR);
-- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB , GL_SRC_COLOR);
-- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA , GL_REPLACE);
-- glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA , GL_PREVIOUS);
-- VerifyGLState();
-- }
-+ const GLfloat rgba[4] = {16.0f / 255.0f, 16.0f / 255.0f, 16.0f / 255.0f, 0.0f};
-+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE , GL_COMBINE);
-+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB , GL_ADD);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB , GL_PREVIOUS);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB , GL_CONSTANT);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB , GL_SRC_COLOR);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB , GL_SRC_COLOR);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA , GL_REPLACE);
-+ glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA , GL_PREVIOUS);
-+ VerifyGLState();
-+ }
-
- #else
-- g_Windowing.EnableGUIShader(SM_FONTS);
-+ g_Windowing.EnableGUIShader(SM_FONTS);
- #endif
--
-- m_vertex_count = 0;
-- }
-- // Keep track of the nested begin/end calls.
-- m_nestedBeginCount++;
-+ return true;
- }
-
--void CGUIFontTTFGL::End()
-+void CGUIFontTTFGL::LastEnd()
- {
-- if (m_nestedBeginCount == 0)
-- return;
--
-- if (--m_nestedBeginCount > 0)
-- return;
--
- #ifdef HAS_GL
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-
-diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h
-index a0dacba..6736cf7 100644
---- a/xbmc/guilib/GUIFontTTFGL.h
-+++ b/xbmc/guilib/GUIFontTTFGL.h
-@@ -41,8 +41,8 @@ class CGUIFontTTFGL : public CGUIFontTTFBase
- CGUIFontTTFGL(const CStdString& strFileName);
- virtual ~CGUIFontTTFGL(void);
-
-- virtual void Begin();
-- virtual void End();
-+ virtual bool FirstBegin();
-+ virtual void LastEnd();
-
- protected:
- virtual CBaseTexture* ReallocTexture(unsigned int& newHeight);
---
-1.9.3
-
-
-From 0bc34394428f3d54a73e4e2e5c6b0daf2f157a60 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 11 Dec 2013 18:47:54 +0000
-Subject: [PATCH 06/82] Convert CGUIFontTTFBase::m_vertex to be managed as a
- std::vector. Also retired CGUIFontTTFBase::m_vertex_count and
- CGUIFontTTFBase::m_vertex_size because these can be derived from vector
- member functions.
-
----
- xbmc/guilib/GUIFontTTF.cpp | 29 +++++------------------------
- xbmc/guilib/GUIFontTTF.h | 4 +---
- xbmc/guilib/GUIFontTTFDX.cpp | 12 ++++++------
- xbmc/guilib/GUIFontTTFGL.cpp | 12 ++++++------
- 4 files changed, 18 insertions(+), 39 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 90b9c4a..3f219d9 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -139,8 +139,7 @@ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName)
- m_nestedBeginCount = 0;
-
- m_bTextureLoaded = false;
-- m_vertex_size = 4*1024;
-- m_vertex = (SVertex*)malloc(m_vertex_size * sizeof(SVertex));
-+ m_vertex.reserve(4*1024);
-
- m_face = NULL;
- m_stroker = NULL;
-@@ -155,7 +154,6 @@ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName)
- m_textureScaleX = m_textureScaleY = 0.0;
- m_ellipsesWidth = m_height = 0.0f;
- m_color = 0;
-- m_vertex_count = 0;
- m_nTexture = 0;
- }
-
-@@ -216,9 +214,7 @@ void CGUIFontTTFBase::Clear()
- g_freeTypeLibrary.ReleaseStroker(m_stroker);
- m_stroker = NULL;
-
-- free(m_vertex);
-- m_vertex = NULL;
-- m_vertex_count = 0;
-+ m_vertex.clear();
- }
-
- bool CGUIFontTTFBase::Load(const CStdString& strFilename, float height, float aspect, float lineSpacing, bool border)
-@@ -313,7 +309,7 @@ void CGUIFontTTFBase::Begin()
- {
- if (m_nestedBeginCount == 0 && m_texture != NULL && FirstBegin())
- {
-- m_vertex_count = 0;
-+ m_vertex.clear();
- }
- // Keep track of the nested begin/end calls.
- m_nestedBeginCount++;
-@@ -746,22 +742,9 @@ void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *c
- float tt = texture.y1 * m_textureScaleY;
- float tb = texture.y2 * m_textureScaleY;
-
-- // grow the vertex buffer if required
-- if(m_vertex_count >= m_vertex_size)
-- {
-- m_vertex_size *= 2;
-- void* old = m_vertex;
-- m_vertex = (SVertex*)realloc(m_vertex, m_vertex_size * sizeof(SVertex));
-- if (!m_vertex)
-- {
-- free(old);
-- CLog::Log(LOGSEVERE, "%s: can't allocate %"PRIdS" bytes for texture", __FUNCTION__ , m_vertex_size * sizeof(SVertex));
-- return;
-- }
-- }
--
-+ m_vertex.resize(m_vertex.size() + 4);
-+ SVertex* v = &m_vertex[m_vertex.size() - 4];
- m_color = color;
-- SVertex* v = m_vertex + m_vertex_count;
-
- unsigned char r = GET_R(color)
- , g = GET_G(color)
-@@ -828,8 +811,6 @@ void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *c
- v[3].y = y[2];
- v[3].z = z[2];
- #endif
--
-- m_vertex_count+=4;
- }
-
- // Oblique code - original taken from freetype2 (ftsynth.c)
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index c1c4507..35e3cf9 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -157,9 +157,7 @@ class CGUIFontTTFBase
- bool m_bTextureLoaded;
- unsigned int m_nTexture;
-
-- SVertex* m_vertex;
-- int m_vertex_count;
-- int m_vertex_size;
-+ std::vector m_vertex;
-
- float m_textureScaleX;
- float m_textureScaleY;
-diff --git a/xbmc/guilib/GUIFontTTFDX.cpp b/xbmc/guilib/GUIFontTTFDX.cpp
-index 2f90668..6ef8984 100644
---- a/xbmc/guilib/GUIFontTTFDX.cpp
-+++ b/xbmc/guilib/GUIFontTTFDX.cpp
-@@ -101,17 +101,17 @@ void CGUIFontTTFDX::LastEnd()
- {
- LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
-
-- if (m_vertex_count == 0)
-+ if (m_vertex.size() == 0)
- return;
-
-- unsigned index_size = m_vertex_size * 6 / 4;
-+ unsigned index_size = m_vertex.capacity() * 6 / 4;
- if(m_index_size < index_size)
- {
- uint16_t* id = (uint16_t*)calloc(index_size, sizeof(uint16_t));
- if(id == NULL)
- return;
-
-- for(int i = 0, b = 0; i < m_vertex_size; i += 4, b += 6)
-+ for(int i = 0, b = 0; i < m_vertex.capacity(); i += 4, b += 6)
- {
- id[b+0] = i + 0;
- id[b+1] = i + 1;
-@@ -140,11 +140,11 @@ void CGUIFontTTFDX::LastEnd()
-
- pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST
- , 0
-- , m_vertex_count
-- , m_vertex_count / 2
-+ , m_vertex.size()
-+ , m_vertex.size() / 2
- , m_index
- , D3DFMT_INDEX16
-- , m_vertex
-+ , &m_vertex[0]
- , sizeof(SVertex));
- pD3DDevice->SetTransform(D3DTS_WORLD, &orig);
-
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index 93b7ea6..a4e8571 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -125,13 +125,13 @@ void CGUIFontTTFGL::LastEnd()
- #ifdef HAS_GL
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-
-- glColorPointer (4, GL_UNSIGNED_BYTE, sizeof(SVertex), (char*)m_vertex + offsetof(SVertex, r));
-- glVertexPointer (3, GL_FLOAT , sizeof(SVertex), (char*)m_vertex + offsetof(SVertex, x));
-- glTexCoordPointer(2, GL_FLOAT , sizeof(SVertex), (char*)m_vertex + offsetof(SVertex, u));
-+ glColorPointer (4, GL_UNSIGNED_BYTE, sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, r));
-+ glVertexPointer (3, GL_FLOAT , sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, x));
-+ glTexCoordPointer(2, GL_FLOAT , sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, u));
- glEnableClientState(GL_COLOR_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-- glDrawArrays(GL_QUADS, 0, m_vertex_count);
-+ glDrawArrays(GL_QUADS, 0, m_vertex.size());
- glPopClientAttrib();
-
- glActiveTexture(GL_TEXTURE1);
-@@ -147,10 +147,10 @@ void CGUIFontTTFGL::LastEnd()
- GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
-
- // stack object until VBOs will be used
-- std::vector vecVertices( 6 * (m_vertex_count / 4) );
-+ std::vector vecVertices( 6 * (m_vertex.size() / 4) );
- SVertex *vertices = &vecVertices[0];
-
-- for (int i=0; i
-Date: Mon, 16 Dec 2013 18:58:12 +0000
-Subject: [PATCH 07/82] CGUIFontTTFBase::RenderCharacter can now append to
- arbitrary vectors of vertices rather than only CGUIFontTTFBase::m_vertex
-
----
- xbmc/guilib/GUIFontTTF.cpp | 12 +++++++-----
- xbmc/guilib/GUIFontTTF.h | 2 +-
- 2 files changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 3f219d9..1aaf68b 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -330,6 +330,8 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- {
- Begin();
-
-+ std::vector &vertices = m_vertex;
-+
- // save the origin, which is scaled separately
- m_originX = x;
- m_originY = y;
-@@ -410,7 +412,7 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
-
- for (int i = 0; i < 3; i++)
- {
-- RenderCharacter(startX + cursorX, startY, period, color, !scrolling);
-+ RenderCharacter(startX + cursorX, startY, period, color, !scrolling, vertices);
- cursorX += period->advance;
- }
- break;
-@@ -419,7 +421,7 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- else if (maxPixelWidth > 0 && cursorX > maxPixelWidth)
- break; // exceeded max allowed width - stop rendering
-
-- RenderCharacter(startX + cursorX, startY, ch, color, !scrolling);
-+ RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, vertices);
- if ( alignment & XBFONT_JUSTIFIED )
- {
- if ((*pos & 0xffff) == L' ')
-@@ -676,7 +678,7 @@ bool CGUIFontTTFBase::CacheCharacter(wchar_t letter, uint32_t style, Character *
- return true;
- }
-
--void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *ch, color_t color, bool roundX)
-+void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *ch, color_t color, bool roundX, std::vector &vertices)
- {
- // actual image width isn't same as the character width as that is
- // just baseline width and height should include the descent
-@@ -742,8 +744,8 @@ void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *c
- float tt = texture.y1 * m_textureScaleY;
- float tb = texture.y2 * m_textureScaleY;
-
-- m_vertex.resize(m_vertex.size() + 4);
-- SVertex* v = &m_vertex[m_vertex.size() - 4];
-+ vertices.resize(vertices.size() + 4);
-+ SVertex* v = &vertices[vertices.size() - 4];
- m_color = color;
-
- unsigned char r = GET_R(color)
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index 35e3cf9..4a6a696 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -109,7 +109,7 @@ class CGUIFontTTFBase
- // Stuff for pre-rendering for speed
- inline Character *GetCharacter(character_t letter);
- bool CacheCharacter(wchar_t letter, uint32_t style, Character *ch);
-- void RenderCharacter(float posX, float posY, const Character *ch, color_t color, bool roundX);
-+ void RenderCharacter(float posX, float posY, const Character *ch, color_t color, bool roundX, std::vector &vertices);
- void ClearCharacterCache();
-
- virtual CBaseTexture* ReallocTexture(unsigned int& newHeight) = 0;
---
-1.9.3
-
-
-From 96abf97cc233118b46670fc78a28d09f4c1c5335 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 15 Jan 2014 17:18:38 +0000
-Subject: [PATCH 08/82] Add a cache of font glyph bounding box vertices. This
- is implemented as a template because ultimately we will key on different
- parameters and store values of different types, depending upon whether we
- have a GLES or non-GLES backend, and for GLES, whether or not the currently
- applicable transformation matrices permit the use of hardware clipping.
-
----
- xbmc/guilib/GUIFontCache.cpp | 105 ++++++++++++++++++++
- xbmc/guilib/GUIFontCache.h | 217 ++++++++++++++++++++++++++++++++++++++++++
- xbmc/guilib/GUIFontTTF.cpp | 181 +++++++++++++++++++----------------
- xbmc/guilib/GUIFontTTF.h | 5 +
- xbmc/guilib/GUIFontTTFGL.cpp | 1 +
- xbmc/guilib/GraphicContext.h | 1 +
- xbmc/guilib/Makefile.in | 1 +
- xbmc/guilib/TransformMatrix.h | 11 +++
- 8 files changed, 438 insertions(+), 84 deletions(-)
- create mode 100644 xbmc/guilib/GUIFontCache.cpp
- create mode 100644 xbmc/guilib/GUIFontCache.h
-
-diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp
-new file mode 100644
-index 0000000..c029713
---- /dev/null
-+++ b/xbmc/guilib/GUIFontCache.cpp
-@@ -0,0 +1,105 @@
-+/*
-+ * 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
-+#include
-+#include "utils/StdString.h" // required by GUIFontTTF.h
-+#include "GUIFontTTF.h"
-+#include "GraphicContext.h"
-+
-+template
-+void CGUIFontCacheEntry::Reassign::operator()(CGUIFontCacheEntry &entry)
-+{
-+ entry.m_key.m_pos = m_key.m_pos;
-+ entry.m_key.m_colors.assign(m_key.m_colors.begin(), m_key.m_colors.end());
-+ entry.m_key.m_text.assign(m_key.m_text.begin(), m_key.m_text.end());
-+ entry.m_key.m_alignment = m_key.m_alignment;
-+ entry.m_key.m_maxPixelWidth = m_key.m_maxPixelWidth;
-+ entry.m_key.m_scrolling = m_key.m_scrolling;
-+ entry.m_matrix = m_key.m_matrix;
-+ entry.m_key.m_scaleX = m_key.m_scaleX;
-+ entry.m_key.m_scaleY = m_key.m_scaleY;
-+
-+ entry.m_lastUsedMillis = m_nowMillis;
-+ entry.m_value.clear();
-+}
-+
-+template
-+CGUIFontCacheEntry::~CGUIFontCacheEntry()
-+{
-+ delete &m_key.m_colors;
-+ delete &m_key.m_text;
-+ m_value.clear();
-+}
-+
-+template
-+Value &CGUIFontCache::Lookup(Position &pos,
-+ const vecColors &colors, const vecText &text,
-+ uint32_t alignment, float maxPixelWidth,
-+ bool scrolling,
-+ unsigned int nowMillis, bool &dirtyCache)
-+{
-+ const CGUIFontCacheKey key(pos,
-+ const_cast(colors), const_cast(text),
-+ alignment, maxPixelWidth,
-+ scrolling, g_graphicsContext.GetGUIMatrix(),
-+ g_graphicsContext.GetGUIScaleX(), g_graphicsContext.GetGUIScaleY());
-+ EntryHashIterator i = m_list.get().find(key);
-+ if (i == m_list.get().end())
-+ {
-+ /* Cache miss */
-+ EntryAgeIterator oldest = m_list.get().begin();
-+ if (!m_list.get().empty() && nowMillis - oldest->m_lastUsedMillis > FONT_CACHE_TIME_LIMIT)
-+ {
-+ /* The oldest existing entry is old enough to expire and reuse */
-+ m_list.get().modify(m_list.project(oldest), typename CGUIFontCacheEntry::Reassign(key, nowMillis));
-+ m_list.get().relocate(m_list.get().end(), oldest);
-+ }
-+ else
-+ {
-+ /* We need a new entry instead */
-+ /* Yes, this causes the creation an destruction of a temporary entry, but
-+ * this code ought to only be used infrequently, when the cache needs to grow */
-+ m_list.get().push_back(CGUIFontCacheEntry(*this, key, nowMillis));
-+ }
-+ dirtyCache = true;
-+ return (--m_list.get().end())->m_value;
-+ }
-+ else
-+ {
-+ /* Cache hit */
-+ /* Update time in entry and move to the back of the list */
-+ i->m_lastUsedMillis = nowMillis;
-+ m_list.get().relocate(m_list.get().end(), m_list.project(i));
-+ dirtyCache = false;
-+ return i->m_value;
-+ }
-+}
-+
-+template
-+void CGUIFontCache::Flush()
-+{
-+ m_list.get().clear();
-+}
-+
-+template void CGUIFontCacheEntry::Reassign::operator()(CGUIFontCacheEntry &entry);
-+template CGUIFontCacheEntry::~CGUIFontCacheEntry();
-+template CGUIFontCacheStaticValue &CGUIFontCache::Lookup(CGUIFontCacheStaticPosition &, const vecColors &, const vecText &, uint32_t, float, bool, unsigned int, bool &);
-+template void CGUIFontCache::Flush();
-diff --git a/xbmc/guilib/GUIFontCache.h b/xbmc/guilib/GUIFontCache.h
-new file mode 100644
-index 0000000..ef65845
---- /dev/null
-+++ b/xbmc/guilib/GUIFontCache.h
-@@ -0,0 +1,217 @@
-+/*!
-+\file GUIFontCache.h
-+\brief
-+*/
-+
-+#ifndef CGUILIB_GUIFONTCACHE_H
-+#define CGUILIB_GUIFONTCACHE_H
-+#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
-+#include
-+#include
-+
-+#include
-+#include
-+
-+#include "boost/multi_index_container.hpp"
-+#include "boost/multi_index/sequenced_index.hpp"
-+#include "boost/multi_index/hashed_index.hpp"
-+#include "boost/multi_index/member.hpp"
-+
-+#include "TransformMatrix.h"
-+
-+using namespace boost::multi_index;
-+
-+#define FONT_CACHE_TIME_LIMIT (1000)
-+
-+template class CGUIFontCache;
-+class CGUIFontTTFBase;
-+
-+template
-+struct CGUIFontCacheKey
-+{
-+ Position m_pos;
-+ vecColors &m_colors;
-+ vecText &m_text;
-+ uint32_t m_alignment;
-+ float m_maxPixelWidth;
-+ bool m_scrolling;
-+ const TransformMatrix &m_matrix;
-+ float m_scaleX;
-+ float m_scaleY;
-+
-+ CGUIFontCacheKey(Position pos,
-+ vecColors &colors, vecText &text,
-+ uint32_t alignment, float maxPixelWidth,
-+ bool scrolling, const TransformMatrix &matrix,
-+ float scaleX, float scaleY) :
-+ m_pos(pos),
-+ m_colors(colors), m_text(text),
-+ m_alignment(alignment), m_maxPixelWidth(maxPixelWidth),
-+ m_scrolling(scrolling), m_matrix(matrix),
-+ m_scaleX(scaleX), m_scaleY(scaleY)
-+ {}
-+};
-+
-+template
-+struct CGUIFontCacheEntry
-+{
-+ const CGUIFontCache &m_cache;
-+ CGUIFontCacheKey m_key;
-+ TransformMatrix m_matrix;
-+
-+ /* These need to be declared as mutable to get round the fact that only
-+ * const iterators are available. These fields do not affect comparison or
-+ * hash functors, so from the container's point of view, they are mutable. */
-+ mutable unsigned int m_lastUsedMillis;
-+ mutable Value m_value;
-+
-+ CGUIFontCacheEntry(const CGUIFontCache &cache, const CGUIFontCacheKey &key, unsigned int nowMillis) :
-+ m_cache(cache),
-+ m_key(key.m_pos,
-+ *new vecColors, *new vecText,
-+ key.m_alignment, key.m_maxPixelWidth,
-+ key.m_scrolling, m_matrix,
-+ key.m_scaleX, key.m_scaleY),
-+ m_lastUsedMillis(nowMillis)
-+ {
-+ m_key.m_colors.assign(key.m_colors.begin(), key.m_colors.end());
-+ m_key.m_text.assign(key.m_text.begin(), key.m_text.end());
-+ m_matrix = key.m_matrix;
-+ }
-+
-+ CGUIFontCacheEntry(const CGUIFontCacheEntry &other) :
-+ m_cache(other.m_cache),
-+ m_key(other.m_key.m_pos,
-+ *new vecColors, *new vecText,
-+ other.m_key.m_alignment, other.m_key.m_maxPixelWidth,
-+ other.m_key.m_scrolling, m_matrix,
-+ other.m_key.m_scaleX, other.m_key.m_scaleY),
-+ m_lastUsedMillis(other.m_lastUsedMillis),
-+ m_value(other.m_value)
-+ {
-+ m_key.m_colors.assign(other.m_key.m_colors.begin(), other.m_key.m_colors.end());
-+ m_key.m_text.assign(other.m_key.m_text.begin(), other.m_key.m_text.end());
-+ m_matrix = other.m_key.m_matrix;
-+ }
-+
-+ struct Reassign
-+ {
-+ Reassign(const CGUIFontCacheKey &key, unsigned int nowMillis) : m_key(key), m_nowMillis(nowMillis) {}
-+ void operator()(CGUIFontCacheEntry &entry);
-+ private:
-+ const CGUIFontCacheKey &m_key;
-+ unsigned int m_nowMillis;
-+ };
-+
-+ ~CGUIFontCacheEntry();
-+};
-+
-+template
-+struct CGUIFontCacheHash
-+{
-+ size_t operator()(const CGUIFontCacheKey &key) const
-+ {
-+ /* Not much effort has gone into choosing this hash function */
-+ size_t hash = 0, i;
-+ for (i = 0; i < 3 && i < key.m_text.size(); ++i)
-+ hash += key.m_text[i];
-+ if (key.m_colors.size())
-+ hash += key.m_colors[0];
-+ hash += MatrixHashContribution(key);
-+ return hash;
-+ }
-+};
-+
-+template
-+struct CGUIFontCacheKeysMatch
-+{
-+ bool operator()(const CGUIFontCacheKey &a, const CGUIFontCacheKey &b) const
-+ {
-+ return a.m_text == b.m_text &&
-+ a.m_colors == b.m_colors &&
-+ a.m_alignment == b.m_alignment &&
-+ a.m_scrolling == b.m_scrolling &&
-+ a.m_maxPixelWidth == b.m_maxPixelWidth &&
-+ Match(a.m_pos, a.m_matrix, b.m_pos, b.m_matrix, a.m_scrolling) &&
-+ a.m_scaleX == b.m_scaleX &&
-+ a.m_scaleY == b.m_scaleY;
-+ }
-+};
-+
-+template
-+class CGUIFontCache
-+{
-+ /* Empty structs used as tags to identify indexes */
-+ struct Age {};
-+ struct Hash {};
-+
-+ typedef multi_index_container<
-+ CGUIFontCacheEntry,
-+ indexed_by<
-+ sequenced >,
-+ hashed_unique, member, CGUIFontCacheKey, &CGUIFontCacheEntry::m_key>, CGUIFontCacheHash, CGUIFontCacheKeysMatch >
-+ >
-+ > EntryList;
-+
-+ typedef typename EntryList::template index::type::iterator EntryAgeIterator;
-+ typedef typename EntryList::template index::type::iterator EntryHashIterator;
-+
-+ EntryList m_list;
-+
-+public:
-+ const CGUIFontTTFBase &m_font;
-+
-+ CGUIFontCache(CGUIFontTTFBase &font) : m_font(font) {}
-+ Value &Lookup(Position &pos,
-+ const vecColors &colors, const vecText &text,
-+ uint32_t alignment, float maxPixelWidth,
-+ bool scrolling,
-+ unsigned int nowMillis, bool &dirtyCache);
-+ void Flush();
-+};
-+
-+struct CGUIFontCacheStaticPosition
-+{
-+ float m_x;
-+ float m_y;
-+ CGUIFontCacheStaticPosition(float x, float y) : m_x(x), m_y(y) {}
-+};
-+
-+typedef std::vector CGUIFontCacheStaticValue;
-+
-+inline bool Match(const CGUIFontCacheStaticPosition &a, const TransformMatrix &a_m,
-+ const CGUIFontCacheStaticPosition &b, const TransformMatrix &b_m,
-+ bool scrolling)
-+{
-+ return a.m_x == b.m_x && a.m_y == b.m_y && a_m == b_m;
-+}
-+
-+inline float MatrixHashContribution(const CGUIFontCacheKey &a)
-+{
-+ /* Ensure horizontally translated versions end up in different buckets */
-+ return a.m_matrix.m[0][3];
-+}
-+
-+#endif
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 1aaf68b..288e61a 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -27,6 +27,7 @@
- #include "utils/MathUtils.h"
- #include "utils/log.h"
- #include "windowing/WindowingFactory.h"
-+#include "threads/SystemClock.h"
-
- #include
-
-@@ -131,7 +132,7 @@ class CFreeTypeLibrary
- XBMC_GLOBAL_REF(CFreeTypeLibrary, g_freeTypeLibrary); // our freetype library
- #define g_freeTypeLibrary XBMC_GLOBAL_USE(CFreeTypeLibrary)
-
--CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName)
-+CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) : m_staticCache(*this)
- {
- m_texture = NULL;
- m_char = NULL;
-@@ -330,108 +331,120 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- {
- Begin();
-
-- std::vector &vertices = m_vertex;
--
-- // save the origin, which is scaled separately
-- m_originX = x;
-- m_originY = y;
--
-- // Check if we will really need to truncate or justify the text
-- if ( alignment & XBFONT_TRUNCATED )
-+ bool dirtyCache;
-+ CGUIFontCacheStaticPosition staticPos(x, y);
-+ std::vector &vertices = m_staticCache.Lookup(staticPos,
-+ colors, text,
-+ alignment, maxPixelWidth,
-+ scrolling,
-+ XbmcThreads::SystemClockMillis(),
-+ dirtyCache);
-+ if (dirtyCache)
- {
-- if ( maxPixelWidth <= 0.0f || GetTextWidthInternal(text.begin(), text.end()) <= maxPixelWidth)
-- alignment &= ~XBFONT_TRUNCATED;
-- }
-- else if ( alignment & XBFONT_JUSTIFIED )
-- {
-- if ( maxPixelWidth <= 0.0f )
-- alignment &= ~XBFONT_JUSTIFIED;
-- }
-+ // save the origin, which is scaled separately
-+ m_originX = x;
-+ m_originY = y;
-
-- // calculate sizing information
-- float startX = 0;
-- float startY = (alignment & XBFONT_CENTER_Y) ? -0.5f*m_cellHeight : 0; // vertical centering
-+ // Check if we will really need to truncate or justify the text
-+ if ( alignment & XBFONT_TRUNCATED )
-+ {
-+ if ( maxPixelWidth <= 0.0f || GetTextWidthInternal(text.begin(), text.end()) <= maxPixelWidth)
-+ alignment &= ~XBFONT_TRUNCATED;
-+ }
-+ else if ( alignment & XBFONT_JUSTIFIED )
-+ {
-+ if ( maxPixelWidth <= 0.0f )
-+ alignment &= ~XBFONT_JUSTIFIED;
-+ }
-
-- if ( alignment & (XBFONT_RIGHT | XBFONT_CENTER_X) )
-- {
-- // Get the extent of this line
-- float w = GetTextWidthInternal( text.begin(), text.end() );
-+ // calculate sizing information
-+ float startX = 0;
-+ float startY = (alignment & XBFONT_CENTER_Y) ? -0.5f*m_cellHeight : 0; // vertical centering
-
-- if ( alignment & XBFONT_TRUNCATED && w > maxPixelWidth + 0.5f ) // + 0.5f due to rounding issues
-- w = maxPixelWidth;
-+ if ( alignment & (XBFONT_RIGHT | XBFONT_CENTER_X) )
-+ {
-+ // Get the extent of this line
-+ float w = GetTextWidthInternal( text.begin(), text.end() );
-
-- if ( alignment & XBFONT_CENTER_X)
-- w *= 0.5f;
-- // Offset this line's starting position
-- startX -= w;
-- }
-+ if ( alignment & XBFONT_TRUNCATED && w > maxPixelWidth + 0.5f ) // + 0.5f due to rounding issues
-+ w = maxPixelWidth;
-
-- float spacePerLetter = 0; // for justification effects
-- if ( alignment & XBFONT_JUSTIFIED )
-- {
-- // first compute the size of the text to render in both characters and pixels
-- unsigned int lineChars = 0;
-- float linePixels = 0;
-- for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
-+ if ( alignment & XBFONT_CENTER_X)
-+ w *= 0.5f;
-+ // Offset this line's starting position
-+ startX -= w;
-+ }
-+
-+ float spacePerLetter = 0; // for justification effects
-+ if ( alignment & XBFONT_JUSTIFIED )
- {
-- Character *ch = GetCharacter(*pos);
-- if (ch)
-- { // spaces have multiple times the justification spacing of normal letters
-- lineChars += ((*pos & 0xffff) == L' ') ? justification_word_weight : 1;
-- linePixels += ch->advance;
-+ // first compute the size of the text to render in both characters and pixels
-+ unsigned int lineChars = 0;
-+ float linePixels = 0;
-+ for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
-+ {
-+ Character *ch = GetCharacter(*pos);
-+ if (ch)
-+ { // spaces have multiple times the justification spacing of normal letters
-+ lineChars += ((*pos & 0xffff) == L' ') ? justification_word_weight : 1;
-+ linePixels += ch->advance;
-+ }
- }
-+ if (lineChars > 1)
-+ spacePerLetter = (maxPixelWidth - linePixels) / (lineChars - 1);
- }
-- if (lineChars > 1)
-- spacePerLetter = (maxPixelWidth - linePixels) / (lineChars - 1);
-- }
-- float cursorX = 0; // current position along the line
--
-- for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
-- {
-- // If starting text on a new line, determine justification effects
-- // Get the current letter in the CStdString
-- color_t color = (*pos & 0xff0000) >> 16;
-- if (color >= colors.size())
-- color = 0;
-- color = colors[color];
-+ float cursorX = 0; // current position along the line
-
-- // grab the next character
-- Character *ch = GetCharacter(*pos);
-- if (!ch) continue;
--
-- if ( alignment & XBFONT_TRUNCATED )
-+ for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
- {
-- // Check if we will be exceeded the max allowed width
-- if ( cursorX + ch->advance + 3 * m_ellipsesWidth > maxPixelWidth )
-- {
-- // Yup. Let's draw the ellipses, then bail
-- // Perhaps we should really bail to the next line in this case??
-- Character *period = GetCharacter(L'.');
-- if (!period)
-- break;
-+ // If starting text on a new line, determine justification effects
-+ // Get the current letter in the CStdString
-+ color_t color = (*pos & 0xff0000) >> 16;
-+ if (color >= colors.size())
-+ color = 0;
-+ color = colors[color];
-+
-+ // grab the next character
-+ Character *ch = GetCharacter(*pos);
-+ if (!ch) continue;
-
-- for (int i = 0; i < 3; i++)
-+ if ( alignment & XBFONT_TRUNCATED )
-+ {
-+ // Check if we will be exceeded the max allowed width
-+ if ( cursorX + ch->advance + 3 * m_ellipsesWidth > maxPixelWidth )
- {
-- RenderCharacter(startX + cursorX, startY, period, color, !scrolling, vertices);
-- cursorX += period->advance;
-+ // Yup. Let's draw the ellipses, then bail
-+ // Perhaps we should really bail to the next line in this case??
-+ Character *period = GetCharacter(L'.');
-+ if (!period)
-+ break;
-+
-+ for (int i = 0; i < 3; i++)
-+ {
-+ RenderCharacter(startX + cursorX, startY, period, color, !scrolling, vertices);
-+ cursorX += period->advance;
-+ }
-+ break;
- }
-- break;
- }
-- }
-- else if (maxPixelWidth > 0 && cursorX > maxPixelWidth)
-- break; // exceeded max allowed width - stop rendering
-+ else if (maxPixelWidth > 0 && cursorX > maxPixelWidth)
-+ break; // exceeded max allowed width - stop rendering
-
-- RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, vertices);
-- if ( alignment & XBFONT_JUSTIFIED )
-- {
-- if ((*pos & 0xffff) == L' ')
-- cursorX += ch->advance + spacePerLetter * justification_word_weight;
-+ RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, vertices);
-+ if ( alignment & XBFONT_JUSTIFIED )
-+ {
-+ if ((*pos & 0xffff) == L' ')
-+ cursorX += ch->advance + spacePerLetter * justification_word_weight;
-+ else
-+ cursorX += ch->advance + spacePerLetter;
-+ }
- else
-- cursorX += ch->advance + spacePerLetter;
-+ cursorX += ch->advance;
- }
-- else
-- cursorX += ch->advance;
- }
-+ /* Append the new vertices (from the cache or otherwise) to the set collected
-+ * since the first Begin() call */
-+ m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-
- End();
- }
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index 4a6a696..7cb4669 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -64,6 +64,9 @@ struct SVertex
- };
-
-
-+#include "GUIFontCache.h"
-+
-+
- class CGUIFontTTFBase
- {
- friend class CGUIFont;
-@@ -166,6 +169,8 @@ class CGUIFontTTFBase
-
- CStdString m_strFileName;
-
-+ CGUIFontCache m_staticCache;
-+
- private:
- virtual bool FirstBegin() = 0;
- virtual void LastEnd() = 0;
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index a4e8571..cb56987 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -200,6 +200,7 @@ CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight)
- m_textureScaleX = 1.0f / m_textureWidth;
- if (m_textureHeight < newHeight)
- CLog::Log(LOGWARNING, "%s: allocated new texture with height of %d, requested %d", __FUNCTION__, m_textureHeight, newHeight);
-+ m_staticCache.Flush();
-
- memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch());
- if (m_texture)
-diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h
-index 6c2dcd4..bab2457 100644
---- a/xbmc/guilib/GraphicContext.h
-+++ b/xbmc/guilib/GraphicContext.h
-@@ -146,6 +146,7 @@ class CGraphicContext : public CCriticalSection,
- inline void ScaleFinalCoords(float &x, float &y, float &z) const XBMC_FORCE_INLINE { m_finalTransform.matrix.TransformPosition(x, y, z); }
- bool RectIsAngled(float x1, float y1, float x2, float y2) const;
-
-+ inline const TransformMatrix &GetGUIMatrix() const XBMC_FORCE_INLINE { return m_finalTransform.matrix; }
- inline float GetGUIScaleX() const XBMC_FORCE_INLINE { return m_finalTransform.scaleX; }
- inline float GetGUIScaleY() const XBMC_FORCE_INLINE { return m_finalTransform.scaleY; }
- inline color_t MergeAlpha(color_t color) const XBMC_FORCE_INLINE
-diff --git a/xbmc/guilib/Makefile.in b/xbmc/guilib/Makefile.in
-index 086fb0d..af82979 100644
---- a/xbmc/guilib/Makefile.in
-+++ b/xbmc/guilib/Makefile.in
-@@ -23,6 +23,7 @@ SRCS += GUIEditControl.cpp
- SRCS += GUIFadeLabelControl.cpp
- SRCS += GUIFixedListContainer.cpp
- SRCS += GUIFont.cpp
-+SRCS += GUIFontCache.cpp
- SRCS += GUIFontManager.cpp
- SRCS += GUIFontTTF.cpp
- SRCS += GUIImage.cpp
-diff --git a/xbmc/guilib/TransformMatrix.h b/xbmc/guilib/TransformMatrix.h
-index f351c99..9036ba9 100644
---- a/xbmc/guilib/TransformMatrix.h
-+++ b/xbmc/guilib/TransformMatrix.h
-@@ -245,3 +245,14 @@ class TransformMatrix
- float alpha;
- bool identity;
- };
-+
-+inline bool operator==(const TransformMatrix &a, const TransformMatrix &b)
-+{
-+ return a.alpha == b.alpha && ((a.identity && b.identity) ||
-+ (!a.identity && !b.identity && std::equal(&a.m[0][0], &a.m[0][0] + sizeof a.m / sizeof a.m[0][0], &b.m[0][0])));
-+}
-+
-+inline bool operator!=(const TransformMatrix &a, const TransformMatrix &b)
-+{
-+ return !operator==(a, b);
-+}
---
-1.9.3
-
-
-From 87a615ec2b918f622cdeb4d97ac383473d533c19 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Thu, 23 Jan 2014 22:24:17 +0000
-Subject: [PATCH 09/82] Lay the groundwork for hardware clipping.
-
-For glScissor() to replace CGraphicContext::ClipRect, a necessary condition
-is that no shear or rotation is introduced between the coordinate systems
-they use; this depends upon the settings of the GUI matrix m_finalTransform
-as well as the OpenGL model-view and projection matrices. These all remain
-unchanged between paired calls of CGUIShader::OnEnabled and
-CGUIShader::OnDisabled, so we scan the matrices in CGUIShader::OnEnabled to
-see whether hardware clipping is possible.
-
-Then, in CGUIFontTTFBase::RenderCharacter, we don't apply software clipping
-in such cases. However, because vertices arising from multiple
-CGUIFontTTFBase::DrawTextInternal calls (each of which often uses a different
-clip rectangle) get lumped into the same vector, which only at the end is
-passed to OpenGL for rendering, we need to wait a few commits before we can
-actually apply hardware clipping. In the meantime, expect to see rendering
-errors.
----
- xbmc/guilib/GUIFontTTF.cpp | 3 +-
- xbmc/guilib/GUIShader.cpp | 80 +++++++++++++++++++++++++++++++-
- xbmc/guilib/GUIShader.h | 11 +++++
- xbmc/guilib/GraphicContext.cpp | 10 ++++
- xbmc/guilib/GraphicContext.h | 1 +
- xbmc/rendering/RenderSystem.h | 2 +
- xbmc/rendering/gles/RenderSystemGLES.cpp | 22 +++++++++
- xbmc/rendering/gles/RenderSystemGLES.h | 2 +
- 8 files changed, 128 insertions(+), 3 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 288e61a..19c7ff4 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -710,7 +710,8 @@ void CGUIFontTTFBase::RenderCharacter(float posX, float posY, const Character *c
- (posY + ch->offsetY + height) * g_graphicsContext.GetGUIScaleY());
- vertex += CPoint(m_originX, m_originY);
- CRect texture(ch->left, ch->top, ch->right, ch->bottom);
-- g_graphicsContext.ClipRect(vertex, texture);
-+ if (!g_Windowing.ScissorsCanEffectClipping())
-+ g_graphicsContext.ClipRect(vertex, texture);
-
- // transform our positions - note, no scaling due to GUI calibration/resolution occurs
- float x[4], y[4], z[4];
-diff --git a/xbmc/guilib/GUIShader.cpp b/xbmc/guilib/GUIShader.cpp
-index 11089b8..53bce09 100644
---- a/xbmc/guilib/GUIShader.cpp
-+++ b/xbmc/guilib/GUIShader.cpp
-@@ -26,6 +26,8 @@
- #include "GUIShader.h"
- #include "MatrixGLES.h"
- #include "utils/log.h"
-+#include "windowing/egl/WinSystemEGL.h"
-+#include "guilib/GraphicContext.h"
-
- CGUIShader::CGUIShader( const char *shader ) : CGLSLShaderProgram("guishader_vert.glsl", shader)
- {
-@@ -86,8 +88,82 @@ bool CGUIShader::OnEnabled()
- {
- // This is called after glUseProgram()
-
-- glUniformMatrix4fv(m_hProj, 1, GL_FALSE, g_matrices.GetMatrix(MM_PROJECTION));
-- glUniformMatrix4fv(m_hModel, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW));
-+ GLfloat *projMatrix = g_matrices.GetMatrix(MM_PROJECTION);
-+ GLfloat *modelMatrix = g_matrices.GetMatrix(MM_MODELVIEW);
-+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, projMatrix);
-+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, modelMatrix);
-+
-+ const TransformMatrix &guiMatrix = g_graphicsContext.GetGUIMatrix();
-+ CRect viewPort; // absolute positions of corners
-+ g_Windowing.GetViewPort(viewPort);
-+
-+ /* glScissor operates in window coordinates. In order that we can use it to
-+ * perform clipping, we must ensure that there is an independent linear
-+ * transformation from the coordinate system used by CGraphicContext::ClipRect
-+ * to window coordinates, separately for X and Y (in other words, no
-+ * rotation or shear is introduced at any stage). To do, this, we need to
-+ * check that zeros are present in the following locations:
-+ *
-+ * GUI matrix:
-+ * / * 0 * * \
-+ * | 0 * * * |
-+ * \ 0 0 * * /
-+ * ^ TransformMatrix::TransformX/Y/ZCoord are only ever called with
-+ * input z = 0, so this column doesn't matter
-+ * Model-view matrix:
-+ * / * 0 0 * \
-+ * | 0 * 0 * |
-+ * | 0 0 * * |
-+ * \ * * * * / <- eye w has no influence on window x/y (last column below
-+ * is either 0 or ignored)
-+ * Projection matrix:
-+ * / * 0 0 0 \
-+ * | 0 * 0 0 |
-+ * | * * * * | <- normalised device coordinate z has no influence on window x/y
-+ * \ 0 0 * 0 /
-+ *
-+ * Some of these zeros are not strictly required to ensure this, but they tend
-+ * to be zeroed in the common case, so by checking for zeros here, we simplify
-+ * the calculation of the window x/y coordinates further down the line.
-+ *
-+ * (Minor detail: we don't quite deal in window coordinates as defined by
-+ * OpenGL, because CRenderSystemGLES::SetScissors flips the Y axis. But all
-+ * that's needed to handle that is an effective negation at the stage where
-+ * Y is in normalised device coordinates.)
-+ */
-+ m_clipPossible = guiMatrix.m[0][1] == 0 &&
-+ guiMatrix.m[1][0] == 0 &&
-+ guiMatrix.m[2][0] == 0 &&
-+ guiMatrix.m[2][1] == 0 &&
-+ modelMatrix[0+1*4] == 0 &&
-+ modelMatrix[0+2*4] == 0 &&
-+ modelMatrix[1+0*4] == 0 &&
-+ modelMatrix[1+2*4] == 0 &&
-+ modelMatrix[2+0*4] == 0 &&
-+ modelMatrix[2+1*4] == 0 &&
-+ projMatrix[0+1*4] == 0 &&
-+ projMatrix[0+2*4] == 0 &&
-+ projMatrix[0+3*4] == 0 &&
-+ projMatrix[1+0*4] == 0 &&
-+ projMatrix[1+2*4] == 0 &&
-+ projMatrix[1+3*4] == 0 &&
-+ projMatrix[3+0*4] == 0 &&
-+ projMatrix[3+1*4] == 0 &&
-+ projMatrix[3+3*4] == 0;
-+ if (m_clipPossible)
-+ {
-+ m_clipXFactor = guiMatrix.m[0][0] * modelMatrix[0+0*4] * projMatrix[0+0*4];
-+ m_clipXOffset = (guiMatrix.m[0][3] * modelMatrix[0+0*4] + modelMatrix[0+3*4]) * projMatrix[0+0*4];
-+ m_clipYFactor = guiMatrix.m[1][1] * modelMatrix[1+1*4] * projMatrix[1+1*4];
-+ m_clipYOffset = (guiMatrix.m[1][3] * modelMatrix[1+1*4] + modelMatrix[1+3*4]) * projMatrix[1+1*4];
-+ float clipW = (guiMatrix.m[2][3] * modelMatrix[2+2*4] + modelMatrix[2+3*4]) * projMatrix[3+2*4];
-+ float xMult = (viewPort.x2 - viewPort.x1) / (2 * clipW);
-+ float yMult = (viewPort.y1 - viewPort.y2) / (2 * clipW); // correct for inverted window coordinate scheme
-+ m_clipXFactor = m_clipXFactor * xMult;
-+ m_clipXOffset = m_clipXOffset * xMult + (viewPort.x2 + viewPort.x1) / 2;
-+ m_clipYFactor = m_clipYFactor * yMult;
-+ m_clipYOffset = m_clipYOffset * yMult + (viewPort.y2 + viewPort.y1) / 2;
-+ }
-
- return true;
- }
-diff --git a/xbmc/guilib/GUIShader.h b/xbmc/guilib/GUIShader.h
-index c7e95aa..86ce4cc 100644
---- a/xbmc/guilib/GUIShader.h
-+++ b/xbmc/guilib/GUIShader.h
-@@ -41,6 +41,11 @@ class CGUIShader : public CGLSLShaderProgram
- GLint GetCord1Loc() { return m_hCord1; }
- GLint GetUniColLoc() { return m_hUniCol; }
- GLint GetCoord0MatrixLoc() { return m_hCoord0Matrix; }
-+ bool HardwareClipIsPossible() { return m_clipPossible; }
-+ GLfloat GetClipXFactor() { return m_clipXFactor; }
-+ GLfloat GetClipXOffset() { return m_clipXOffset; }
-+ GLfloat GetClipYFactor() { return m_clipYFactor; }
-+ GLfloat GetClipYOffset() { return m_clipYOffset; }
-
- protected:
- GLint m_hTex0;
-@@ -56,6 +61,12 @@ class CGUIShader : public CGLSLShaderProgram
-
- GLfloat *m_proj;
- GLfloat *m_model;
-+
-+ bool m_clipPossible;
-+ GLfloat m_clipXFactor;
-+ GLfloat m_clipXOffset;
-+ GLfloat m_clipYFactor;
-+ GLfloat m_clipYOffset;
- };
-
- #endif // GUI_SHADER_H
-diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp
-index 38f17a7..5bffdf5 100644
---- a/xbmc/guilib/GraphicContext.cpp
-+++ b/xbmc/guilib/GraphicContext.cpp
-@@ -167,6 +167,16 @@ void CGraphicContext::ClipRect(CRect &vertex, CRect &texture, CRect *texture2)
- }
- }
-
-+CRect CGraphicContext::GetClipRegion()
-+{
-+ if (m_clipRegions.empty())
-+ return CRect(0, 0, m_iScreenWidth, m_iScreenHeight);
-+ CRect clipRegion(m_clipRegions.top());
-+ if (!m_origins.empty())
-+ clipRegion -= m_origins.top();
-+ return clipRegion;
-+}
-+
- bool CGraphicContext::SetViewPort(float fx, float fy, float fwidth, float fheight, bool intersectPrevious /* = false */)
- {
- // transform coordinates - we may have a rotation which changes the positioning of the
-diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h
-index bab2457..0a27643 100644
---- a/xbmc/guilib/GraphicContext.h
-+++ b/xbmc/guilib/GraphicContext.h
-@@ -199,6 +199,7 @@ class CGraphicContext : public CCriticalSection,
- void ApplyHardwareTransform();
- void RestoreHardwareTransform();
- void ClipRect(CRect &vertex, CRect &texture, CRect *diffuse = NULL);
-+ CRect GetClipRegion();
- inline void AddGUITransform()
- {
- m_transforms.push(m_finalTransform);
-diff --git a/xbmc/rendering/RenderSystem.h b/xbmc/rendering/RenderSystem.h
-index fa64eba..c1dfb93 100644
---- a/xbmc/rendering/RenderSystem.h
-+++ b/xbmc/rendering/RenderSystem.h
-@@ -110,6 +110,8 @@ class CRenderSystemBase
- virtual void GetViewPort(CRect& viewPort) = 0;
- virtual void RestoreViewPort() {};
-
-+ virtual bool ScissorsCanEffectClipping() { return false; }
-+ virtual CRect ClipRectToScissorRect(const CRect &rect) { return CRect(); }
- virtual void SetScissors(const CRect &rect) = 0;
- virtual void ResetScissors() = 0;
-
-diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
-index 653c9ec..deb3afc 100644
---- a/xbmc/rendering/gles/RenderSystemGLES.cpp
-+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
-@@ -533,6 +533,28 @@ void CRenderSystemGLES::SetViewPort(CRect& viewPort)
- m_viewPort[3] = viewPort.Height();
- }
-
-+bool CRenderSystemGLES::ScissorsCanEffectClipping()
-+{
-+ if (m_pGUIshader[m_method])
-+ return m_pGUIshader[m_method]->HardwareClipIsPossible();
-+
-+ return false;
-+}
-+
-+CRect CRenderSystemGLES::ClipRectToScissorRect(const CRect &rect)
-+{
-+ if (!m_pGUIshader[m_method])
-+ return CRect();
-+ float xFactor = m_pGUIshader[m_method]->GetClipXFactor();
-+ float xOffset = m_pGUIshader[m_method]->GetClipXOffset();
-+ float yFactor = m_pGUIshader[m_method]->GetClipYFactor();
-+ float yOffset = m_pGUIshader[m_method]->GetClipYOffset();
-+ return CRect(rect.x1 * xFactor + xOffset,
-+ rect.y1 * yFactor + yOffset,
-+ rect.x2 * xFactor + xOffset,
-+ rect.y2 * yFactor + yOffset);
-+}
-+
- void CRenderSystemGLES::SetScissors(const CRect &rect)
- {
- if (!m_bRenderCreated)
-diff --git a/xbmc/rendering/gles/RenderSystemGLES.h b/xbmc/rendering/gles/RenderSystemGLES.h
-index 98e398a..81ee49e 100644
---- a/xbmc/rendering/gles/RenderSystemGLES.h
-+++ b/xbmc/rendering/gles/RenderSystemGLES.h
-@@ -63,6 +63,8 @@ class CRenderSystemGLES : public CRenderSystemBase
- virtual void SetViewPort(CRect& viewPort);
- virtual void GetViewPort(CRect& viewPort);
-
-+ virtual bool ScissorsCanEffectClipping();
-+ virtual CRect ClipRectToScissorRect(const CRect &rect);
- virtual void SetScissors(const CRect& rect);
- virtual void ResetScissors();
-
---
-1.9.3
-
-
-From 2c2cd66f778cfe80f5addf0e31524f5adf401725 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Thu, 23 Jan 2014 16:42:22 +0000
-Subject: [PATCH 10/82] Increase font cache hit rate by keying on the
- fractional part of m_originX and m_originY *after* they have been through the
- graphics context's transformation matrix, plus the scale/rotation elements of
- the matrix, rather than the origin in the original frame of reference plus
- the complete transformation matrix. All vertices of individual glyph bounding
- boxes are a constant offset from this position, and when the fractional part
- of the translation is a match, the rounding of each vertex will be in the
- same direction; this permits us to calculate the desired vertices from the
- cached ones simply by adding the integer parts of the translations with no
- additional rounding steps.
-
-Note that this requires that software clipping is *not* performed.
----
- xbmc/guilib/GUIFontCache.cpp | 8 +++++++
- xbmc/guilib/GUIFontCache.h | 43 +++++++++++++++++++++++++++++++++++
- xbmc/guilib/GUIFontTTF.cpp | 53 +++++++++++++++++++++++++++++++++++---------
- xbmc/guilib/GUIFontTTF.h | 1 +
- 4 files changed, 95 insertions(+), 10 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp
-index c029713..b66c00b 100644
---- a/xbmc/guilib/GUIFontCache.cpp
-+++ b/xbmc/guilib/GUIFontCache.cpp
-@@ -85,6 +85,9 @@ Value &CGUIFontCache::Lookup(Position &pos,
- else
- {
- /* Cache hit */
-+ /* Update the translation arguments so that they hold the offset to apply
-+ * to the cached values (but only in the dynamic case) */
-+ pos.UpdateWithOffsets(i->m_key.m_pos, scrolling);
- /* Update time in entry and move to the back of the list */
- i->m_lastUsedMillis = nowMillis;
- m_list.get().relocate(m_list.get().end(), m_list.project(i));
-@@ -103,3 +106,8 @@ template void CGUIFontCacheEntry::~CGUIFontCacheEntry();
- template CGUIFontCacheStaticValue &CGUIFontCache::Lookup(CGUIFontCacheStaticPosition &, const vecColors &, const vecText &, uint32_t, float, bool, unsigned int, bool &);
- template void CGUIFontCache::Flush();
-+
-+template void CGUIFontCacheEntry::Reassign::operator()(CGUIFontCacheEntry &entry);
-+template CGUIFontCacheEntry::~CGUIFontCacheEntry();
-+template CGUIFontCacheDynamicValue &CGUIFontCache::Lookup(CGUIFontCacheDynamicPosition &, const vecColors &, const vecText &, uint32_t, float, bool, unsigned int, bool &);
-+template void CGUIFontCache::Flush();
-diff --git a/xbmc/guilib/GUIFontCache.h b/xbmc/guilib/GUIFontCache.h
-index ef65845..d913dee 100644
---- a/xbmc/guilib/GUIFontCache.h
-+++ b/xbmc/guilib/GUIFontCache.h
-@@ -44,6 +44,7 @@
- using namespace boost::multi_index;
-
- #define FONT_CACHE_TIME_LIMIT (1000)
-+#define FONT_CACHE_DIST_LIMIT (0.01)
-
- template class CGUIFontCache;
- class CGUIFontTTFBase;
-@@ -197,6 +198,7 @@ struct CGUIFontCacheStaticPosition
- float m_x;
- float m_y;
- CGUIFontCacheStaticPosition(float x, float y) : m_x(x), m_y(y) {}
-+ void UpdateWithOffsets(const CGUIFontCacheStaticPosition &cached, bool scrolling) {}
- };
-
- typedef std::vector CGUIFontCacheStaticValue;
-@@ -214,4 +216,45 @@ inline float MatrixHashContribution(const CGUIFontCacheKey CGUIFontCacheDynamicValue;
-+
-+inline bool Match(const CGUIFontCacheDynamicPosition &a, const TransformMatrix &a_m,
-+ const CGUIFontCacheDynamicPosition &b, const TransformMatrix &b_m,
-+ bool scrolling)
-+{
-+ float diffX = a.m_x - b.m_x + FONT_CACHE_DIST_LIMIT;
-+ float diffY = a.m_y - b.m_y + FONT_CACHE_DIST_LIMIT;
-+ float diffZ = a.m_z - b.m_z + FONT_CACHE_DIST_LIMIT;
-+ return (scrolling || diffX - floorf(diffX) < 2 * FONT_CACHE_DIST_LIMIT) &&
-+ diffY - floorf(diffY) < 2 * FONT_CACHE_DIST_LIMIT &&
-+ diffZ - floorf(diffZ) < 2 * FONT_CACHE_DIST_LIMIT &&
-+ a_m.m[0][0] == b_m.m[0][0] &&
-+ a_m.m[1][1] == b_m.m[1][1] &&
-+ a_m.m[2][2] == b_m.m[2][2];
-+ // We already know the first 3 columns of both matrices are diagonal, so no need to check the other elements
-+}
-+
-+inline float MatrixHashContribution(const CGUIFontCacheKey &a)
-+{
-+ return 0;
-+}
-+
- #endif
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 19c7ff4..73f0e50 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -132,7 +132,7 @@ class CFreeTypeLibrary
- XBMC_GLOBAL_REF(CFreeTypeLibrary, g_freeTypeLibrary); // our freetype library
- #define g_freeTypeLibrary XBMC_GLOBAL_USE(CFreeTypeLibrary)
-
--CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) : m_staticCache(*this)
-+CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) : m_staticCache(*this), m_dynamicCache(*this)
- {
- m_texture = NULL;
- m_char = NULL;
-@@ -332,13 +332,28 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- Begin();
-
- bool dirtyCache;
-+ bool hardwareClipping = g_Windowing.ScissorsCanEffectClipping();
- CGUIFontCacheStaticPosition staticPos(x, y);
-- std::vector &vertices = m_staticCache.Lookup(staticPos,
-- colors, text,
-- alignment, maxPixelWidth,
-- scrolling,
-- XbmcThreads::SystemClockMillis(),
-- dirtyCache);
-+ CGUIFontCacheDynamicPosition dynamicPos;
-+ if (hardwareClipping)
-+ {
-+ dynamicPos = CGUIFontCacheDynamicPosition(g_graphicsContext.ScaleFinalXCoord(x, y),
-+ g_graphicsContext.ScaleFinalYCoord(x, y),
-+ g_graphicsContext.ScaleFinalZCoord(x, y));
-+ }
-+ std::vector &vertices = hardwareClipping ?
-+ m_dynamicCache.Lookup(dynamicPos,
-+ colors, text,
-+ alignment, maxPixelWidth,
-+ scrolling,
-+ XbmcThreads::SystemClockMillis(),
-+ dirtyCache) :
-+ m_staticCache.Lookup(staticPos,
-+ colors, text,
-+ alignment, maxPixelWidth,
-+ scrolling,
-+ XbmcThreads::SystemClockMillis(),
-+ dirtyCache);
- if (dirtyCache)
- {
- // save the origin, which is scaled separately
-@@ -441,10 +456,28 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- else
- cursorX += ch->advance;
- }
-+ if (hardwareClipping)
-+ /* Append the new vertices (which we have just constructed in the cache)
-+ * to the set collected since the first Begin() call */
-+ m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-+ }
-+ else if (hardwareClipping)
-+ {
-+ /* Apply the translation offset to the vertices from the cache after
-+ * appending them to the set collected since the first Begin() call */
-+ m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-+ SVertex *v;
-+ for (v = &*m_vertex.end() - vertices.size(); v != &*m_vertex.end(); v++)
-+ {
-+ v->x += dynamicPos.m_x;
-+ v->y += dynamicPos.m_y;
-+ v->z += dynamicPos.m_z;
-+ }
- }
-- /* Append the new vertices (from the cache or otherwise) to the set collected
-- * since the first Begin() call */
-- m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-+ if (!hardwareClipping)
-+ /* Append the new vertices (from the cache or otherwise) to the set collected
-+ * since the first Begin() call */
-+ m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-
- End();
- }
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index 7cb4669..78445ab 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -170,6 +170,7 @@ class CGUIFontTTFBase
- CStdString m_strFileName;
-
- CGUIFontCache m_staticCache;
-+ CGUIFontCache m_dynamicCache;
-
- private:
- virtual bool FirstBegin() = 0;
---
-1.9.3
-
-
-From aa09af31e58262051e8571223cc6fcefaf8d1697 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 8 Jan 2014 12:16:33 +0000
-Subject: [PATCH 11/82] Rewrite of scrolling text code.
-
-No longer shuffles the string round to minimise the number of characters
-before the clipping rectangle; this doesn't save much on rendering time but
-does harm the effectiveness of the cache. Now uses a pixel offset into the
-string rather than a character + pixel offset, and plots the entire string
-every time (execpt when the wrap point is visible, in which case the entire
-string is plotted twice).
-
-It also makes motion smoother, because (possibly unintentionally) the
-previous code preferred to align the scroll offset with character boundaries.
-This would lead to uneven changes of position, especially when the width of
-the character currently being scrolled off the edge was only slightly more
-than an integral multiple of the scroll increment.
----
- xbmc/guilib/GUIFadeLabelControl.cpp | 8 +--
- xbmc/guilib/GUIFont.cpp | 123 +++++++++++++-----------------------
- xbmc/guilib/GUIFont.h | 17 ++---
- xbmc/guilib/GUIRSSControl.cpp | 6 +-
- xbmc/utils/RssReader.cpp | 2 +-
- xbmc/utils/RssReader.h | 2 +-
- 6 files changed, 58 insertions(+), 100 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFadeLabelControl.cpp b/xbmc/guilib/GUIFadeLabelControl.cpp
-index d594c04..86ee73a 100644
---- a/xbmc/guilib/GUIFadeLabelControl.cpp
-+++ b/xbmc/guilib/GUIFadeLabelControl.cpp
-@@ -109,18 +109,14 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d
- bool moveToNextLabel = false;
- if (!m_scrollOut)
- {
-- vecText text;
-- m_textLayout.GetFirstText(text);
-- if (m_scrollInfo.characterPos && m_scrollInfo.characterPos < text.size())
-- text.erase(text.begin(), text.begin() + min((int)m_scrollInfo.characterPos - 1, (int)text.size()));
-- if (m_label.font->GetTextWidth(text) < m_width)
-+ if (m_scrollInfo.pixelPos + m_width > m_scrollInfo.m_textWidth)
- {
- if (m_fadeAnim.GetProcess() != ANIM_PROCESS_NORMAL)
- m_fadeAnim.QueueAnimation(ANIM_PROCESS_NORMAL);
- moveToNextLabel = true;
- }
- }
-- else if (m_scrollInfo.characterPos > m_textLayout.GetTextLength())
-+ else if (m_scrollInfo.pixelPos > m_scrollInfo.m_textWidth)
- moveToNextLabel = true;
-
- // apply the fading animation
-diff --git a/xbmc/guilib/GUIFont.cpp b/xbmc/guilib/GUIFont.cpp
-index a7ee668..eb8efdb 100644
---- a/xbmc/guilib/GUIFont.cpp
-+++ b/xbmc/guilib/GUIFont.cpp
-@@ -36,7 +36,12 @@ CScrollInfo::CScrollInfo(unsigned int wait /* = 50 */, float pos /* = 0 */,
- initialWait = wait;
- initialPos = pos;
- SetSpeed(speed ? speed : defaultSpeed);
-- g_charsetConverter.utf8ToW(scrollSuffix, suffix);
-+ CStdStringW wsuffix;
-+ g_charsetConverter.utf8ToW(scrollSuffix, wsuffix);
-+ suffix.clear();
-+ suffix.reserve(wsuffix.size());
-+ for (vecText::size_type i = 0; i < wsuffix.size(); i++)
-+ suffix.push_back(wsuffix[i]);
- Reset();
- }
-
-@@ -115,11 +120,12 @@ bool CGUIFont::UpdateScrollInfo(const vecText &text, CScrollInfo &scrollInfo)
- {
- // draw at our scroll position
- // we handle the scrolling as follows:
-- // We scroll on a per-pixel basis up until we have scrolled the first character outside
-- // of our viewport, whereby we cycle the string around, and reset the scroll position.
-- //
-- // pixelPos is the amount in pixels to move the string by.
-- // characterPos is the amount in characters to rotate the string by.
-+ // We scroll on a per-pixel basis (eschewing the use of character indices
-+ // which were also in use previously). The complete string, including suffix,
-+ // is plotted to achieve the desired effect - normally just the one time, but
-+ // if there is a wrap point within the viewport then it will be plotted twice.
-+ // If the string is smaller than the viewport, then it may be plotted even
-+ // more times than that.
- //
- if (scrollInfo.waitTime)
- {
-@@ -135,54 +141,19 @@ bool CGUIFont::UpdateScrollInfo(const vecText &text, CScrollInfo &scrollInfo)
- // move along by the appropriate scroll amount
- float scrollAmount = fabs(scrollInfo.GetPixelsPerFrame() * g_graphicsContext.GetGUIScaleX());
-
-- if (scrollInfo.pixelSpeed > 0)
-+ if (!scrollInfo.m_widthValid)
- {
-- // we want to move scrollAmount, grab the next character
-- float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
-- if (scrollInfo.pixelPos + scrollAmount < charWidth)
-- scrollInfo.pixelPos += scrollAmount; // within the current character
-- else
-- { // past the current character, decrement scrollAmount by the charWidth and move to the next character
-- while (scrollInfo.pixelPos + scrollAmount >= charWidth)
-- {
-- scrollAmount -= (charWidth - scrollInfo.pixelPos);
-- scrollInfo.pixelPos = 0;
-- scrollInfo.characterPos++;
-- if (scrollInfo.characterPos >= text.size() + scrollInfo.suffix.size())
-- {
-- scrollInfo.Reset();
-- break;
-- }
-- charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
-- }
-- }
-- }
-- else if (scrollInfo.pixelSpeed < 0)
-- { // scrolling backwards
-- // we want to move scrollAmount, grab the next character
-- float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
-- if (scrollInfo.pixelPos + scrollAmount < charWidth)
-- scrollInfo.pixelPos += scrollAmount; // within the current character
-- else
-- { // past the current character, decrement scrollAmount by the charWidth and move to the next character
-- while (scrollInfo.pixelPos + scrollAmount >= charWidth)
-- {
-- scrollAmount -= (charWidth - scrollInfo.pixelPos);
-- scrollInfo.pixelPos = 0;
-- if (scrollInfo.characterPos == 0)
-- {
-- scrollInfo.Reset();
-- scrollInfo.characterPos = text.size() + scrollInfo.suffix.size() - 1;
-- break;
-- }
-- scrollInfo.characterPos--;
-- charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
-- }
-- }
-+ /* Calculate the pixel width of the complete string */
-+ scrollInfo.m_textWidth = GetTextWidth(text);
-+ scrollInfo.m_totalWidth = scrollInfo.m_textWidth + GetTextWidth(scrollInfo.suffix);
-+ scrollInfo.m_widthValid = true;
- }
-+ scrollInfo.pixelPos += scrollAmount;
-+ assert(scrollInfo.m_totalWidth != 0);
-+ while (scrollInfo.pixelPos >= scrollInfo.m_totalWidth)
-+ scrollInfo.pixelPos -= scrollInfo.m_totalWidth;
-
-- if(scrollInfo.characterPos != old.characterPos
-- || scrollInfo.pixelPos != old.pixelPos)
-+ if (scrollInfo.pixelPos != old.pixelPos)
- return true;
- else
- return false;
-@@ -194,39 +165,27 @@ void CGUIFont::DrawScrollingText(float x, float y, const vecColors &colors, colo
- if (!m_font) return;
- if (!shadowColor) shadowColor = m_shadowColor;
-
-- float spaceWidth = GetCharWidth(L' ');
-- // max chars on screen + extra margin chars
-- vecText::size_type maxChars =
-- std::min(
-- (text.size() + (vecText::size_type)scrollInfo.suffix.size()),
-- (vecText::size_type)((maxWidth * 1.05f) / spaceWidth));
--
- if (!text.size() || ClippedRegionIsEmpty(x, y, maxWidth, alignment))
- return; // nothing to render
-
-- maxWidth = ROUND((maxWidth + scrollInfo.pixelPos) / g_graphicsContext.GetGUIScaleX());
-+ if (!scrollInfo.m_widthValid)
-+ {
-+ /* Calculate the pixel width of the complete string */
-+ scrollInfo.m_textWidth = GetTextWidth(text);
-+ scrollInfo.m_totalWidth = scrollInfo.m_textWidth + GetTextWidth(scrollInfo.suffix);
-+ scrollInfo.m_widthValid = true;
-+ }
-+
-+ assert(scrollInfo.m_totalWidth != 0);
-+
-+ float textPixelWidth = ROUND(scrollInfo.m_textWidth / g_graphicsContext.GetGUIScaleX());
-+ float suffixPixelWidth = ROUND((scrollInfo.m_totalWidth - scrollInfo.m_textWidth) / g_graphicsContext.GetGUIScaleX());
-
-- float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
- float offset;
- if(scrollInfo.pixelSpeed >= 0)
- offset = scrollInfo.pixelPos;
- else
-- offset = charWidth - scrollInfo.pixelPos;
--
-- // Now rotate our string as needed, only take a slightly larger then visible part of the text.
-- unsigned int pos = scrollInfo.characterPos;
-- vecText renderText;
-- renderText.reserve(maxChars);
-- for (vecText::size_type i = 0; i < maxChars; i++)
-- {
-- if (pos >= text.size() + scrollInfo.suffix.size())
-- pos = 0;
-- if (pos < text.size())
-- renderText.push_back(text[pos]);
-- else
-- renderText.push_back(scrollInfo.suffix[pos - text.size()]);
-- pos++;
-- }
-+ offset = scrollInfo.m_totalWidth - scrollInfo.pixelPos;
-
- vecColors renderColors;
- for (unsigned int i = 0; i < colors.size(); i++)
-@@ -239,9 +198,17 @@ void CGUIFont::DrawScrollingText(float x, float y, const vecColors &colors, colo
- vecColors shadowColors;
- for (unsigned int i = 0; i < renderColors.size(); i++)
- shadowColors.push_back((renderColors[i] & 0xff000000) != 0 ? shadowColor : 0);
-- m_font->DrawTextInternal(x - offset + 1, y + 1, shadowColors, renderText, alignment, maxWidth + m_font->GetLineHeight(2.0f), scroll);
-+ for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
-+ {
-+ m_font->DrawTextInternal(x + dx + 1, y + 1, shadowColors, text, alignment, textPixelWidth, scroll);
-+ m_font->DrawTextInternal(x + dx + scrollInfo.m_textWidth + 1, y + 1, shadowColors, scrollInfo.suffix, alignment, suffixPixelWidth, scroll);
-+ }
-+ }
-+ for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
-+ {
-+ m_font->DrawTextInternal(x + dx, y, renderColors, text, alignment, textPixelWidth, scroll);
-+ m_font->DrawTextInternal(x + dx + scrollInfo.m_textWidth, y, renderColors, scrollInfo.suffix, alignment, suffixPixelWidth, scroll);
- }
-- m_font->DrawTextInternal(x - offset, y, renderColors, renderText, alignment, maxWidth + m_font->GetLineHeight(2.0f), scroll);
-
- g_graphicsContext.RestoreClipRegion();
- }
-diff --git a/xbmc/guilib/GUIFont.h b/xbmc/guilib/GUIFont.h
-index c55db48..09cf9b3 100644
---- a/xbmc/guilib/GUIFont.h
-+++ b/xbmc/guilib/GUIFont.h
-@@ -64,7 +64,6 @@ class CScrollInfo
- void Reset()
- {
- waitTime = initialWait;
-- characterPos = 0;
- // pixelPos is where we start the current letter, so is measured
- // to the left of the text rendering's left edge. Thus, a negative
- // value will mean the text starts to the right
-@@ -72,25 +71,19 @@ class CScrollInfo
- // privates:
- m_averageFrameTime = 1000.f / abs(defaultSpeed);
- m_lastFrameTime = 0;
-- }
-- uint32_t GetCurrentChar(const vecText &text) const
-- {
-- assert(text.size());
-- if (characterPos < text.size())
-- return text[characterPos];
-- else if (characterPos < text.size() + suffix.size())
-- return suffix[characterPos - text.size()];
-- return text[0];
-+ m_widthValid = false;
- }
- float GetPixelsPerFrame();
-
- float pixelPos;
- float pixelSpeed;
- unsigned int waitTime;
-- unsigned int characterPos;
- unsigned int initialWait;
- float initialPos;
-- CStdStringW suffix;
-+ vecText suffix;
-+ mutable float m_textWidth;
-+ mutable float m_totalWidth;
-+ mutable bool m_widthValid;
-
- static const int defaultSpeed = 60;
- private:
-diff --git a/xbmc/guilib/GUIRSSControl.cpp b/xbmc/guilib/GUIRSSControl.cpp
-index 712e118..203c138 100644
---- a/xbmc/guilib/GUIRSSControl.cpp
-+++ b/xbmc/guilib/GUIRSSControl.cpp
-@@ -119,7 +119,9 @@ void CGUIRSSControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyre
- dirty = true;
-
- if (CRssManager::Get().GetReader(GetID(), GetParentID(), this, m_pReader))
-- m_scrollInfo.characterPos = m_pReader->m_SavedScrollPos;
-+ {
-+ m_scrollInfo.pixelPos = m_pReader->m_savedScrollPixelPos;
-+ }
- else
- {
- if (m_strRSSTags != "")
-@@ -177,7 +179,7 @@ void CGUIRSSControl::Render()
- if (m_pReader)
- {
- m_pReader->CheckForUpdates();
-- m_pReader->m_SavedScrollPos = m_scrollInfo.characterPos;
-+ m_pReader->m_savedScrollPixelPos = m_scrollInfo.pixelPos;
- }
- }
- CGUIControl::Render();
-diff --git a/xbmc/utils/RssReader.cpp b/xbmc/utils/RssReader.cpp
-index 12bbeb5..505a02d 100644
---- a/xbmc/utils/RssReader.cpp
-+++ b/xbmc/utils/RssReader.cpp
-@@ -54,7 +54,7 @@ CRssReader::CRssReader() : CThread("RSSReader")
- m_pObserver = NULL;
- m_spacesBetweenFeeds = 0;
- m_bIsRunning = false;
-- m_SavedScrollPos = 0;
-+ m_savedScrollPixelPos = 0;
- m_rtlText = false;
- m_requestRefresh = false;
- }
-diff --git a/xbmc/utils/RssReader.h b/xbmc/utils/RssReader.h
-index 2c6f366..b74faf2 100644
---- a/xbmc/utils/RssReader.h
-+++ b/xbmc/utils/RssReader.h
-@@ -43,7 +43,7 @@ class CRssReader : public CThread
- void SetObserver(IRssObserver* observer);
- void CheckForUpdates();
- void requestRefresh();
-- unsigned int m_SavedScrollPos;
-+ float m_savedScrollPixelPos;
-
- private:
- void Process();
---
-1.9.3
-
-
-From 08ae1b29d2987df3738787df1267ddfe898df472 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Mon, 27 Jan 2014 23:21:10 +0000
-Subject: [PATCH 12/82] Move the application of the translation offsets into
- the GLES code. Still all pure software at this stage. Main change is in the
- data types at the interface between CGUIFontTTFBase and CGUIFontTTFGL. The
- old way (array of vertices in m_vertex) are retained in addition, for the
- sake`of cases that need to use software clipping on GLES, as well as for DX
- and GL support where the new scheme is not (yet?) used.
-
----
- xbmc/guilib/GUIFontTTF.cpp | 19 +++---------
- xbmc/guilib/GUIFontTTF.h | 17 +++++++++++
- xbmc/guilib/GUIFontTTFGL.cpp | 72 ++++++++++++++++++++++++++++++++------------
- 3 files changed, 73 insertions(+), 35 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index 73f0e50..ad0a53b 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -215,6 +215,7 @@ void CGUIFontTTFBase::Clear()
- g_freeTypeLibrary.ReleaseStroker(m_stroker);
- m_stroker = NULL;
-
-+ m_vertexTrans.clear();
- m_vertex.clear();
- }
-
-@@ -310,6 +311,7 @@ void CGUIFontTTFBase::Begin()
- {
- if (m_nestedBeginCount == 0 && m_texture != NULL && FirstBegin())
- {
-+ m_vertexTrans.clear();
- m_vertex.clear();
- }
- // Keep track of the nested begin/end calls.
-@@ -457,23 +459,10 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- cursorX += ch->advance;
- }
- if (hardwareClipping)
-- /* Append the new vertices (which we have just constructed in the cache)
-- * to the set collected since the first Begin() call */
-- m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-+ m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertices));
- }
- else if (hardwareClipping)
-- {
-- /* Apply the translation offset to the vertices from the cache after
-- * appending them to the set collected since the first Begin() call */
-- m_vertex.insert(m_vertex.end(), vertices.begin(), vertices.end());
-- SVertex *v;
-- for (v = &*m_vertex.end() - vertices.size(); v != &*m_vertex.end(); v++)
-- {
-- v->x += dynamicPos.m_x;
-- v->y += dynamicPos.m_y;
-- v->z += dynamicPos.m_z;
-- }
-- }
-+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertices));
- if (!hardwareClipping)
- /* Append the new vertices (from the cache or otherwise) to the set collected
- * since the first Begin() call */
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index 78445ab..c71f90d 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -61,6 +61,14 @@ struct SVertex
- unsigned char r, g, b, a;
- #endif
- float u, v;
-+ struct SVertex Offset(float translate[3]) const
-+ {
-+ SVertex out = *this;
-+ out.x += translate[0];
-+ out.y += translate[1];
-+ out.z += translate[2];
-+ return out;
-+ }
- };
-
-
-@@ -160,6 +168,15 @@ class CGUIFontTTFBase
- bool m_bTextureLoaded;
- unsigned int m_nTexture;
-
-+ struct CTranslatedVertices
-+ {
-+ float translateX;
-+ float translateY;
-+ float translateZ;
-+ const std::vector *vertexBuffer;
-+ CTranslatedVertices(float translateX, float translateY, float translateZ, const std::vector *vertexBuffer) : translateX(translateX), translateY(translateY), translateZ(translateZ), vertexBuffer(vertexBuffer) {}
-+ };
-+ std::vector m_vertexTrans;
- std::vector m_vertex;
-
- float m_textureScaleX;
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index cb56987..f6aa081 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -146,34 +146,65 @@ void CGUIFontTTFGL::LastEnd()
- GLint colLoc = g_Windowing.GUIShaderGetCol();
- GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
-
-- // stack object until VBOs will be used
-- std::vector vecVertices( 6 * (m_vertex.size() / 4) );
-- SVertex *vertices = &vecVertices[0];
-+ // Enable the attributes used by this shader
-+ glEnableVertexAttribArray(posLoc);
-+ glEnableVertexAttribArray(colLoc);
-+ glEnableVertexAttribArray(tex0Loc);
-
-- for (size_t i=0; i 0)
- {
-- *vertices++ = m_vertex[i];
-- *vertices++ = m_vertex[i+1];
-- *vertices++ = m_vertex[i+2];
-+ // Deal with vertices that had to use software clipping
-+ std::vector vecVertices( 6 * (m_vertex.size() / 4) );
-+ SVertex *vertices = &vecVertices[0];
-
-- *vertices++ = m_vertex[i+1];
-- *vertices++ = m_vertex[i+3];
-- *vertices++ = m_vertex[i+2];
-- }
-+ for (size_t i=0; i 0)
-+ {
-+ // Deal with the vertices that can be hardware clipped and therefore translated
-+ std::vector vecVertices;
-+ for (size_t i = 0; i < m_vertexTrans.size(); i++)
-+ {
-+ float translate[3] = { m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ };
-+ for (size_t j = 0; j < m_vertexTrans[i].vertexBuffer->size(); j += 4)
-+ {
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+3].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2].Offset(translate));
-+ }
-+ }
-+ SVertex *vertices = &vecVertices[0];
-
-- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, x));
-+ // Normalize color values. Does not affect Performance at all.
-+ glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, r));
-+ glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, u));
-+
-+ glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-+ }
-
-+ // Disable the attributes used by this shader
- glDisableVertexAttribArray(posLoc);
- glDisableVertexAttribArray(colLoc);
- glDisableVertexAttribArray(tex0Loc);
-@@ -201,6 +232,7 @@ CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight)
- if (m_textureHeight < newHeight)
- CLog::Log(LOGWARNING, "%s: allocated new texture with height of %d, requested %d", __FUNCTION__, m_textureHeight, newHeight);
- m_staticCache.Flush();
-+ m_dynamicCache.Flush();
-
- memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch());
- if (m_texture)
---
-1.9.3
-
-
-From 96e5d3e05b9ac2cef47d2e2a6fc13c407f1f672e Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 15 Jan 2014 15:28:06 +0000
-Subject: [PATCH 13/82] Rather than applying the translation offsets to the
- vertices, now applies them to the model view matrix from the top of the
- matrix stack and pushes it over to OpenGL. The vertices themselves are still
- all held client-side.
-
----
- xbmc/guilib/GUIFontTTF.h | 8 -------
- xbmc/guilib/GUIFontTTFGL.cpp | 40 +++++++++++++++++++++-----------
- xbmc/guilib/GUIShader.h | 1 +
- xbmc/rendering/gles/RenderSystemGLES.cpp | 8 +++++++
- xbmc/rendering/gles/RenderSystemGLES.h | 1 +
- 5 files changed, 36 insertions(+), 22 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index c71f90d..fde2085 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -61,14 +61,6 @@ struct SVertex
- unsigned char r, g, b, a;
- #endif
- float u, v;
-- struct SVertex Offset(float translate[3]) const
-- {
-- SVertex out = *this;
-- out.x += translate[0];
-- out.y += translate[1];
-- out.z += translate[2];
-- return out;
-- }
- };
-
-
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index f6aa081..fbffaa0 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -29,6 +29,7 @@
- #include "utils/log.h"
- #include "utils/GLUtils.h"
- #include "windowing/WindowingFactory.h"
-+#include "guilib/MatrixGLES.h"
-
- // stuff for freetype
- #include
-@@ -145,6 +146,7 @@ void CGUIFontTTFGL::LastEnd()
- GLint posLoc = g_Windowing.GUIShaderGetPos();
- GLint colLoc = g_Windowing.GUIShaderGetCol();
- GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
-+ GLint modelLoc = g_Windowing.GUIShaderGetModel();
-
- // Enable the attributes used by this shader
- glEnableVertexAttribArray(posLoc);
-@@ -183,25 +185,35 @@ void CGUIFontTTFGL::LastEnd()
- std::vector vecVertices;
- for (size_t i = 0; i < m_vertexTrans.size(); i++)
- {
-- float translate[3] = { m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ };
-+ // Apply the translation to the currently active (top-of-stack) model view matrix
-+ g_matrices.MatrixMode(MM_MODELVIEW);
-+ g_matrices.PushMatrix();
-+ g_matrices.Translatef(m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ);
-+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW));
-+
-+ vecVertices.clear();
- for (size_t j = 0; j < m_vertexTrans[i].vertexBuffer->size(); j += 4)
- {
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j].Offset(translate));
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1].Offset(translate));
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2].Offset(translate));
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1].Offset(translate));
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+3].Offset(translate));
-- vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2].Offset(translate));
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j]);
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1]);
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2]);
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+1]);
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+3]);
-+ vecVertices.push_back((*m_vertexTrans[i].vertexBuffer)[j+2]);
- }
-- }
-- SVertex *vertices = &vecVertices[0];
-+ SVertex *vertices = &vecVertices[0];
-
-- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, x));
-- // Normalize color values. Does not affect Performance at all.
-- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, r));
-- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, u));
-+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, x));
-+ // Normalize color values. Does not affect Performance at all.
-+ glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, r));
-+ glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, u));
-
-- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-+ glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-+
-+ g_matrices.PopMatrix();
-+ }
-+ // Restore the original model view matrix
-+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW));
- }
-
- // Disable the attributes used by this shader
-diff --git a/xbmc/guilib/GUIShader.h b/xbmc/guilib/GUIShader.h
-index 86ce4cc..ba01956 100644
---- a/xbmc/guilib/GUIShader.h
-+++ b/xbmc/guilib/GUIShader.h
-@@ -41,6 +41,7 @@ class CGUIShader : public CGLSLShaderProgram
- GLint GetCord1Loc() { return m_hCord1; }
- GLint GetUniColLoc() { return m_hUniCol; }
- GLint GetCoord0MatrixLoc() { return m_hCoord0Matrix; }
-+ GLint GetModelLoc() { return m_hModel; }
- bool HardwareClipIsPossible() { return m_clipPossible; }
- GLfloat GetClipXFactor() { return m_clipXFactor; }
- GLfloat GetClipXOffset() { return m_clipXOffset; }
-diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
-index deb3afc..0904d1f 100644
---- a/xbmc/rendering/gles/RenderSystemGLES.cpp
-+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
-@@ -691,4 +691,12 @@ bool CRenderSystemGLES::SupportsStereo(RENDER_STEREO_MODE mode)
- }
- }
-
-+GLint CRenderSystemGLES::GUIShaderGetModel()
-+{
-+ if (m_pGUIshader[m_method])
-+ return m_pGUIshader[m_method]->GetModelLoc();
-+
-+ return -1;
-+}
-+
- #endif
-diff --git a/xbmc/rendering/gles/RenderSystemGLES.h b/xbmc/rendering/gles/RenderSystemGLES.h
-index 81ee49e..d2f9cd1 100644
---- a/xbmc/rendering/gles/RenderSystemGLES.h
-+++ b/xbmc/rendering/gles/RenderSystemGLES.h
-@@ -91,6 +91,7 @@ class CRenderSystemGLES : public CRenderSystemBase
- GLint GUIShaderGetCoord1();
- GLint GUIShaderGetUniCol();
- GLint GUIShaderGetCoord0Matrix();
-+ GLint GUIShaderGetModel();
-
- protected:
- virtual void SetVSyncImpl(bool enable) = 0;
---
-1.9.3
-
-
-From a831b39d8b967665371ccc99a9e8ee1679d8ae54 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 29 Jan 2014 13:21:19 +0000
-Subject: [PATCH 14/82] Enable hardware clipping.
-
----
- xbmc/guilib/GUIFontTTF.cpp | 4 ++--
- xbmc/guilib/GUIFontTTF.h | 5 ++++-
- xbmc/guilib/GUIFontTTFGL.cpp | 6 ++++++
- 3 files changed, 12 insertions(+), 3 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
-index ad0a53b..4dc4c8e 100644
---- a/xbmc/guilib/GUIFontTTF.cpp
-+++ b/xbmc/guilib/GUIFontTTF.cpp
-@@ -459,10 +459,10 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors
- cursorX += ch->advance;
- }
- if (hardwareClipping)
-- m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertices));
-+ m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertices, g_graphicsContext.GetClipRegion()));
- }
- else if (hardwareClipping)
-- m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertices));
-+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertices, g_graphicsContext.GetClipRegion()));
- if (!hardwareClipping)
- /* Append the new vertices (from the cache or otherwise) to the set collected
- * since the first Begin() call */
-diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
-index fde2085..5e7c31f 100644
---- a/xbmc/guilib/GUIFontTTF.h
-+++ b/xbmc/guilib/GUIFontTTF.h
-@@ -27,6 +27,8 @@
- *
- */
-
-+#include "Geometry.h"
-+
- // forward definition
- class CBaseTexture;
-
-@@ -166,7 +168,8 @@ class CGUIFontTTFBase
- float translateY;
- float translateZ;
- const std::vector *vertexBuffer;
-- CTranslatedVertices(float translateX, float translateY, float translateZ, const std::vector *vertexBuffer) : translateX(translateX), translateY(translateY), translateZ(translateZ), vertexBuffer(vertexBuffer) {}
-+ CRect clip;
-+ CTranslatedVertices(float translateX, float translateY, float translateZ, const std::vector *vertexBuffer, const CRect &clip) : translateX(translateX), translateY(translateY), translateZ(translateZ), vertexBuffer(vertexBuffer), clip(clip) {}
- };
- std::vector m_vertexTrans;
- std::vector m_vertex;
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index fbffaa0..b7618e1 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -185,6 +185,10 @@ void CGUIFontTTFGL::LastEnd()
- std::vector vecVertices;
- for (size_t i = 0; i < m_vertexTrans.size(); i++)
- {
-+ // Apply the clip rectangle
-+ CRect clip = g_Windowing.ClipRectToScissorRect(m_vertexTrans[i].clip);
-+ g_graphicsContext.SetScissors(clip);
-+
- // Apply the translation to the currently active (top-of-stack) model view matrix
- g_matrices.MatrixMode(MM_MODELVIEW);
- g_matrices.PushMatrix();
-@@ -212,6 +216,8 @@ void CGUIFontTTFGL::LastEnd()
-
- g_matrices.PopMatrix();
- }
-+ // Restore the original scissor rectangle
-+ g_graphicsContext.ResetScissors();
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW));
- }
---
-1.9.3
-
-
-From c65c7b0f23d31b1677b0cd60355eb28d05865977 Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 15 Jan 2014 15:32:51 +0000
-Subject: [PATCH 15/82] Move the vertex data across to a vertex buffer object
- just prior to drawing.
-
----
- xbmc/guilib/GUIFontTTFGL.cpp | 24 +++++++++++++++++++-----
- 1 file changed, 19 insertions(+), 5 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
-index b7618e1..0df3749 100644
---- a/xbmc/guilib/GUIFontTTFGL.cpp
-+++ b/xbmc/guilib/GUIFontTTFGL.cpp
-@@ -207,12 +207,24 @@ void CGUIFontTTFGL::LastEnd()
- }
- SVertex *vertices = &vecVertices[0];
-
-- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, x));
-- // Normalize color values. Does not affect Performance at all.
-- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, r));
-- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, u));
--
-+ // Generate a unique buffer object name and put it in vertexBuffer
-+ GLuint vertexBuffer;
-+ glGenBuffers(1, &vertexBuffer);
-+ // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point
-+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
-+ // Create a data store for the buffer object bound to the GL_ARRAY_BUFFER
-+ // binding point (i.e. our buffer object) and initialise it from the
-+ // specified client-side pointer
-+ glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof *vertices, vertices, GL_STATIC_DRAW);
-+ // Set up the offsets of the various vertex attributes within the buffer
-+ // object bound to GL_ARRAY_BUFFER
-+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) offsetof(SVertex, x));
-+ glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (GLvoid *) offsetof(SVertex, r));
-+ glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) offsetof(SVertex, u));
-+ // Do the actual drawing operation, using the full set of vertices in the buffer
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-+ // Release the buffer name for reuse
-+ glDeleteBuffers(1, &vertexBuffer);
-
- g_matrices.PopMatrix();
- }
-@@ -220,6 +232,8 @@ void CGUIFontTTFGL::LastEnd()
- g_graphicsContext.ResetScissors();
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW));
-+ // Unbind GL_ARRAY_BUFFER
-+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- // Disable the attributes used by this shader
---
-1.9.3
-
-
-From aff1d0b71b7a455daba6bbd29496fcdc9169e37e Mon Sep 17 00:00:00 2001
-From: Ben Avison
-Date: Wed, 15 Jan 2014 16:04:04 +0000
-Subject: [PATCH 16/82] Move vertex data into an OpenGL VBO when the font cache
- entry is populated. The font cache now stores the "name" (handle) of the VBO,
- rather than a vector of vertices.
-
----
- xbmc/guilib/GUIFontCache.cpp | 6 ++++
- xbmc/guilib/GUIFontCache.h | 30 +++++++++++++++++-
- xbmc/guilib/GUIFontTTF.cpp | 15 +++++++--
- xbmc/guilib/GUIFontTTF.h | 7 +++--
- xbmc/guilib/GUIFontTTFGL.cpp | 74 ++++++++++++++++++++++++++++++--------------
- xbmc/guilib/GUIFontTTFGL.h | 5 +++
- 6 files changed, 107 insertions(+), 30 deletions(-)
-
-diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp
-index b66c00b..895fa72 100644
---- a/xbmc/guilib/GUIFontCache.cpp
-+++ b/xbmc/guilib/GUIFontCache.cpp
-@@ -111,3 +111,9 @@ template void CGUIFontCacheEntry::~CGUIFontCacheEntry();
- template CGUIFontCacheDynamicValue &CGUIFontCache::Lookup(CGUIFontCacheDynamicPosition &, const vecColors &, const vecText &, uint32_t, float, bool, unsigned int, bool &);
- template void CGUIFontCache::Flush();
-+
-+void CVertexBuffer::clear()
-+{
-+ if (m_font != NULL)
-+ m_font->DestroyVertexBuffer(*this);
-+}
-diff --git a/xbmc/guilib/GUIFontCache.h b/xbmc/guilib/GUIFontCache.h
-index d913dee..ff766bf 100644
---- a/xbmc/guilib/GUIFontCache.h
-+++ b/xbmc/guilib/GUIFontCache.h
-@@ -234,7 +234,35 @@ struct CGUIFontCacheDynamicPosition
- }
- };
-
--typedef std::vector