diff --git a/packages/mediacenter/kodi-theme-Confluence/package.mk b/packages/mediacenter/kodi-theme-Confluence/package.mk index 012947c84c..98bf3af4da 100644 --- a/packages/mediacenter/kodi-theme-Confluence/package.mk +++ b/packages/mediacenter/kodi-theme-Confluence/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="kodi-theme-Confluence" -PKG_VERSION="14-7cc53a9" +PKG_VERSION="15.0-beta1-56af059" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 1e9b8fcfd5..e6dc432fbb 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -17,14 +17,14 @@ ################################################################################ PKG_NAME="kodi" -PKG_VERSION="14-7cc53a9" +PKG_VERSION="15.0-beta1-56af059" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.kodi.tv" 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 tinyxml libjpeg-turbo libpng tiff freetype jasper libogg libcdio libmodplug libmpeg2 taglib libxml2 libxslt yajl sqlite libvorbis ffmpeg kodi:host" -PKG_DEPENDS_HOST="toolchain" +PKG_DEPENDS_TARGET="toolchain kodi:host libsquish boost Python zlib bzip2 systemd pciutils lzo pcre swig:host libass curl rtmpdump fontconfig fribidi tinyxml libjpeg-turbo libpng tiff freetype jasper libogg libcdio libmpeg2 taglib libxml2 libxslt yajl sqlite libvorbis ffmpeg" +PKG_DEPENDS_HOST="lzo:host libpng:host libjpeg-turbo:host giflib:host" PKG_PRIORITY="optional" PKG_SECTION="mediacenter" PKG_SHORTDESC="kodi: Kodi Mediacenter" @@ -33,15 +33,14 @@ PKG_LONGDESC="Kodi Media Center (which was formerly named Xbox Media Center or X PKG_IS_ADDON="no" PKG_AUTORECONF="no" +DEBUG="yes" + # configure GPU drivers and dependencies: get_graphicdrivers # 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 libdrm" @@ -68,14 +67,6 @@ else KODI_OPENGLES="--disable-gles" fi -if [ "$SDL_SUPPORT" = yes ]; then -# for SDL support - PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET SDL2" - KODI_SDL="--enable-sdl" -else - KODI_SDL="--disable-sdl" -fi - if [ "$ALSA_SUPPORT" = yes ]; then # for ALSA support PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET alsa-lib" @@ -97,53 +88,17 @@ else KODI_CEC="--disable-libcec" fi -if [ "$KODI_SCR_RSXS" = yes ]; then -# for RSXS Screensaver support - PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libXt libXmu" - KODI_RSXS="--enable-rsxs" -# fix build of RSXS Screensaver support if not using libiconv - export jm_cv_func_gettimeofday_clobber=no -else - KODI_RSXS="--disable-rsxs" -fi - -if [ "$KODI_VIS_PROJECTM" = yes ]; then -# for ProjectM Visualisation support - KODI_PROJECTM="--enable-projectm" -else - KODI_PROJECTM="--disable-projectm" -fi - -if [ "$KODI_VIS_GOOM" = yes ]; then -# for GOOM Visualisation support - KODI_GOOM="--enable-goom" -else - KODI_GOOM="--disable-goom" -fi - -if [ "$KODI_VIS_WAVEFORM" = yes ]; then -# for Waveform Visualisation support - KODI_WAVEFORM="--enable-waveform" -else - KODI_WAVEFORM="--disable-waveform" -fi - -if [ "$KODI_VIS_SPECTRUM" = yes ]; then -# for Spectrum Visualisation support - KODI_SPECTRUM="--enable-spectrum" -else - KODI_SPECTRUM="--disable-spectrum" -fi - -if [ "$KODI_VIS_FISHBMC" = yes ]; then -# for FishBMC Visualisation support - KODI_FISHBMC="--enable-fishbmc" -else - KODI_FISHBMC="--disable-fishbmc" -fi +# TODO remove +KODI_RSXS="--disable-rsxs" +KODI_PROJECTM="--disable-projectm" +KODI_GOOM="--disable-goom" +KODI_WAVEFORM="--disable-waveform" +KODI_SPECTRUM="--disable-spectrum" +KODI_FISHBMC="--disable-fishbmc" if [ "$JOYSTICK_SUPPORT" = yes ]; then # for Joystick support + PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET SDL2" KODI_JOYSTICK="--enable-joystick" else KODI_JOYSTICK="--disable-joystick" @@ -168,10 +123,6 @@ else KODI_DVDCSS="--disable-dvdcss" fi -if [ "$FAAC_SUPPORT" = yes ]; then - PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET faac" -fi - if [ "$KODI_BLURAY_SUPPORT" = yes ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libbluray" KODI_BLURAY="--enable-libbluray" @@ -294,7 +245,6 @@ PKG_CONFIGURE_OPTS_TARGET="gl_cv_func_gettimeofday_clobber=no \ --disable-optimizations \ $KODI_OPENGL \ $KODI_OPENGLES \ - $KODI_SDL \ $KODI_OPENMAX \ $KODI_VDPAU \ $KODI_VAAPI \ @@ -318,8 +268,6 @@ PKG_CONFIGURE_OPTS_TARGET="gl_cv_func_gettimeofday_clobber=no \ --enable-rtmp \ $KODI_SAMBA \ $KODI_NFS \ - --disable-afpclient \ - --enable-libvorbisenc \ --disable-libcap \ $KODI_DVDCSS \ --disable-mid \ @@ -347,10 +295,13 @@ pre_configure_host() { make_host() { make -C tools/depends/native/JsonSchemaBuilder + make -C tools/depends/native/TexturePacker } makeinstall_host() { cp -PR tools/depends/native/JsonSchemaBuilder/native/JsonSchemaBuilder $ROOT/$TOOLCHAIN/bin + rm -f $ROOT/$TOOLCHAIN/bin/TexturePacker + cp -PR tools/depends/native/TexturePacker/native/TexturePacker $ROOT/$TOOLCHAIN/bin } pre_build_target() { @@ -394,9 +345,6 @@ make_target() { if [ "$DISPLAYSERVER" = "x11" ]; then make kodi-xrandr fi - - make -C tools/TexturePacker - cp -PR tools/TexturePacker/TexturePacker $ROOT/$TOOLCHAIN/bin } post_makeinstall_target() { @@ -423,14 +371,6 @@ post_makeinstall_target() { rm -rf $INSTALL/usr/lib/kodi/kodi-xrandr fi - if [ ! "$KODI_SCR_RSXS" = yes ]; then - rm -rf $INSTALL/usr/share/kodi/addons/screensaver.rsxs.* - fi - - if [ ! "$KODI_VIS_PROJECTM" = yes ]; then - rm -rf $INSTALL/usr/share/kodi/addons/visualization.projectm - fi - rm -rf $INSTALL/usr/share/applications rm -rf $INSTALL/usr/share/icons rm -rf $INSTALL/usr/share/kodi/addons/service.xbmc.versioncheck diff --git a/packages/mediacenter/kodi/patches/kodi-051-add_ouya_controller_keymap.patch b/packages/mediacenter/kodi/patches/kodi-051-add_ouya_controller_keymap.patch deleted file mode 100644 index 199c1a442d..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-051-add_ouya_controller_keymap.patch +++ /dev/null @@ -1,338 +0,0 @@ -diff -Naur xbmc-14-5ec51aa.orig/system/keymaps/joystick.Ouya.Controller.xml xbmc-14-5ec51aa/system/keymaps/joystick.Ouya.Controller.xml ---- xbmc-14-5ec51aa.orig/system/keymaps/joystick.Ouya.Controller.xml 1969-12-31 16:00:00.000000000 -0800 -+++ xbmc-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/kodi/patches/kodi-052-ps4_controller_support.patch b/packages/mediacenter/kodi/patches/kodi-052-ps4_controller_support.patch deleted file mode 100644 index 03283fe921..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-052-ps4_controller_support.patch +++ /dev/null @@ -1,328 +0,0 @@ -diff -Naur xbmc-14-5ec51aa.orig/system/keymaps/joystick.PS4.Controller.xml xbmc-14-5ec51aa/system/keymaps/joystick.PS4.Controller.xml ---- xbmc-14-5ec51aa.orig/system/keymaps/joystick.PS4.Controller.xml 1969-12-31 16:00:00.000000000 -0800 -+++ xbmc-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/kodi/patches/kodi-053-add-custom-key-id.patch b/packages/mediacenter/kodi/patches/kodi-053-add-custom-key-id.patch deleted file mode 100644 index 3925f09d02..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-053-add-custom-key-id.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur kodi-14-b5dbdb5.orig/xbmc/input/linux/LinuxInputDevices.cpp kodi-14-b5dbdb5/xbmc/input/linux/LinuxInputDevices.cpp ---- kodi-14-b5dbdb5.orig/xbmc/input/linux/LinuxInputDevices.cpp 2015-02-20 22:00:07.688420179 -0800 -+++ kodi-14-b5dbdb5/xbmc/input/linux/LinuxInputDevices.cpp 2015-02-20 22:01:36.495680879 -0800 -@@ -255,6 +255,8 @@ - { 378 , XBMCK_RIGHT }, // Green - { 381 , XBMCK_UP }, // Yellow - { 366 , XBMCK_DOWN }, // Blue -+ // Rii i7 Home button -+ { 172 , XBMCK_HOME }, - }; - - typedef enum diff --git a/packages/mediacenter/kodi/patches/kodi-102-dont_really_depend_on_SDL_image.patch b/packages/mediacenter/kodi/patches/kodi-102-dont_really_depend_on_SDL_image.patch deleted file mode 100644 index d0aa38f3a0..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-102-dont_really_depend_on_SDL_image.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur kodi-14-af6d342/configure.in kodi-14-af6d342.patch/configure.in ---- kodi-14-af6d342/configure.in 2014-10-27 11:34:57.000000000 +0100 -+++ kodi-14-af6d342.patch/configure.in 2014-10-31 02:34:19.322700780 +0100 -@@ -1230,7 +1230,6 @@ - [AC_MSG_ERROR($missing_library)]) - ] - ) -- AC_CHECK_LIB([SDL_image], [main],, AC_MSG_ERROR($missing_library)) - AC_DEFINE([HAVE_SDL],[1],["Define to 1 if using sdl"]) - fi - fi diff --git a/packages/mediacenter/kodi/patches/kodi-104-use-udevil-to-umount.patch b/packages/mediacenter/kodi/patches/kodi-104-use-udevil-to-umount.patch index 86bfb5c4fe..f5c29accf1 100644 --- a/packages/mediacenter/kodi/patches/kodi-104-use-udevil-to-umount.patch +++ b/packages/mediacenter/kodi/patches/kodi-104-use-udevil-to-umount.patch @@ -1,7 +1,7 @@ -From 855160db446fe0059f072b207d53c15ba18d952f Mon Sep 17 00:00:00 2001 +From a3795cdc78a56b73875ce862227114bdf2871591 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 +Subject: [PATCH 1/6] use udevil to umount --- xbmc/linux/PosixMountProvider.cpp | 2 +- @@ -9,10 +9,10 @@ Subject: [PATCH] use udevil to umount 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/linux/PosixMountProvider.cpp b/xbmc/linux/PosixMountProvider.cpp -index 2339709..7001563 100644 +index 218d10b..57e94ca 100644 --- a/xbmc/linux/PosixMountProvider.cpp +++ b/xbmc/linux/PosixMountProvider.cpp -@@ -131,7 +131,7 @@ bool CPosixMountProvider::Eject(CStdString mountpath) +@@ -133,7 +133,7 @@ bool CPosixMountProvider::Eject(const std::string& mountpath) { // just go ahead and try to umount the disk // if it does umount, life is good, if not, no loss. @@ -22,10 +22,10 @@ index 2339709..7001563 100644 if (status == 0) diff --git a/xbmc/storage/linux/UDevProvider.cpp b/xbmc/storage/linux/UDevProvider.cpp -index 73aa408..8bd02b6 100644 +index 0ca370b..dffee34 100644 --- a/xbmc/storage/linux/UDevProvider.cpp +++ b/xbmc/storage/linux/UDevProvider.cpp -@@ -183,7 +183,7 @@ bool CUDevProvider::Eject(CStdString mountpath) +@@ -207,7 +207,7 @@ bool CUDevProvider::Eject(const std::string& mountpath) { // just go ahead and try to umount the disk // if it does umount, life is good, if not, no loss. @@ -35,5 +35,5 @@ index 73aa408..8bd02b6 100644 if (status == 0) -- -1.9.1 +2.1.4 diff --git a/packages/mediacenter/kodi/patches/kodi-200-make-binary-addons-executable.patch b/packages/mediacenter/kodi/patches/kodi-200-make-binary-addons-executable.patch index 03ad7e1487..fbbfe2687e 100644 --- a/packages/mediacenter/kodi/patches/kodi-200-make-binary-addons-executable.patch +++ b/packages/mediacenter/kodi/patches/kodi-200-make-binary-addons-executable.patch @@ -1,28 +1,28 @@ -From c572751d90ab26971d401819b146cf4daa64670c Mon Sep 17 00:00:00 2001 -From: vpeter4 -Date: Wed, 1 Oct 2014 10:12:11 +0200 +From 06ebc448041c43b8c13ac61b7bda20cb6120c588 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Mon, 2 Mar 2015 23:50:40 +0200 Subject: [PATCH] make binary addons executable add executable mode to all files in addon's bin folder --- - xbmc/addons/AddonInstaller.cpp | 23 +++++++++++++++++++++++ + xbmc/addons/AddonInstaller.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp -index d358a23..6b55c3a 100644 +index f4a241c..f6d88f2 100644 --- a/xbmc/addons/AddonInstaller.cpp +++ b/xbmc/addons/AddonInstaller.cpp -@@ -39,6 +39,9 @@ - #include "dialogs/GUIDialogKaiToast.h" +@@ -40,6 +40,9 @@ + #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogProgress.h" #include "URL.h" +#include +#include +#include - using namespace std; - using namespace XFILE; -@@ -715,6 +718,26 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r + #include + +@@ -869,6 +872,26 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r void CAddonInstallJob::OnPostInstall(bool reloadAddon) { @@ -46,9 +46,9 @@ index d358a23..6b55c3a 100644 + closedir(addonsDir); + } + - if (CSettings::Get().GetBool("general.addonnotifications")) - { - CGUIDialogKaiToast::QueueNotification(m_addon->Icon(), + if (!IsModal() && CSettings::Get().GetBool("general.addonnotifications")) + CGUIDialogKaiToast::QueueNotification(m_addon->Icon(), m_addon->Name(), + g_localizeStrings.Get(m_update ? 24065 : 24064), -- -1.8.1.2 +1.7.10.4 diff --git a/packages/mediacenter/kodi/patches/kodi-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch b/packages/mediacenter/kodi/patches/kodi-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch index d58eeecb9d..17b1a6752d 100644 --- a/packages/mediacenter/kodi/patches/kodi-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch +++ b/packages/mediacenter/kodi/patches/kodi-501-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch @@ -1,18 +1,18 @@ diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp -index 01a129e..07b4878 100644 +index f179b12..4a4ddd1 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 +@@ -571,10 +571,9 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker) + // 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); +- /* 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()) - { + // check if we are running as real xbmc.app or just binary + if (!CUtil::GetFrameworksPath(true).empty()) + { diff --git a/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch b/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch deleted file mode 100644 index 61b6f44c47..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-995.01-fernetmenta.patch +++ /dev/null @@ -1,1223 +0,0 @@ -From f96268818f3d054afb71d22be580d9cdedd7eb66 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 01/10] 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 1871eb8..5e18248 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1965,10 +1965,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 e6d58b3..1f92402 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_useFfmpegVda = false; -@@ -589,6 +591,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); - 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); - XMLUtils::GetBoolean(pElement,"useffmpegvda", m_useFfmpegVda); -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index fb5a837..9b805a0 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -162,6 +162,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; - -From aecf2bd32b23a933d65eff1e32a295fdadaf8867 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Thu, 25 Jul 2013 17:18:13 +0200 -Subject: [PATCH 02/10] 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 6e9900f..17b6c01 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -33,8 +33,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) - -From 817f21c47b7c000b6a49596b862adfa6de4feec7 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 4 Oct 2014 21:25:31 +0200 -Subject: [PATCH 04/10] vaapi: lock gfx context on pre-cleanup - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index ed7bd74..9c1dd84 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -628,6 +628,7 @@ long CDecoder::Release() - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG,"VAAPI::Release pre-cleanup"); - -+ CSingleLock lock1(g_graphicsContext); - Message *reply; - if (m_vaapiOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::PRECLEANUP, - &reply, - -From d0fa19a4c6ce0967d4bfdab9836696b379895064 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Sun, 19 Oct 2014 21:34:47 +0300 -Subject: [PATCH 05/10] [linux] Add FDEventMonitor for monitoring file - descriptors - -Add FDEventMonitor helper thread for monitoring file descriptors for -events (ready for read, ready for write) without the need for spawning -a separate thread with a tight loop around poll()/select(). - -FDEventMonitor uses an eventfd for signaling poll() instead of a -timeout, therefore it can sleep for long times in case of no events but -still immediately respond to e.g. shutdown. ---- - xbmc/linux/FDEventMonitor.cpp | 248 ++++++++++++++++++++++++++++++++++++++++++ - xbmc/linux/FDEventMonitor.h | 89 +++++++++++++++ - xbmc/linux/Makefile.in | 1 + - 3 files changed, 338 insertions(+) - create mode 100644 xbmc/linux/FDEventMonitor.cpp - create mode 100644 xbmc/linux/FDEventMonitor.h - -diff --git a/xbmc/linux/FDEventMonitor.cpp b/xbmc/linux/FDEventMonitor.cpp -new file mode 100644 -index 0000000..4a41477 ---- /dev/null -+++ b/xbmc/linux/FDEventMonitor.cpp -@@ -0,0 +1,248 @@ -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+#include "system.h" -+#ifdef HAS_ALSA -+ -+#include -+#include -+#include -+ -+#include "utils/log.h" -+ -+#include "FDEventMonitor.h" -+ -+CFDEventMonitor::CFDEventMonitor() : -+ CThread("FDEventMonitor"), -+ m_nextID(0), -+ m_wakeupfd(-1) -+{ -+} -+ -+CFDEventMonitor::~CFDEventMonitor() -+{ -+ CSingleLock lock(m_mutex); -+ InterruptPoll(); -+ -+ if (m_wakeupfd >= 0) -+ { -+ /* sets m_bStop */ -+ StopThread(false); -+ -+ /* wake up the poll() call */ -+ eventfd_write(m_wakeupfd, 1); -+ -+ /* Wait for the thread to stop */ -+ { -+ CSingleExit exit(m_mutex); -+ StopThread(true); -+ } -+ -+ close(m_wakeupfd); -+ } -+} -+ -+void CFDEventMonitor::AddFD(const MonitoredFD& monitoredFD, int& id) -+{ -+ CSingleLock lock(m_mutex); -+ InterruptPoll(); -+ -+ AddFDLocked(monitoredFD, id); -+ -+ StartMonitoring(); -+} -+ -+void CFDEventMonitor::AddFDs(const std::vector& monitoredFDs, -+ std::vector& ids) -+{ -+ CSingleLock lock(m_mutex); -+ InterruptPoll(); -+ -+ for (unsigned int i = 0; i < monitoredFDs.size(); ++i) -+ { -+ int id; -+ AddFDLocked(monitoredFDs[i], id); -+ ids.push_back(id); -+ } -+ -+ StartMonitoring(); -+} -+ -+void CFDEventMonitor::RemoveFD(int id) -+{ -+ CSingleLock lock(m_mutex); -+ InterruptPoll(); -+ -+ if (m_monitoredFDs.erase(id) != 1) -+ { -+ CLog::Log(LOGERROR, "CFDEventMonitor::RemoveFD - Tried to remove non-existing monitoredFD %d", id); -+ } -+ -+ UpdatePollDescs(); -+} -+ -+void CFDEventMonitor::RemoveFDs(const std::vector& ids) -+{ -+ CSingleLock lock(m_mutex); -+ InterruptPoll(); -+ -+ for (unsigned int i = 0; i < ids.size(); ++i) -+ { -+ if (m_monitoredFDs.erase(ids[i]) != 1) -+ { -+ CLog::Log(LOGERROR, "CFDEventMonitor::RemoveFDs - Tried to remove non-existing monitoredFD %d while removing %u FDs", ids[i], (unsigned)ids.size()); -+ } -+ } -+ -+ UpdatePollDescs(); -+} -+ -+void CFDEventMonitor::Process() -+{ -+ eventfd_t dummy; -+ -+ while (!m_bStop) -+ { -+ CSingleLock lock(m_mutex); -+ CSingleLock pollLock(m_pollMutex); -+ -+ /* -+ * Leave the main mutex here to allow another thread to -+ * lock it while we are in poll(). -+ * By then calling InterruptPoll() the other thread can -+ * wake up poll and wait for the processing to pause at -+ * the above lock(m_mutex). -+ */ -+ lock.Leave(); -+ -+ int err = poll(&m_pollDescs[0], m_pollDescs.size(), -1); -+ -+ if (err < 0 && errno != EINTR) -+ { -+ CLog::Log(LOGERROR, "CFDEventMonitor::Process - poll() failed, error %d, stopping monitoring", errno); -+ StopThread(false); -+ } -+ -+ // Something woke us up - either there is data available or we are being -+ // paused/stopped via m_wakeupfd. -+ -+ for (unsigned int i = 0; i < m_pollDescs.size(); ++i) -+ { -+ struct pollfd& pollDesc = m_pollDescs[i]; -+ int id = m_monitoredFDbyPollDescs[i]; -+ const MonitoredFD& monitoredFD = m_monitoredFDs[id]; -+ -+ if (pollDesc.revents) -+ { -+ if (monitoredFD.callback) -+ { -+ monitoredFD.callback(id, pollDesc.fd, pollDesc.revents, -+ monitoredFD.callbackData); -+ } -+ -+ if (pollDesc.revents & (POLLERR | POLLHUP | POLLNVAL)) -+ { -+ CLog::Log(LOGERROR, "CFDEventMonitor::Process - polled fd %d got revents 0x%x, removing it", pollDesc.fd, pollDesc.revents); -+ -+ /* Probably would be nice to inform our caller that their FD was -+ * dropped, but oh well... */ -+ m_monitoredFDs.erase(id); -+ UpdatePollDescs(); -+ } -+ -+ pollDesc.revents = 0; -+ } -+ } -+ -+ /* flush wakeup fd */ -+ eventfd_read(m_wakeupfd, &dummy); -+ -+ } -+} -+ -+void CFDEventMonitor::AddFDLocked(const MonitoredFD& monitoredFD, int& id) -+{ -+ id = m_nextID; -+ -+ while (m_monitoredFDs.count(id)) -+ { -+ ++id; -+ } -+ m_nextID = id + 1; -+ -+ m_monitoredFDs[id] = monitoredFD; -+ -+ AddPollDesc(id, monitoredFD.fd, monitoredFD.events); -+} -+ -+void CFDEventMonitor::AddPollDesc(int id, int fd, short events) -+{ -+ struct pollfd newPollFD; -+ newPollFD.fd = fd; -+ newPollFD.events = events; -+ newPollFD.revents = 0; -+ -+ m_pollDescs.push_back(newPollFD); -+ m_monitoredFDbyPollDescs.push_back(id); -+} -+ -+void CFDEventMonitor::UpdatePollDescs() -+{ -+ m_monitoredFDbyPollDescs.clear(); -+ m_pollDescs.clear(); -+ -+ for (std::map::iterator it = m_monitoredFDs.begin(); -+ it != m_monitoredFDs.end(); ++it) -+ { -+ AddPollDesc(it->first, it->second.fd, it->second.events); -+ } -+} -+ -+void CFDEventMonitor::StartMonitoring() -+{ -+ if (!IsRunning()) -+ { -+ /* Start the monitoring thread */ -+ -+ m_wakeupfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); -+ if (m_wakeupfd < 0) -+ { -+ CLog::Log(LOGERROR, "CFDEventMonitor::StartMonitoring - Failed to create eventfd, error %d", errno); -+ return; -+ } -+ -+ /* Add wakeup fd to the fd list */ -+ int id; -+ AddFDLocked(MonitoredFD(m_wakeupfd, POLLIN, NULL, NULL), id); -+ -+ Create(false); -+ } -+} -+ -+void CFDEventMonitor::InterruptPoll() -+{ -+ if (m_wakeupfd >= 0) -+ { -+ eventfd_write(m_wakeupfd, 1); -+ /* wait for the poll() result handling (if any) to end */ -+ CSingleLock pollLock(m_pollMutex); -+ } -+} -+ -+#endif -diff --git a/xbmc/linux/FDEventMonitor.h b/xbmc/linux/FDEventMonitor.h -new file mode 100644 -index 0000000..4602d12 ---- /dev/null -+++ b/xbmc/linux/FDEventMonitor.h -@@ -0,0 +1,89 @@ -+#pragma once -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "system.h" -+ -+#include -+#include -+ -+#include "threads/CriticalSection.h" -+#include "threads/Thread.h" -+ -+#include "utils/GlobalsHandling.h" -+ -+/** -+ * Monitor a file descriptor with callback on poll() events. -+ */ -+class CFDEventMonitor : private CThread -+{ -+public: -+ -+ typedef void (*EventCallback)(int id, int fd, short revents, void *data); -+ -+ struct MonitoredFD -+ { -+ int fd; /**< File descriptor to be monitored */ -+ short events; /**< Events to be monitored (see poll(2)) */ -+ -+ EventCallback callback; /** Callback to be called on events */ -+ void *callbackData; /** data parameter for EventCallback */ -+ -+ MonitoredFD(int fd_, short events_, EventCallback callback_, void *callbackData_) : -+ fd(fd_), events(events_), callback(callback_), callbackData(callbackData_) {} -+ MonitoredFD() : fd(-1), events(0), callback(NULL), callbackData(NULL) {} -+ }; -+ -+ CFDEventMonitor(); -+ ~CFDEventMonitor(); -+ -+ void AddFD(const MonitoredFD& monitoredFD, int& id); -+ void AddFDs(const std::vector& monitoredFDs, std::vector& ids); -+ -+ void RemoveFD(int id); -+ void RemoveFDs(const std::vector& ids); -+ -+protected: -+ virtual void Process(); -+ -+private: -+ void AddFDLocked(const MonitoredFD& monitoredFD, int& id); -+ -+ void AddPollDesc(int id, int fd, short events); -+ void UpdatePollDescs(); -+ -+ void StartMonitoring(); -+ void InterruptPoll(); -+ -+ std::map m_monitoredFDs; -+ -+ /* these are kept synchronized */ -+ std::vector m_monitoredFDbyPollDescs; -+ std::vector m_pollDescs; -+ -+ int m_nextID; -+ int m_wakeupfd; -+ -+ CCriticalSection m_mutex; -+ CCriticalSection m_pollMutex; -+}; -+ -+XBMC_GLOBAL_REF(CFDEventMonitor, g_fdEventMonitor); -+#define g_fdEventMonitor XBMC_GLOBAL_USE(CFDEventMonitor) -diff --git a/xbmc/linux/Makefile.in b/xbmc/linux/Makefile.in -index c147d8f..744fd06 100644 ---- a/xbmc/linux/Makefile.in -+++ b/xbmc/linux/Makefile.in -@@ -4,6 +4,7 @@ SRCS = ConvUtils.cpp - SRCS += DBusUtil.cpp - SRCS += DBusMessage.cpp - SRCS += DBusReserve.cpp -+SRCS += FDEventMonitor.cpp - SRCS += LinuxResourceCounter.cpp - SRCS += LinuxTimezone.cpp - SRCS += PosixMountProvider.cpp - -From 9fe447e12d86fbd75995d8c0f0fa6d89786c6983 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Sun, 19 Oct 2014 21:36:44 +0300 -Subject: [PATCH 06/10] [AE] ALSA: Add ALSADeviceMonitor for monitoring card - removals/additions - ---- - xbmc/cores/AudioEngine/Makefile.in | 1 + - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 8 ++ - xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 10 ++ - .../AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp | 131 +++++++++++++++++++++ - .../AudioEngine/Sinks/alsa/ALSADeviceMonitor.h | 49 ++++++++ - 5 files changed, 199 insertions(+) - create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp - create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h - -diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in -index 8491050..6f818e2 100644 ---- a/xbmc/cores/AudioEngine/Makefile.in -+++ b/xbmc/cores/AudioEngine/Makefile.in -@@ -49,6 +49,7 @@ SRCS += Sinks/osx/CoreAudioHelpers.cpp - SRCS += Sinks/osx/CoreAudioStream.cpp - else - SRCS += Sinks/AESinkALSA.cpp -+SRCS += Sinks/alsa/ALSADeviceMonitor.cpp - SRCS += Sinks/AESinkOSS.cpp - ifeq (@USE_PULSE@,1) - SRCS += Sinks/AESinkPULSE.cpp -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index d30cbab..c33d4dd 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -1101,6 +1101,10 @@ bool CAESinkALSA::OpenPCMDevice(const std::string &name, const std::string ¶ - - void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) - { -+#if HAVE_LIBUDEV -+ m_deviceMonitor.Start(); -+#endif -+ - /* ensure that ALSA has been initialized */ - snd_lib_error_set_handler(sndLibErrorHandler); - if(!snd_config || force) -@@ -1612,4 +1616,8 @@ void CAESinkALSA::sndLibErrorHandler(const char *file, int line, const char *fun - va_end(arg); - } - -+#if HAVE_LIBUDEV -+CALSADeviceMonitor CAESinkALSA::m_deviceMonitor; // ARGH -+#endif -+ - #endif -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -index c284255..54402f9 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -@@ -24,6 +24,7 @@ - - #include "cores/AudioEngine/Interfaces/AESink.h" - #include "cores/AudioEngine/Utils/AEDeviceInfo.h" -+#include "cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h" - #include - - #define ALSA_PCM_NEW_HW_PARAMS_API -@@ -31,6 +32,10 @@ - - #include "threads/CriticalSection.h" - -+// ARGH... this is apparently needed to avoid FDEventMonitor -+// being destructed before CALSA*Monitor below. -+#include "linux/FDEventMonitor.h" -+ - class CAESinkALSA : public IAESink - { - public: -@@ -81,6 +86,11 @@ class CAESinkALSA : public IAESink - // support fragmentation, e.g. looping in the sink to get a certain amount of data onto the device - bool m_fragmented; - unsigned int m_originalPeriodSize; -+ -+#if HAVE_LIBUDEV -+ static CALSADeviceMonitor m_deviceMonitor; -+#endif -+ - struct ALSAConfig - { - unsigned int sampleRate; -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp -new file mode 100644 -index 0000000..e3269ad ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp -@@ -0,0 +1,131 @@ -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+#include "system.h" -+#if defined(HAS_ALSA) && defined(HAVE_LIBUDEV) -+ -+#include -+ -+#include "ALSADeviceMonitor.h" -+#include "AEFactory.h" -+#include "linux/FDEventMonitor.h" -+#include "utils/log.h" -+ -+CALSADeviceMonitor::CALSADeviceMonitor() : -+ m_fdMonitorId(0), -+ m_udev(NULL), -+ m_udevMonitor(NULL) -+{ -+} -+ -+CALSADeviceMonitor::~CALSADeviceMonitor() -+{ -+ Stop(); -+} -+ -+void CALSADeviceMonitor::Start() -+{ -+ int err; -+ -+ if (!m_udev) -+ { -+ m_udev = udev_new(); -+ if (!m_udev) -+ { -+ CLog::Log(LOGWARNING, "CALSADeviceMonitor::Start - Unable to open udev handle"); -+ return; -+ } -+ -+ m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev"); -+ if (!m_udevMonitor) -+ { -+ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_new_from_netlink() failed"); -+ goto err_unref_udev; -+ } -+ -+ err = udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitor, "sound", NULL); -+ if (err) -+ { -+ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_filter_add_match_subsystem_devtype() failed"); -+ goto err_unref_monitor; -+ } -+ -+ err = udev_monitor_enable_receiving(m_udevMonitor); -+ if (err) -+ { -+ CLog::Log(LOGERROR, "CALSADeviceMonitor::Start - udev_monitor_enable_receiving() failed"); -+ goto err_unref_monitor; -+ } -+ -+ g_fdEventMonitor.AddFD( -+ CFDEventMonitor::MonitoredFD(udev_monitor_get_fd(m_udevMonitor), -+ POLLIN, FDEventCallback, m_udevMonitor), -+ m_fdMonitorId); -+ } -+ -+ return; -+ -+err_unref_monitor: -+ udev_monitor_unref(m_udevMonitor); -+ m_udevMonitor = NULL; -+err_unref_udev: -+ udev_unref(m_udev); -+ m_udev = NULL; -+} -+ -+void CALSADeviceMonitor::Stop() -+{ -+ if (m_udev) -+ { -+ g_fdEventMonitor.RemoveFD(m_fdMonitorId); -+ -+ udev_monitor_unref(m_udevMonitor); -+ m_udevMonitor = NULL; -+ udev_unref(m_udev); -+ m_udev = NULL; -+ } -+} -+ -+void CALSADeviceMonitor::FDEventCallback(int id, int fd, short revents, void *data) -+{ -+ struct udev_monitor *udevMonitor = (struct udev_monitor *)data; -+ bool audioDevicesChanged = false; -+ struct udev_device *device; -+ -+ while ((device = udev_monitor_receive_device(udevMonitor)) != NULL) -+ { -+ const char* action = udev_device_get_action(device); -+ const char* soundInitialized = udev_device_get_property_value(device, "SOUND_INITIALIZED"); -+ -+ /* cardX devices emit a "change" event when ready (i.e. all subdevices added) */ -+ if (action && soundInitialized && -+ (strcmp(action, "change") == 0 || strcmp(action, "remove") == 0)) -+ { -+ audioDevicesChanged = true; -+ } -+ udev_device_unref(device); -+ } -+ -+ if (audioDevicesChanged) -+ { -+ CAEFactory::DeviceChange(); -+ } -+} -+ -+#endif -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h -new file mode 100644 -index 0000000..f9e2f26 ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h -@@ -0,0 +1,49 @@ -+#pragma once -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "system.h" -+#if defined(HAS_ALSA) && defined(HAVE_LIBUDEV) -+ -+#include -+#include -+ -+#include -+ -+class CALSADeviceMonitor -+{ -+public: -+ CALSADeviceMonitor(); -+ ~CALSADeviceMonitor(); -+ -+ void Start(); -+ void Stop(); -+ -+private: -+ static void FDEventCallback(int id, int fd, short revents, void *data); -+ -+ int m_fdMonitorId; -+ -+ struct udev *m_udev; -+ struct udev_monitor* m_udevMonitor; -+}; -+ -+#endif -+ - -From 750969d09c060e59957d7aa6a582c0406a24cf21 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Sun, 19 Oct 2014 21:37:49 +0300 -Subject: [PATCH 07/10] [AE] ALSA: Add ALSADeviceMonitor for monitoring ELD - changes - -ELD changes can happen e.g. when the connected HDMI sink is changed. ---- - xbmc/cores/AudioEngine/Makefile.in | 1 + - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 9 ++ - xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 2 + - .../AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp | 173 +++++++++++++++++++++ - .../AudioEngine/Sinks/alsa/ALSAHControlMonitor.h | 69 ++++++++ - 5 files changed, 254 insertions(+) - create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp - create mode 100644 xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h - -diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in -index 6f818e2..024618e 100644 ---- a/xbmc/cores/AudioEngine/Makefile.in -+++ b/xbmc/cores/AudioEngine/Makefile.in -@@ -50,6 +50,7 @@ SRCS += Sinks/osx/CoreAudioStream.cpp - else - SRCS += Sinks/AESinkALSA.cpp - SRCS += Sinks/alsa/ALSADeviceMonitor.cpp -+SRCS += Sinks/alsa/ALSAHControlMonitor.cpp - SRCS += Sinks/AESinkOSS.cpp - ifeq (@USE_PULSE@,1) - SRCS += Sinks/AESinkPULSE.cpp -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index c33d4dd..634f35a 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -1118,6 +1118,8 @@ void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) - snd_config_t *config; - snd_config_copy(&config, snd_config); - -+ m_controlMonitor.Clear(); -+ - /* Always enumerate the default device. - * Note: If "default" is a stereo device, EnumerateDevice() - * will automatically add "@" instead to enable surroundXX mangling. -@@ -1195,6 +1197,8 @@ void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) - } - snd_device_name_free_hint(hints); - -+ m_controlMonitor.Start(); -+ - /* set the displayname for default device */ - if (!list.empty() && list[0].m_deviceName == "default") - { -@@ -1375,6 +1379,10 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev - { - snd_hctl_load(hctl); - bool badHDMI = false; -+ -+ /* add ELD to monitoring */ -+ m_controlMonitor.Add(strHwName, SND_CTL_ELEM_IFACE_PCM, dev, "ELD"); -+ - if (!GetELD(hctl, dev, info, badHDMI)) - CLog::Log(LOGDEBUG, "CAESinkALSA - Unable to obtain ELD information for device \"%s\" (not supported by device, or kernel older than 3.2)", - device.c_str()); -@@ -1619,5 +1627,6 @@ void CAESinkALSA::sndLibErrorHandler(const char *file, int line, const char *fun - #if HAVE_LIBUDEV - CALSADeviceMonitor CAESinkALSA::m_deviceMonitor; // ARGH - #endif -+CALSAHControlMonitor CAESinkALSA::m_controlMonitor; // ARGH - - #endif -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -index 54402f9..2059eaa 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h -@@ -25,6 +25,7 @@ - #include "cores/AudioEngine/Interfaces/AESink.h" - #include "cores/AudioEngine/Utils/AEDeviceInfo.h" - #include "cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.h" -+#include "cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h" - #include - - #define ALSA_PCM_NEW_HW_PARAMS_API -@@ -90,6 +91,7 @@ class CAESinkALSA : public IAESink - #if HAVE_LIBUDEV - static CALSADeviceMonitor m_deviceMonitor; - #endif -+ static CALSAHControlMonitor m_controlMonitor; - - struct ALSAConfig - { -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -new file mode 100644 -index 0000000..9b595ee ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+#include "system.h" -+#ifdef HAS_ALSA -+ -+#include "ALSAHControlMonitor.h" -+ -+#include "AEFactory.h" -+#include "linux/FDEventMonitor.h" -+#include "utils/log.h" -+ -+CALSAHControlMonitor::CALSAHControlMonitor() -+{ -+} -+ -+CALSAHControlMonitor::~CALSAHControlMonitor() -+{ -+ Clear(); -+} -+ -+bool CALSAHControlMonitor::Add(const std::string& ctlHandleName, -+ snd_ctl_elem_iface_t interface, -+ unsigned int device, -+ const std::string& name) -+{ -+ snd_hctl_t *hctl = GetHandle(ctlHandleName); -+ -+ if (!hctl) -+ { -+ return false; -+ } -+ -+ snd_ctl_elem_id_t *id; -+ -+ snd_ctl_elem_id_alloca(&id); -+ -+ snd_ctl_elem_id_set_interface(id, interface); -+ snd_ctl_elem_id_set_name (id, name.c_str()); -+ snd_ctl_elem_id_set_device (id, device); -+ -+ snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id); -+ -+ if (!elem) -+ { -+ PutHandle(ctlHandleName); -+ return false; -+ } -+ -+ snd_hctl_elem_set_callback(elem, HCTLCallback); -+ -+ return true; -+} -+ -+void CALSAHControlMonitor::Clear() -+{ -+ Stop(); -+ -+ for (std::map::iterator it = m_ctlHandles.begin(); -+ it != m_ctlHandles.end(); ++it) -+ { -+ snd_hctl_close(it->second.handle); -+ } -+ m_ctlHandles.clear(); -+} -+ -+void CALSAHControlMonitor::Start() -+{ -+ assert(m_fdMonitorIds.size() == 0); -+ -+ std::vector pollfds; -+ std::vector monitoredFDs; -+ -+ for (std::map::iterator it = m_ctlHandles.begin(); -+ it != m_ctlHandles.end(); ++it) -+ { -+ pollfds.resize(snd_hctl_poll_descriptors_count(it->second.handle)); -+ int fdcount = snd_hctl_poll_descriptors(it->second.handle, &pollfds[0], pollfds.size()); -+ -+ for (int j = 0; j < fdcount; ++j) -+ { -+ monitoredFDs.push_back(CFDEventMonitor::MonitoredFD(pollfds[j].fd, -+ pollfds[j].events, -+ FDEventCallback, -+ it->second.handle)); -+ } -+ } -+ -+ g_fdEventMonitor.AddFDs(monitoredFDs, m_fdMonitorIds); -+} -+ -+ -+void CALSAHControlMonitor::Stop() -+{ -+ g_fdEventMonitor.RemoveFDs(m_fdMonitorIds); -+ m_fdMonitorIds.clear(); -+} -+ -+int CALSAHControlMonitor::HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask) -+{ -+ /* -+ * Currently we just re-enumerate on any change. -+ * Custom callbacks for handling other control monitoring may be implemented when needed. -+ */ -+ if (mask & SND_CTL_EVENT_MASK_VALUE) -+ { -+ CAEFactory::DeviceChange(); -+ } -+ -+ return 0; -+} -+ -+void CALSAHControlMonitor::FDEventCallback(int id, int fd, short revents, void *data) -+{ -+ /* Run ALSA event handling when the FD has events */ -+ snd_hctl_t *hctl = (snd_hctl_t *)data; -+ snd_hctl_handle_events(hctl); -+} -+ -+snd_hctl_t* CALSAHControlMonitor::GetHandle(const std::string& ctlHandleName) -+{ -+ if (!m_ctlHandles.count(ctlHandleName)) -+ { -+ snd_hctl_t *hctl; -+ -+ if (snd_hctl_open(&hctl, ctlHandleName.c_str(), 0) != 0) -+ { -+ CLog::Log(LOGWARNING, "CALSAHControlMonitor::GetHandle - snd_hctl_open() failed for \"%s\"", ctlHandleName.c_str()); -+ return NULL; -+ } -+ if (snd_hctl_load(hctl) != 0) -+ { -+ CLog::Log(LOGERROR, "CALSAHControlMonitor::GetHandle - snd_hctl_load() failed for \"%s\"", ctlHandleName.c_str()); -+ snd_hctl_close(hctl); -+ return NULL; -+ } -+ -+ snd_hctl_nonblock(hctl, 1); -+ -+ m_ctlHandles[ctlHandleName] = CTLHandle(hctl); -+ } -+ -+ m_ctlHandles[ctlHandleName].useCount++; -+ return m_ctlHandles[ctlHandleName].handle; -+} -+ -+void CALSAHControlMonitor::PutHandle(const std::string& ctlHandleName) -+{ -+ if (--m_ctlHandles[ctlHandleName].useCount == 0) -+ { -+ snd_hctl_close(m_ctlHandles[ctlHandleName].handle); -+ m_ctlHandles.erase(ctlHandleName); -+ } -+} -+ -+ -+#endif -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h -new file mode 100644 -index 0000000..56dfd50 ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.h -@@ -0,0 +1,69 @@ -+#pragma once -+/* -+ * Copyright (C) 2014 Team Kodi -+ * 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 Kodi; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "system.h" -+#ifdef HAS_ALSA -+ -+#include -+#include -+#include -+ -+#include -+ -+class CALSAHControlMonitor -+{ -+public: -+ CALSAHControlMonitor(); -+ ~CALSAHControlMonitor(); -+ -+ bool Add(const std::string& ctlHandleName, -+ snd_ctl_elem_iface_t interface, -+ unsigned int device, -+ const std::string& name); -+ -+ void Clear(); -+ -+ void Start(); -+ void Stop(); -+ -+private: -+ static int HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask); -+ static void FDEventCallback(int id, int fd, short revents, void *data); -+ -+ snd_hctl_t* GetHandle(const std::string& ctlHandleName); -+ void PutHandle(const std::string& ctlHandleName); -+ -+ struct CTLHandle -+ { -+ snd_hctl_t *handle; -+ int useCount; -+ -+ CTLHandle(snd_hctl_t *handle_) : handle(handle_), useCount(0) {} -+ CTLHandle() : handle(NULL), useCount(0) {} -+ }; -+ -+ std::map m_ctlHandles; -+ -+ std::vector m_fdMonitorIds; -+}; -+ -+#endif -+ - -From b1c67c1a6448d05bb3393eeccb857a3ec71625b5 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Sun, 2 Nov 2014 21:10:51 +0200 -Subject: [PATCH 08/10] [AE] ALSA: Add more logging to device change triggers - ---- - xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp | 13 +++++++++++-- - xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp | 2 ++ - 2 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp -index e3269ad..b0243b9 100644 ---- a/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSADeviceMonitor.cpp -@@ -113,12 +113,21 @@ void CALSADeviceMonitor::FDEventCallback(int id, int fd, short revents, void *da - const char* action = udev_device_get_action(device); - const char* soundInitialized = udev_device_get_property_value(device, "SOUND_INITIALIZED"); - -+ if (!action || !soundInitialized) -+ continue; -+ - /* cardX devices emit a "change" event when ready (i.e. all subdevices added) */ -- if (action && soundInitialized && -- (strcmp(action, "change") == 0 || strcmp(action, "remove") == 0)) -+ if (strcmp(action, "change") == 0) - { -+ CLog::Log(LOGDEBUG, "CALSADeviceMonitor - ALSA card added (\"%s\", \"%s\")", udev_device_get_syspath(device), udev_device_get_devpath(device)); - audioDevicesChanged = true; - } -+ else if (strcmp(action, "remove") == 0) -+ { -+ CLog::Log(LOGDEBUG, "CALSADeviceMonitor - ALSA card removed"); -+ audioDevicesChanged = true; -+ } -+ - udev_device_unref(device); - } - -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -index 9b595ee..f9ca9ae 100644 ---- a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -@@ -120,6 +120,8 @@ int CALSAHControlMonitor::HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask) - */ - if (mask & SND_CTL_EVENT_MASK_VALUE) - { -+ CLog::Log(LOGDEBUG, "CALSAHControlMonitor - Monitored ALSA hctl value changed"); -+ - CAEFactory::DeviceChange(); - } - - -From e83bc9308cd53fcfcef1053caa99797c8187a9b0 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Tue, 4 Nov 2014 19:22:03 +0200 -Subject: [PATCH 09/10] [AE] ALSA: Fix DeviceChange event triggered by - enumeration - -All hctl elements get an SND_CTL_EVENT_MASK_REMOVE event when the ctl -file descriptor is closed, which is done e.g. when re-enumerating -devices. - -(SND_CTL_EVENT_MASK_REMOVE & SND_CTL_EVENT_MASK_VALUE) is true, and -therefore we re-triggered enumeration (depending a bit on timing). - -Fix that by checking for the special _REMOVE value first and ignoring -those events. ---- - .../cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -index f9ca9ae..89a7585 100644 ---- a/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/alsa/ALSAHControlMonitor.cpp -@@ -114,14 +114,22 @@ void CALSAHControlMonitor::Stop() - - int CALSAHControlMonitor::HCTLCallback(snd_hctl_elem_t *elem, unsigned int mask) - { -- /* -- * Currently we just re-enumerate on any change. -- * Custom callbacks for handling other control monitoring may be implemented when needed. -- */ -+ /* _REMOVE is a special value instead of a bit and must be checked first */ -+ if (mask == SND_CTL_EVENT_MASK_REMOVE) -+ { -+ /* Either the device was removed (which is handled in ALSADeviceMonitor instead) -+ * or snd_hctl_close() got called. */ -+ return 0; -+ } -+ - if (mask & SND_CTL_EVENT_MASK_VALUE) - { - CLog::Log(LOGDEBUG, "CALSAHControlMonitor - Monitored ALSA hctl value changed"); - -+ /* -+ * Currently we just re-enumerate on any change. -+ * Custom callbacks for handling other control monitoring may be implemented when needed. -+ */ - CAEFactory::DeviceChange(); - } - - diff --git a/packages/mediacenter/kodi/patches/kodi-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch b/packages/mediacenter/kodi/patches/kodi-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch index 3f331b1574..fd0514ccb9 100644 --- a/packages/mediacenter/kodi/patches/kodi-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch +++ b/packages/mediacenter/kodi/patches/kodi-995.02-dont-set-_NET_WM_STATE_FULLSCREEN.patch @@ -1,29 +1,25 @@ -From 4f6188bc2bcee52ab3a150fff336b58c11f8928a Mon Sep 17 00:00:00 2001 +From cab997df6a39ec87dcfa04215715aa5bbd44d947 Mon Sep 17 00:00:00 2001 From: Stefan Saraev -Date: Sat, 22 Mar 2014 22:18:28 +0200 +Date: Wed, 11 Mar 2015 20:56:15 +0200 Subject: [PATCH] dont set _NET_WM_STATE_FULLSCREEN --- - xbmc/windowing/X11/WinSystemX11.cpp | 6 ------ - 1 files changed, 0 insertions(+), 6 deletions(-) + xbmc/windowing/X11/WinSystemX11.cpp | 2 -- + 1 file changed, 2 deletions(-) diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c95f4ec..d12e050 100644 +index 05f36ee..1714422 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); +@@ -1155,8 +1155,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std: -- if (fullscreen && hasWM) -- { + 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; + // disable desktop compositing for KDE, when Kodi is in full-screen mode + int one = 1; + XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_KDE_NET_WM_BLOCK_COMPOSITING", True), XA_CARDINAL, 32, -- -1.7.2.5 +1.7.10.4 diff --git a/packages/mediacenter/kodi/patches/kodi-995.12-openelec-setup-timezone.patch b/packages/mediacenter/kodi/patches/kodi-995.12-openelec-setup-timezone.patch index 9e5e4387f8..57a047d562 100644 --- a/packages/mediacenter/kodi/patches/kodi-995.12-openelec-setup-timezone.patch +++ b/packages/mediacenter/kodi/patches/kodi-995.12-openelec-setup-timezone.patch @@ -1,26 +1,29 @@ -From c2717b64788fd05098f1d1f5499def9fbc4af957 Mon Sep 17 00:00:00 2001 +From 3cfa580493f7a57109d19d99373a455852388e0d Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Mon, 18 Aug 2014 17:46:54 +0300 -Subject: [PATCH] openelec: setup timezone +Subject: [PATCH 3/6] setup timezone +on TZ country setting change, store the value in format +TIMEZONE=Xx/Yyy to /storage/.cache/timezone to be used with +tz-data.service --- - xbmc/linux/LinuxTimezone.cpp | 12 ++++++++++++ - 1 files changed, 12 insertions(+), 0 deletions(-) + xbmc/linux/LinuxTimezone.cpp | 12 ++++++++++++ + 1 file changed, 12 insertions(+) diff --git a/xbmc/linux/LinuxTimezone.cpp b/xbmc/linux/LinuxTimezone.cpp -index b4ffd13..5bf41eb 100644 +index 37130d8..3431638 100644 --- a/xbmc/linux/LinuxTimezone.cpp +++ b/xbmc/linux/LinuxTimezone.cpp -@@ -39,6 +39,8 @@ - #include "settings/lib/Setting.h" - #include "settings/Settings.h" +@@ -42,6 +42,8 @@ + + #include +#include + using namespace std; CLinuxTimezone::CLinuxTimezone() : m_IsDST(0) -@@ -158,6 +160,16 @@ void CLinuxTimezone::OnSettingChanged(const CSetting *setting) +@@ -161,6 +163,16 @@ void CLinuxTimezone::OnSettingChanged(const CSetting *setting) const std::string &settingId = setting->GetId(); if (settingId == "locale.timezone") { @@ -38,5 +41,5 @@ index b4ffd13..5bf41eb 100644 CDateTime::ResetTimezoneBias(); -- -1.7.2.5 +2.1.4 diff --git a/packages/mediacenter/kodi/patches/kodi-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch b/packages/mediacenter/kodi/patches/kodi-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch index 77f4df6189..e48635206f 100644 --- a/packages/mediacenter/kodi/patches/kodi-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch +++ b/packages/mediacenter/kodi/patches/kodi-999.00-service-addons-use-a-wrapper-to-setup-systemd.patch @@ -1,7 +1,7 @@ -From a58ead6a20bcfd6132c6f234c3108b5d16a6440c Mon Sep 17 00:00:00 2001 +From 4672bee097751d04098b5989516ecdc2ee80391e Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Fri, 8 Aug 2014 18:22:44 +0300 -Subject: [PATCH] use a wrapper to setup systemd services +Subject: [PATCH 2/6] use a wrapper to setup systemd services --- xbmc/addons/Service.cpp | 22 ++++++++++++++++++++++ @@ -9,7 +9,7 @@ Subject: [PATCH] use a wrapper to setup systemd services 2 files changed, 23 insertions(+) diff --git a/xbmc/addons/Service.cpp b/xbmc/addons/Service.cpp -index c406b11..f6afbe8 100644 +index 2f5c38c..4fc8d5f 100644 --- a/xbmc/addons/Service.cpp +++ b/xbmc/addons/Service.cpp @@ -53,6 +53,10 @@ AddonPtr CService::Clone() const @@ -50,7 +50,7 @@ index c406b11..f6afbe8 100644 @@ -145,13 +160,20 @@ void CService::OnPostInstall(bool restart, bool update) { - boost::shared_ptr service = boost::dynamic_pointer_cast(localAddon); + std::shared_ptr service = std::dynamic_pointer_cast(localAddon); if (service) + { + // systemctl stop & disable / enable & start on addon upgrade @@ -82,5 +82,5 @@ index 98ec8b6..683ae60 100644 virtual void OnEnabled(); virtual bool OnPreInstall(); -- -2.1.0 +2.1.4 diff --git a/packages/mediacenter/kodi/patches/kodi-999.02-revert-b6bec7a.patch b/packages/mediacenter/kodi/patches/kodi-999.02-revert-b6bec7a.patch deleted file mode 100644 index 5486ef02ad..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.02-revert-b6bec7a.patch +++ /dev/null @@ -1,35 +0,0 @@ -From d4d83054ad9096c31d3c91bcbbf1919de1aa76f0 Mon Sep 17 00:00:00 2001 -From: Stefan Saraev -Date: Sun, 29 Jun 2014 22:59:00 +0300 -Subject: [PATCH] revert b6bec7a - -this reverts upstream commit b6bec7a (part of xbmc/pull/4761): - -> From b6bec7a44fec728c28aa0cedc96288539a71e324 Mon Sep 17 00:00:00 2001 -> From: Trent Nelson -> Date: Wed, 21 May 2014 17:16:54 +0800 -> Subject: [PATCH] [PVR] Make sure client addons are disabled first time we see -> them. - -pvr client addons should NOT be disabled after pvr database reset ---- - xbmc/pvr/addons/PVRClients.cpp | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp -index b403fd6..809c244 100644 ---- a/xbmc/pvr/addons/PVRClients.cpp -+++ b/xbmc/pvr/addons/PVRClients.cpp -@@ -1126,8 +1126,7 @@ bool CPVRClients::UpdateAddons(void) - for (unsigned iClientPtr = 0; iClientPtr < m_addons.size(); iClientPtr++) - { - const AddonPtr clientAddon = m_addons.at(iClientPtr); -- bool newRegistration = false; -- if (RegisterClient(clientAddon, &newRegistration) < 0 || newRegistration) -+ if (RegisterClient(clientAddon) < 0) - { - CAddonMgr::Get().DisableAddon(clientAddon->ID(), true); - usableClients--; --- -1.9.1 - diff --git a/packages/mediacenter/kodi/patches/kodi-999.03-0001-handle-SIGTERM.patch b/packages/mediacenter/kodi/patches/kodi-999.03-handle-SIGTERM.patch similarity index 90% rename from packages/mediacenter/kodi/patches/kodi-999.03-0001-handle-SIGTERM.patch rename to packages/mediacenter/kodi/patches/kodi-999.03-handle-SIGTERM.patch index 418f67f4be..df811af5c4 100644 --- a/packages/mediacenter/kodi/patches/kodi-999.03-0001-handle-SIGTERM.patch +++ b/packages/mediacenter/kodi/patches/kodi-999.03-handle-SIGTERM.patch @@ -1,7 +1,7 @@ -From eabb811c7f82695cb566b0aadf5d86cb7448368a Mon Sep 17 00:00:00 2001 +From ec3a12fb4708e9319c18af1b851a7a324294bc6c Mon Sep 17 00:00:00 2001 From: Stefan Saraev -Date: Thu, 5 Jun 2014 18:50:04 +0300 -Subject: [PATCH] handle SIGTERM +Date: Mon, 15 Dec 2014 21:28:54 +0200 +Subject: [PATCH 6/6] 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 @@ -31,10 +31,10 @@ is requested externaly (ssh, 3rdparty script). 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 875ca39..9572b62 100644 +index 69b1cd7..f1f60cd 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -3477,12 +3477,19 @@ bool CApplication::Cleanup() +@@ -2543,12 +2543,19 @@ bool CApplication::Cleanup() } } @@ -55,7 +55,7 @@ index 875ca39..9572b62 100644 CAnnouncementManager::Get().Announce(System, "xbmc", "OnQuit", vExitCode); SaveFileState(true); -@@ -3506,7 +3513,6 @@ void CApplication::Stop(int exitCode) +@@ -2572,7 +2579,6 @@ void CApplication::Stop(int exitCode) m_bStop = true; m_AppFocused = false; @@ -64,10 +64,10 @@ index 875ca39..9572b62 100644 // cancel any jobs from the jobmanager diff --git a/xbmc/Application.h b/xbmc/Application.h -index 0a332ff..a4d6b58 100644 +index ec5dfac..96cbf71 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h -@@ -153,6 +153,7 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs +@@ -154,6 +154,7 @@ public: bool StartPVRManager(); void StopPVRManager(); bool IsCurrentThread() const; @@ -76,7 +76,7 @@ index 0a332ff..a4d6b58 100644 void RestartApp(); void UnloadSkin(bool forReload = false); diff --git a/xbmc/ApplicationMessenger.cpp b/xbmc/ApplicationMessenger.cpp -index 2f4d651..0467893 100644 +index a46c9be..9bb6804 100644 --- a/xbmc/ApplicationMessenger.cpp +++ b/xbmc/ApplicationMessenger.cpp @@ -261,13 +261,14 @@ void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg) @@ -128,7 +128,7 @@ 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 @@ class CXBApplicationEx : public IWindowManagerCallback +@@ -40,6 +40,7 @@ public: // Variables for timing bool m_bStop; int m_ExitCode; @@ -137,10 +137,10 @@ index c46cba1..ed3f35f 100644 bool m_renderGUI; diff --git a/xbmc/main/main.cpp b/xbmc/main/main.cpp -index ec86426..ad8fe6e 100644 +index 87fe2fd..3bfb338 100644 --- a/xbmc/main/main.cpp +++ b/xbmc/main/main.cpp -@@ -40,9 +40,24 @@ +@@ -41,9 +41,24 @@ #include "input/linux/LIRC.h" #endif #include "XbmcContext.h" @@ -165,3 +165,6 @@ index ec86426..ad8fe6e 100644 // set up some xbmc specific relationships XBMC::Context context; +-- +2.1.4 + diff --git a/packages/mediacenter/kodi/patches/kodi-999.90-show_rss-setting_in_standard_group.patch b/packages/mediacenter/kodi/patches/kodi-999.90-show_rss-setting_in_standard_group.patch deleted file mode 100644 index 50186d7813..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-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/kodi/patches/kodi-999.92-Load_OSD_dialogs_on_startup.patch b/packages/mediacenter/kodi/patches/kodi-999.92-Load_OSD_dialogs_on_startup.patch deleted file mode 100644 index f56dbe2b4f..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.92-Load_OSD_dialogs_on_startup.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 925a4e4d7e775cc246518d6ea934d1f93a069870 Mon Sep 17 00:00:00 2001 -From: anaconda -Date: Wed, 25 Feb 2015 18:22:21 +0100 -Subject: [PATCH] Load OSD dialogs on startup. - -Fixes skipped frames the first time they're loaded in memory on less powered -devices, like a Raspberry Pi, when using DVDPlayer. -See http://forum.kodi.tv/showthread.php?tid=211501&pid=1938811#pid1938811 ---- - xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp | 1 + - xbmc/pvr/dialogs/GUIDialogPVRGuideOSD.cpp | 1 + - xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp | 4 +++- - xbmc/video/dialogs/GUIDialogSubtitles.cpp | 2 +- - xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp | 2 +- - xbmc/video/dialogs/GUIDialogVideoOSD.cpp | 2 +- - xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 4 +++- - 7 files changed, 11 insertions(+), 5 deletions(-) - -diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp -index 5fb5c79..36f7273 100644 ---- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp -+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp -@@ -50,6 +50,7 @@ CGUIDialogPVRChannelsOSD::CGUIDialogPVRChannelsOSD() : - CGUIDialog(WINDOW_DIALOG_PVR_OSD_CHANNELS, "DialogPVRChannelsOSD.xml"), - Observer() - { -+ m_loadType = LOAD_ON_GUI_INIT; - m_vecItems = new CFileItemList; - } - -diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideOSD.cpp -index cf7e5d2..9e9ed32 100644 ---- a/xbmc/pvr/dialogs/GUIDialogPVRGuideOSD.cpp -+++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideOSD.cpp -@@ -35,6 +35,7 @@ using namespace PVR; - CGUIDialogPVRGuideOSD::CGUIDialogPVRGuideOSD() - : CGUIDialog(WINDOW_DIALOG_PVR_OSD_GUIDE, "DialogPVRGuideOSD.xml") - { -+ m_loadType = LOAD_ON_GUI_INIT; - m_vecItems = new CFileItemList; - } - -diff --git a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp -index 32a9ba4..9999bdf 100644 ---- a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp -@@ -62,7 +62,9 @@ using namespace std; - CGUIDialogAudioSubtitleSettings::CGUIDialogAudioSubtitleSettings() - : CGUIDialogSettingsManualBase(WINDOW_DIALOG_AUDIO_OSD_SETTINGS, "VideoOSDSettings.xml"), - m_passthrough(false) --{ } -+{ -+ m_loadType = LOAD_ON_GUI_INIT; -+} - - CGUIDialogAudioSubtitleSettings::~CGUIDialogAudioSubtitleSettings() - { } -diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.cpp b/xbmc/video/dialogs/GUIDialogSubtitles.cpp -index e3939f1..e184d53 100644 ---- a/xbmc/video/dialogs/GUIDialogSubtitles.cpp -+++ b/xbmc/video/dialogs/GUIDialogSubtitles.cpp -@@ -99,7 +99,7 @@ class CSubtitlesJob: public CJob - CGUIDialogSubtitles::CGUIDialogSubtitles(void) - : CGUIDialog(WINDOW_DIALOG_SUBTITLES, "DialogSubtitles.xml") - { -- m_loadType = KEEP_IN_MEMORY; -+ m_loadType = LOAD_ON_GUI_INIT; - m_subtitles = new CFileItemList; - m_serviceItems = new CFileItemList; - m_pausedOnRun = false; -diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp -index 1ccabc8..43691bf 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp -@@ -61,7 +61,7 @@ CGUIDialogVideoBookmarks::CGUIDialogVideoBookmarks() - : CGUIDialog(WINDOW_DIALOG_VIDEO_BOOKMARKS, "VideoOSDBookmarks.xml") - { - m_vecItems = new CFileItemList; -- m_loadType = KEEP_IN_MEMORY; -+ m_loadType = LOAD_ON_GUI_INIT; - } - - CGUIDialogVideoBookmarks::~CGUIDialogVideoBookmarks() -diff --git a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp -index 98c3c5a..ba1b5f4 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp -@@ -35,7 +35,7 @@ using namespace PVR; - CGUIDialogVideoOSD::CGUIDialogVideoOSD(void) - : CGUIDialog(WINDOW_DIALOG_VIDEO_OSD, "VideoOSD.xml") - { -- m_loadType = KEEP_IN_MEMORY; -+ m_loadType = LOAD_ON_GUI_INIT; - } - - CGUIDialogVideoOSD::~CGUIDialogVideoOSD(void) -diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -index ca65fdc..fbd2a52 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -@@ -65,7 +65,9 @@ using namespace std; - CGUIDialogVideoSettings::CGUIDialogVideoSettings() - : CGUIDialogSettingsManualBase(WINDOW_DIALOG_VIDEO_OSD_SETTINGS, "VideoOSDSettings.xml"), - m_viewModeChanged(false) --{ } -+{ -+ m_loadType = LOAD_ON_GUI_INIT; -+} - - CGUIDialogVideoSettings::~CGUIDialogVideoSettings() - { } diff --git a/packages/mediacenter/kodi/patches/kodi-999.94-add_devinput_KEY_TV.patch b/packages/mediacenter/kodi/patches/kodi-999.94-add_devinput_KEY_TV.patch deleted file mode 100644 index 1c4df00b06..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.94-add_devinput_KEY_TV.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur xbmc-14-f6a3308/system/Lircmap.xml xbmc-14-f6a3308.patch/system/Lircmap.xml ---- xbmc-14-f6a3308/system/Lircmap.xml 2014-09-18 11:39:57.000000000 +0200 -+++ xbmc-14-f6a3308.patch/system/Lircmap.xml 2014-09-18 21:36:50.615305824 +0200 -@@ -574,6 +574,7 @@ - KEY_AUDIO - KEY_CAMERA - KEY_TUNER -+ KEY_TV - KEY_TEXT - KEY_NUMERIC_1 - KEY_NUMERIC_2 diff --git a/packages/mediacenter/kodi/patches/kodi-999.95-backportPR6312PR6311PR6295.patch b/packages/mediacenter/kodi/patches/kodi-999.95-backportPR6312PR6311PR6295.patch deleted file mode 100644 index 034a1fcf23..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.95-backportPR6312PR6311PR6295.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 7f928f9f341b4321c24c58cb513edbc9107dbde2 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Thu, 29 Jan 2015 14:55:18 +0100 -Subject: [PATCH 1/5] dvdplayer: fix calculation of level when data based - ---- - 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 f030e37..3a96bbc 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -869,7 +869,7 @@ int CDVDPlayerVideo::GetLevel() const - int datasize = m_messageQueue.GetDataSize(); - if (m_pVideoCodec) - datasize += m_pVideoCodec->GetDataSize(); -- return min(100, (int)(100 * datasize / (m_messageQueue.GetMaxDataSize() * m_messageQueue.GetMaxTimeSize()))); -+ return min(100, (int)((100.0 * datasize) / m_messageQueue.GetMaxDataSize())); - } - else - { --- -1.9.1 - - -From 5e40b28269cf962f1585c44a2e0ff0f17d456877 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 31 Jan 2015 21:16:33 +0100 -Subject: [PATCH 2/5] dvdplayer: drop dead code - IHardwareDecoder::Section - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 6 +----- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 1 - - xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h | 1 - - 3 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index ae67480..e4b7c74 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -451,10 +451,6 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - shared_ptr lock; - if(m_pHardware) - { -- CCriticalSection* section = m_pHardware->Section(); -- if(section) -- lock = shared_ptr(new CSingleLock(*section)); -- - int result; - if(pData) - result = m_pHardware->Check(m_pCodecContext); -@@ -909,4 +905,4 @@ void CDVDVideoCodecFFmpeg::DisposeHWDecoders() - m_disposeDecoders.back()->Release(); - m_disposeDecoders.pop_back(); - } --} -\ No newline at end of file -+} -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index f18da12..ed806f8 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -52,7 +52,6 @@ public: - virtual unsigned GetAllowedReferences() { return 0; } - virtual bool CanSkipDeint() {return false; } - virtual const std::string Name() = 0; -- virtual CCriticalSection* Section() { return NULL; } - }; - - CDVDVideoCodecFFmpeg(); -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h -index 95adb94..5586259 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h -@@ -39,7 +39,6 @@ public: - virtual int Check (AVCodecContext* avctx); - virtual void Close(); - virtual const std::string Name() { return "vda"; } -- virtual CCriticalSection* Section() { return NULL; } - virtual unsigned GetAllowedReferences(); - - int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); --- -1.9.1 - - -From 0949bda558b4dfa80bd81c828e779ef152197460 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 31 Jan 2015 22:29:11 +0100 -Subject: [PATCH 3/5] dvdplayer: do not reset hw decoder if just ffmpeg - get_buffer failed - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 1 + - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 9 +++++++++ - 2 files changed, 10 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 1dd7590..909704e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -171,6 +171,7 @@ class CDVDCodecOptions; - #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data - #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again - #define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped -+#define VC_NOBUFFER 0x00000040 // last FFmpeg GetBuffer failed - - class CDVDVideoCodec - { -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index e4b7c74..5ec0e9b 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -495,6 +495,15 @@ int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double p - - if (len < 0) - { -+ if(m_pHardware) -+ { -+ int result = m_pHardware->Check(m_pCodecContext); -+ if (result & VC_NOBUFFER) -+ { -+ result = m_pHardware->Decode(m_pCodecContext, NULL); -+ return result; -+ } -+ } - CLog::Log(LOGERROR, "%s - avcodec_decode_video returned failure", __FUNCTION__); - return VC_ERROR; - } --- -1.9.1 - - -From 6eb4d52bf0183078cc8cbeb3f235e867066ae998 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 1 Feb 2015 07:47:12 +0100 -Subject: [PATCH 4/5] VAAPI: avoid reset when running out of surfaces - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 15 ++++++++++++--- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 1 + - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index ed0b745..0f91b02 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -468,6 +468,7 @@ CDecoder::CDecoder() : m_vaapiOutput(&m_inMsgEvent) - m_vaapiConfig.contextId = VA_INVALID_ID; - m_vaapiConfig.configId = VA_INVALID_ID; - m_avctx = NULL; -+ m_getBufferError = false; - } - - CDecoder::~CDecoder() -@@ -695,9 +696,9 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags) - uint16_t decoded, processed, render; - bool vpp; - va->m_bufferStats.Get(decoded, processed, render, vpp); -- CLog::Log(LOGERROR, "VAAPI::FFGetBuffer - no surface available - dec: %d, render: %d", -+ CLog::Log(LOGWARNING, "VAAPI::FFGetBuffer - no surface available - dec: %d, render: %d", - decoded, render); -- va->m_DisplayState = VAAPI_ERROR; -+ va->m_getBufferError = true; - return -1; - } - -@@ -732,6 +733,8 @@ void CDecoder::FFReleaseBuffer(uint8_t *data) - - int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) - { -+ m_getBufferError = false; -+ - int result = Check(avctx); - if (result) - return result; -@@ -848,6 +851,7 @@ int CDecoder::Decode(AVCodecContext* avctx, AVFrame* pFrame) - - int CDecoder::Check(AVCodecContext* avctx) - { -+ int ret = 0; - EDisplayState state; - - { CSingleLock lock(m_DecoderSection); -@@ -889,7 +893,12 @@ int CDecoder::Check(AVCodecContext* avctx) - else - return VC_ERROR; - } -- return 0; -+ -+ if (m_getBufferError) -+ ret |= VC_NOBUFFER; -+ -+ m_getBufferError = false; -+ return ret; - } - - bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index 6b2b67a..f737edc 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -449,6 +449,7 @@ protected: - CVideoSurfaces m_videoSurfaces; - vaapi_context m_hwContext; - AVCodecContext* m_avctx; -+ bool m_getBufferError; - - COutput m_vaapiOutput; - CVaapiBufferStats m_bufferStats; --- -1.9.1 - - -From fe1f52cf795348b0a6816647acf46343b83dec4e Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 1 Feb 2015 09:25:12 +0100 -Subject: [PATCH 5/5] dvdplayer: avoid unwanted dropping in output stage of - video - -Conflicts: - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 3a96bbc..4556cc8 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1219,9 +1219,12 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - - AutoCrop(pPicture); - -- int buffer = g_renderManager.WaitForBuffer(m_bStop, std::max(DVD_TIME_TO_MSEC(iSleepTime) + 500, 1)); -+ int buffer = g_renderManager.WaitForBuffer(m_bStop, std::max(DVD_TIME_TO_MSEC(iSleepTime) + 500, 50)); - if (buffer < 0) -+ { -+ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); - return EOS_DROPPED; -+ } - - ProcessOverlays(pPicture, pts); - -@@ -1236,7 +1239,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - } - - if (index < 0) -+ { -+ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); - return EOS_DROPPED; -+ } - - g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); - --- -1.9.1 - diff --git a/packages/mediacenter/kodi/patches/kodi-999.96-PR6090.patch b/packages/mediacenter/kodi/patches/kodi-999.96-PR6090.patch deleted file mode 100644 index a51682ecda..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.96-PR6090.patch +++ /dev/null @@ -1,1004 +0,0 @@ -From ced0caecb0c5d4862290a1fbbaec0665ab6847a7 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 2 Jan 2015 10:02:09 +0100 -Subject: [PATCH 1/6] renderer: drop old tempfix firstflippage, did not work - anyway because RendererHandlesPresent returned always true - ---- - xbmc/Application.cpp | 2 +- - xbmc/cores/VideoRenderers/RenderManager.cpp | 9 --------- - xbmc/cores/VideoRenderers/RenderManager.h | 5 ----- - xbmc/guilib/GUIVideoControl.cpp | 3 +-- - 4 files changed, 2 insertions(+), 17 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 4a5619a..aa7aed0 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2222,7 +2222,7 @@ void CApplication::Render() - bool extPlayerActive = m_pPlayer->GetCurrentPlayer() == EPC_EXTPLAYER && m_pPlayer->IsPlaying() && !m_AppFocused; - - m_bPresentFrame = false; -- if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback() && g_renderManager.RendererHandlesPresent()) -+ if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) - { - m_bPresentFrame = g_renderManager.FrameWait(100); - hasRendered = true; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index b31f3c9..ab894ba 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -293,19 +293,12 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_sleeptime = 1.0; - m_presentevent.notifyAll(); - -- m_firstFlipPage = false; // tempfix -- - CLog::Log(LOGDEBUG, "CXBMCRenderManager::Configure - %d", m_QueueSize); - } - - return result; - } - --bool CXBMCRenderManager::RendererHandlesPresent() const --{ -- return IsConfigured() && (m_firstFlipPage || m_format != RENDER_FMT_BYPASS); --} -- - bool CXBMCRenderManager::IsConfigured() const - { - if (!m_pRenderer) -@@ -661,8 +654,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - - if(!m_pRenderer) return; - -- m_firstFlipPage = true; // tempfix -- - EPRESENTMETHOD presentmethod; - - EDEINTERLACEMODE deinterlacemode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index d3c2f1d..1086066 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -143,8 +143,6 @@ public: - - void UpdateResolution(); - -- bool RendererHandlesPresent() const; -- - #ifdef HAS_GL - CLinuxRendererGL *m_pRenderer; - #elif defined(HAS_MMAL) -@@ -267,9 +265,6 @@ protected: - //set to true when adding something to m_captures, set to false when m_captures is made empty - //std::list::empty() isn't thread safe, using an extra bool will save a lock per render when no captures are requested - bool m_hasCaptures; -- -- // temporary fix for RendererHandlesPresent after #2811 -- bool m_firstFlipPage; - }; - - extern CXBMCRenderManager g_renderManager; -diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp -index 22d0fc8..c47a6d5 100644 ---- a/xbmc/guilib/GUIVideoControl.cpp -+++ b/xbmc/guilib/GUIVideoControl.cpp -@@ -43,8 +43,7 @@ CGUIVideoControl::~CGUIVideoControl(void) - void CGUIVideoControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) - { - // TODO Proper processing which marks when its actually changed. Just mark always for now. -- if (g_renderManager.RendererHandlesPresent()) -- MarkDirtyRegion(); -+ MarkDirtyRegion(); - - CGUIControl::Process(currentTime, dirtyregions); - } --- -1.9.1 - - -From 6d4517a48e8ef757d6f7ae15067858a2bcdf782d Mon Sep 17 00:00:00 2001 -From: smallint -Date: Fri, 2 Jan 2015 15:35:33 +0000 -Subject: [PATCH 2/6] Set dirty flag in teletext dialog if required - ---- - xbmc/video/dialogs/GUIDialogTeletext.cpp | 19 +++++++++++++++++++ - xbmc/video/dialogs/GUIDialogTeletext.h | 1 + - 2 files changed, 20 insertions(+) - -diff --git a/xbmc/video/dialogs/GUIDialogTeletext.cpp b/xbmc/video/dialogs/GUIDialogTeletext.cpp -index c552ae6..9be4548 100644 ---- a/xbmc/video/dialogs/GUIDialogTeletext.cpp -+++ b/xbmc/video/dialogs/GUIDialogTeletext.cpp -@@ -46,7 +46,10 @@ CGUIDialogTeletext::~CGUIDialogTeletext() - bool CGUIDialogTeletext::OnAction(const CAction& action) - { - if (m_TextDecoder.HandleAction(action)) -+ { -+ MarkDirtyRegion(); - return true; -+ } - - return CGUIDialog::OnAction(action); - } -@@ -54,6 +57,7 @@ bool CGUIDialogTeletext::OnAction(const CAction& action) - bool CGUIDialogTeletext::OnBack(int actionID) - { - m_bClose = true; -+ MarkDirtyRegion(); - return true; - } - -@@ -79,6 +83,12 @@ bool CGUIDialogTeletext::OnMessage(CGUIMessage& message) - return CGUIDialog::OnMessage(message); - } - -+void CGUIDialogTeletext::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) -+{ -+ CGUIDialog::Process(currentTime, dirtyregions); -+ m_renderRegion = m_vertCoords; -+} -+ - void CGUIDialogTeletext::Render() - { - // Do not render if we have no texture -@@ -93,12 +103,18 @@ void CGUIDialogTeletext::Render() - if (!m_bClose) - { - if (teletextFadeAmount < 100) -+ { - teletextFadeAmount = std::min(100, teletextFadeAmount + 5); -+ MarkDirtyRegion(); -+ } - } - else - { - if (teletextFadeAmount > 0) -+ { - teletextFadeAmount = std::max(0, teletextFadeAmount - 10); -+ MarkDirtyRegion(); -+ } - - if (teletextFadeAmount == 0) - Close(); -@@ -109,6 +125,7 @@ void CGUIDialogTeletext::Render() - { - m_pTxtTexture->Update(m_TextDecoder.GetWidth(), m_TextDecoder.GetHeight(), m_TextDecoder.GetWidth()*4, XB_FMT_A8R8G8B8, textureBuffer, false); - m_TextDecoder.RenderingDone(); -+ MarkDirtyRegion(); - } - - color_t color = ((color_t)(teletextFadeAmount * 2.55f) & 0xff) << 24 | 0xFFFFFF; -@@ -184,4 +201,6 @@ void CGUIDialogTeletext::SetCoordinates() - top, - right, - bottom); -+ -+ MarkDirtyRegion(); - } -diff --git a/xbmc/video/dialogs/GUIDialogTeletext.h b/xbmc/video/dialogs/GUIDialogTeletext.h -index 51aced5..e8e11f8 100644 ---- a/xbmc/video/dialogs/GUIDialogTeletext.h -+++ b/xbmc/video/dialogs/GUIDialogTeletext.h -@@ -32,6 +32,7 @@ public: - virtual bool OnMessage(CGUIMessage& message); - virtual bool OnAction(const CAction& action); - virtual bool OnBack(int actionID); -+ virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions); - virtual void Render(); - virtual void OnInitWindow(); - virtual void OnDeinitWindow(int nextWindowID); --- -1.9.1 - - -From c374f149e72e7786644c49aa096a7c963c6eb254 Mon Sep 17 00:00:00 2001 -From: smallint -Date: Sat, 16 Aug 2014 17:29:15 +0200 -Subject: [PATCH 3/6] renderer: improve rendering to gui and separate video - layer - ---- - xbmc/Application.cpp | 10 +--- - xbmc/cores/VideoRenderers/BaseRenderer.h | 1 + - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 52 +++++++++++++-------- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 2 + - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 15 ------ - xbmc/cores/VideoRenderers/MMALRenderer.h | 1 + - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 18 +++++++ - xbmc/cores/VideoRenderers/OverlayRenderer.h | 1 + - xbmc/cores/VideoRenderers/RenderManager.cpp | 62 ++++++++++++++++++++----- - xbmc/cores/VideoRenderers/RenderManager.h | 5 +- - xbmc/guilib/GUIControl.h | 3 ++ - xbmc/guilib/GUIControlGroup.cpp | 7 +++ - xbmc/guilib/GUIControlGroup.h | 1 + - xbmc/guilib/GUIVideoControl.cpp | 31 ++++++++++++- - xbmc/guilib/GUIVideoControl.h | 1 + - xbmc/guilib/GUIWindowManager.cpp | 22 ++++++++- - xbmc/guilib/GUIWindowManager.h | 1 + - xbmc/video/windows/GUIWindowFullScreen.cpp | 31 ++++++++++++- - xbmc/video/windows/GUIWindowFullScreen.h | 2 + - 19 files changed, 204 insertions(+), 62 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index aa7aed0..3a222d4 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2170,9 +2170,6 @@ bool CApplication::RenderNoPresent() - // dont show GUI when playing full screen video - if (g_graphicsContext.IsFullScreenVideo()) - { -- g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), false); -- g_renderManager.Render(true, 0, 255); -- - // close window overlays - CGUIDialog *overlay = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OVERLAY); - if (overlay) overlay->Close(true); -@@ -2225,7 +2222,6 @@ void CApplication::Render() - if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) - { - m_bPresentFrame = g_renderManager.FrameWait(100); -- hasRendered = true; - } - else - { -@@ -2268,8 +2264,6 @@ void CApplication::Render() - if(!g_Windowing.BeginRender()) - return; - -- g_renderManager.FrameMove(); -- - CDirtyRegionList dirtyRegions = g_windowManager.GetDirty(); - if(g_graphicsContext.GetStereoMode()) - { -@@ -2291,8 +2285,6 @@ void CApplication::Render() - hasRendered = true; - } - -- g_renderManager.FrameFinish(); -- - g_Windowing.EndRender(); - - // execute post rendering actions (finalize window closing) -@@ -2317,7 +2309,7 @@ void CApplication::Render() - flip = true; - - //fps limiter, make sure each frame lasts at least singleFrameTime milliseconds -- if (limitFrames || !flip) -+ if (limitFrames || !(flip || m_bPresentFrame)) - { - if (!limitFrames) - singleFrameTime = 40; //if not flipping, loop at 25 fps -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index 850aa6f..8988e35 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -94,6 +94,7 @@ public: - virtual void SetBufferSize(int numBuffers) { } - virtual void ReleaseBuffer(int idx) { } - virtual bool NeedBufferForRef(int idx) { return false; } -+ virtual bool IsGuiLayer() { return true; } - - virtual bool Supports(ERENDERFEATURE feature) { return false; } - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index 81fe19b..a765461 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -526,32 +526,16 @@ void CLinuxRendererGLES::Update() - - void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - { -- if (!m_bConfigured) return; -+ if (!m_bConfigured) -+ return; - - // if its first pass, just init textures and return - if (ValidateRenderTarget()) - return; - -- if (m_renderMethod & RENDER_BYPASS) -+ if (!IsGuiLayer()) - { -- ManageDisplay(); -- // if running bypass, then the player might need the src/dst rects -- // for sizing video playback on a layer other than the gles layer. -- if (m_RenderUpdateCallBackFn) -- (*m_RenderUpdateCallBackFn)(m_RenderUpdateCallBackCtx, m_sourceRect, m_destRect); -- -- CRect old = g_graphicsContext.GetScissors(); -- -- g_graphicsContext.BeginPaint(); -- g_graphicsContext.SetScissors(m_destRect); -- -- glEnable(GL_BLEND); -- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- glClearColor(0, 0, 0, 0); -- glClear(GL_COLOR_BUFFER_BIT); -- -- g_graphicsContext.SetScissors(old); -- g_graphicsContext.EndPaint(); -+ RenderUpdateVideo(clear, flags, alpha); - return; - } - -@@ -606,6 +590,26 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - g_graphicsContext.EndPaint(); - } - -+void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) -+{ -+ if (!m_bConfigured) -+ return; -+ -+ if (IsGuiLayer()) -+ return; -+ -+ if (m_renderMethod & RENDER_BYPASS) -+ { -+ ManageDisplay(); -+ // if running bypass, then the player might need the src/dst rects -+ // for sizing video playback on a layer other than the gles layer. -+ if (m_RenderUpdateCallBackFn) -+ (*m_RenderUpdateCallBackFn)(m_RenderUpdateCallBackCtx, m_sourceRect, m_destRect); -+ -+ return; -+ } -+} -+ - void CLinuxRendererGLES::FlipPage(int source) - { - if( source >= 0 && source < m_NumYV12Buffers ) -@@ -3055,5 +3059,13 @@ void CLinuxRendererGLES::AddProcessor(CDVDVideoCodecIMXBuffer *buffer, int index - } - #endif - -+bool CLinuxRendererGLES::IsGuiLayer() -+{ -+ if (m_format == RENDER_FMT_BYPASS) -+ return false; -+ else -+ return true; -+} -+ - #endif - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index d8bf35d..b865033 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -144,6 +144,7 @@ public: - virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } - virtual unsigned int GetOptimalBufferSize(); -+ virtual bool IsGuiLayer(); - - virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - -@@ -177,6 +178,7 @@ public: - - protected: - virtual void Render(DWORD flags, int index); -+ void RenderUpdateVideo(bool clear, DWORD flags = 0, DWORD alpha = 255); - - int NextYV12Texture(); - virtual bool ValidateRenderTarget(); -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 03a05de..69ff30a 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -347,21 +347,6 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - // for sizing video playback on a layer other than the gles layer. - if (m_RenderUpdateCallBackFn) - (*m_RenderUpdateCallBackFn)(m_RenderUpdateCallBackCtx, m_sourceRect, m_destRect); -- -- SetVideoRect(m_sourceRect, m_destRect); -- -- CRect old = g_graphicsContext.GetScissors(); -- -- g_graphicsContext.BeginPaint(); -- g_graphicsContext.SetScissors(m_destRect); -- -- glEnable(GL_BLEND); -- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- glClearColor(0, 0, 0, 0); -- glClear(GL_COLOR_BUFFER_BIT); -- -- g_graphicsContext.SetScissors(old); -- g_graphicsContext.EndPaint(); - } - - void CMMALRenderer::FlipPage(int source) -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.h b/xbmc/cores/VideoRenderers/MMALRenderer.h -index 8ca0b94..62d513e 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.h -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.h -@@ -90,6 +90,7 @@ public: - virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } - virtual unsigned int GetOptimalBufferSize() { return NUM_BUFFERS; } - virtual void SetVideoRect(const CRect& SrcRect, const CRect& DestRect); -+ virtual bool IsGuiLayer() { return false; } - - void vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer); - protected: -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index ea07d9f..e8c4bec 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -306,6 +306,24 @@ void CRenderer::Render(COverlay* o, float adjust_height) - o->Render(state); - } - -+bool CRenderer::HasOverlay(int idx) -+{ -+ bool hasOverlay = false; -+ -+ CSingleLock lock(m_section); -+ -+ SElementV& list = m_buffers[idx]; -+ for(SElementV::iterator it = list.begin(); it != list.end(); ++it) -+ { -+ if (it->overlay || it->overlay_dvd) -+ { -+ hasOverlay = true; -+ break; -+ } -+ } -+ return hasOverlay; -+} -+ - COverlay* CRenderer::Convert(CDVDOverlaySSA* o, double pts) - { - CRect src, dst; -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index 9b8e9da..ca02644 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.h -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -100,6 +100,7 @@ namespace OVERLAY { - void Render(int idx); - void Flush(); - void Release(int idx); -+ bool HasOverlay(int idx); - - protected: - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index ab894ba..63bbdcc 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -120,6 +120,7 @@ CXBMCRenderManager::CXBMCRenderManager() - m_QueueSize = 2; - m_QueueSkip = 0; - m_format = RENDER_FMT_NONE; -+ m_renderedOverlay = false; - } - - CXBMCRenderManager::~CXBMCRenderManager() -@@ -233,7 +234,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - - /* make sure any queued frame was fully presented */ - XbmcThreads::EndTime endtime(5000); -- while(m_presentstep != PRESENT_IDLE) -+ while(m_presentstep != PRESENT_IDLE && m_presentstep != PRESENT_READY) - { - if(endtime.IsTimePast()) - { -@@ -292,6 +293,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_presentpts = DVD_NOPTS_VALUE; - m_sleeptime = 1.0; - m_presentevent.notifyAll(); -+ m_renderedOverlay = false; - - CLog::Log(LOGDEBUG, "CXBMCRenderManager::Configure - %d", m_QueueSize); - } -@@ -766,22 +768,58 @@ void CXBMCRenderManager::RegisterRenderFeaturesCallBack(const void *ctx, RenderF - m_pRenderer->RegisterRenderFeaturesCallBack(ctx, fn); - } - --void CXBMCRenderManager::Render(bool clear, DWORD flags, DWORD alpha) -+void CXBMCRenderManager::Render(bool clear, DWORD flags, DWORD alpha, bool gui) - { - CSharedLock lock(m_sharedSection); - -- SPresent& m = m_Queue[m_presentsource]; -+ if (!gui && m_pRenderer->IsGuiLayer()) -+ return; - -- if( m.presentmethod == PRESENT_METHOD_BOB ) -- PresentFields(clear, flags, alpha); -- else if( m.presentmethod == PRESENT_METHOD_WEAVE ) -- PresentFields(clear, flags | RENDER_FLAG_WEAVE, alpha); -- else if( m.presentmethod == PRESENT_METHOD_BLEND ) -- PresentBlend(clear, flags, alpha); -- else -- PresentSingle(clear, flags, alpha); -+ if (!gui || m_pRenderer->IsGuiLayer()) -+ { -+ SPresent& m = m_Queue[m_presentsource]; -+ -+ if( m.presentmethod == PRESENT_METHOD_BOB ) -+ PresentFields(clear, flags, alpha); -+ else if( m.presentmethod == PRESENT_METHOD_WEAVE ) -+ PresentFields(clear, flags | RENDER_FLAG_WEAVE, alpha); -+ else if( m.presentmethod == PRESENT_METHOD_BLEND ) -+ PresentBlend(clear, flags, alpha); -+ else -+ PresentSingle(clear, flags, alpha); -+ } -+ -+ if (gui) -+ { -+ m_renderedOverlay = m_overlays.HasOverlay(m_presentsource); -+ m_overlays.Render(m_presentsource); -+ } -+} -+ -+bool CXBMCRenderManager::IsGuiLayer() -+{ -+ { CSingleLock lock(m_presentlock); -+ -+ if (!m_pRenderer) -+ return false; -+ -+ if (m_pRenderer->IsGuiLayer() || m_renderedOverlay || m_overlays.HasOverlay(m_presentsource)) -+ return true; -+ } -+ return false; -+} -+ -+bool CXBMCRenderManager::IsVideoLayer() -+{ -+ { CSingleLock lock(m_presentlock); - -- m_overlays.Render(m_presentsource); -+ if (!m_pRenderer) -+ return false; -+ -+ if (!m_pRenderer->IsGuiLayer()) -+ return true; -+ } -+ return false; - } - - /* simple present method */ -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 1086066..7280423 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -60,7 +60,9 @@ public: - void FrameMove(); - void FrameFinish(); - bool FrameWait(int ms); -- void Render(bool clear, DWORD flags = 0, DWORD alpha = 255); -+ void Render(bool clear, DWORD flags = 0, DWORD alpha = 255, bool gui = true); -+ bool IsGuiLayer(); -+ bool IsVideoLayer(); - void SetupScreenshot(); - - CRenderCapture* AllocRenderCapture(); -@@ -257,6 +259,7 @@ protected: - - - OVERLAY::CRenderer m_overlays; -+ bool m_renderedOverlay; - - void RenderCapture(CRenderCapture* capture); - void RemoveCapture(CRenderCapture* capture); -diff --git a/xbmc/guilib/GUIControl.h b/xbmc/guilib/GUIControl.h -index b303ccc..6e0b92e 100644 ---- a/xbmc/guilib/GUIControl.h -+++ b/xbmc/guilib/GUIControl.h -@@ -83,6 +83,9 @@ public: - virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions); - virtual void DoRender(); - virtual void Render() {}; -+ // Called after the actual rendering is completed to trigger additional -+ // non GUI rendering operations -+ virtual void RenderEx() {}; - - /*! \brief Returns whether or not we have processed */ - bool HasProcessed() const { return m_hasProcessed; }; -diff --git a/xbmc/guilib/GUIControlGroup.cpp b/xbmc/guilib/GUIControlGroup.cpp -index 7858e42..bdd7f54 100644 ---- a/xbmc/guilib/GUIControlGroup.cpp -+++ b/xbmc/guilib/GUIControlGroup.cpp -@@ -133,6 +133,13 @@ void CGUIControlGroup::Render() - g_graphicsContext.RestoreOrigin(); - } - -+void CGUIControlGroup::RenderEx() -+{ -+ for (iControls it = m_children.begin(); it != m_children.end(); ++it) -+ (*it)->RenderEx(); -+ CGUIControl::RenderEx(); -+} -+ - bool CGUIControlGroup::OnAction(const CAction &action) - { - ASSERT(false); // unimplemented -diff --git a/xbmc/guilib/GUIControlGroup.h b/xbmc/guilib/GUIControlGroup.h -index 054757f..0b38a56 100644 ---- a/xbmc/guilib/GUIControlGroup.h -+++ b/xbmc/guilib/GUIControlGroup.h -@@ -42,6 +42,7 @@ public: - - virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions); - virtual void Render(); -+ virtual void RenderEx(); - virtual bool OnAction(const CAction &action); - virtual bool OnMessage(CGUIMessage& message); - virtual bool SendControlMessage(CGUIMessage& message); -diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp -index c47a6d5..126e95f 100644 ---- a/xbmc/guilib/GUIVideoControl.cpp -+++ b/xbmc/guilib/GUIVideoControl.cpp -@@ -42,8 +42,11 @@ CGUIVideoControl::~CGUIVideoControl(void) - - void CGUIVideoControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) - { -+ g_renderManager.FrameMove(); -+ - // TODO Proper processing which marks when its actually changed. Just mark always for now. -- MarkDirtyRegion(); -+ if (g_renderManager.IsGuiLayer()) -+ MarkDirtyRegion(); - - CGUIControl::Process(currentTime, dirtyregions); - } -@@ -67,14 +70,38 @@ void CGUIVideoControl::Render() - - #ifdef HAS_VIDEO_PLAYBACK - color_t alpha = g_graphicsContext.MergeAlpha(0xFF000000) >> 24; -- g_renderManager.Render(false, 0, alpha); -+ if (g_renderManager.IsVideoLayer()) -+ { -+ CRect old = g_graphicsContext.GetScissors(); -+ CRect region = GetRenderRegion(); -+ region.Intersect(old); -+ g_graphicsContext.BeginPaint(); -+ g_graphicsContext.SetScissors(region); -+ g_graphicsContext.Clear(0); -+ g_graphicsContext.SetScissors(old); -+ g_graphicsContext.EndPaint(); -+ } -+ else -+ g_renderManager.Render(false, 0, alpha); - #else - ((CDummyVideoPlayer *)g_application.m_pPlayer->GetInternal())->Render(); - #endif - } -+ // TODO: remove this crap: HAS_VIDEO_PLAYBACK -+ // instantiateing a vidio control having no playback is complete nonsense - CGUIControl::Render(); - } - -+void CGUIVideoControl::RenderEx() -+{ -+#ifdef HAS_VIDEO_PLAYBACK -+ if (g_application.m_pPlayer->IsPlayingVideo() && g_renderManager.IsStarted()) -+ g_renderManager.Render(false, 0, 255, false); -+ g_renderManager.FrameFinish(); -+#endif -+ CGUIControl::RenderEx(); -+} -+ - EVENT_RESULT CGUIVideoControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event) - { - if (!g_application.m_pPlayer->IsPlayingVideo()) return EVENT_RESULT_UNHANDLED; -diff --git a/xbmc/guilib/GUIVideoControl.h b/xbmc/guilib/GUIVideoControl.h -index a692d01..0f89a9a 100644 ---- a/xbmc/guilib/GUIVideoControl.h -+++ b/xbmc/guilib/GUIVideoControl.h -@@ -44,6 +44,7 @@ public: - - virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions); - virtual void Render(); -+ virtual void RenderEx(); - virtual EVENT_RESULT OnMouseEvent(const CPoint &point, const CMouseEvent &event); - virtual bool CanFocus() const; - virtual bool CanFocusFromPoint(const CPoint &point) const; -diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp -index 788bbe9..ef97251 100644 ---- a/xbmc/guilib/GUIWindowManager.cpp -+++ b/xbmc/guilib/GUIWindowManager.cpp -@@ -547,6 +547,24 @@ void CGUIWindowManager::RenderPass() const - } - } - -+void CGUIWindowManager::RenderEx() const -+{ -+ CGUIWindow* pWindow = GetWindow(GetActiveWindow()); -+ if (pWindow) -+ pWindow->RenderEx(); -+ -+ // We don't call RenderEx for now on dialogs since it is used -+ // to trigger non gui video rendering. We can activate it later at any time. -+ /* -+ vector &activeDialogs = m_activeDialogs; -+ for (iDialog it = activeDialogs.begin(); it != activeDialogs.end(); ++it) -+ { -+ if ((*it)->IsDialogRunning()) -+ (*it)->RenderEx(); -+ } -+ */ -+} -+ - bool CGUIWindowManager::Render() - { - assert(g_application.IsCurrentThread()); -@@ -586,13 +604,15 @@ bool CGUIWindowManager::Render() - if (g_advancedSettings.m_guiVisualizeDirtyRegions) - { - g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetResInfo(), false); -- const CDirtyRegionList &markedRegions = m_tracker.GetMarkedRegions(); -+ const CDirtyRegionList &markedRegions = m_tracker.GetMarkedRegions(); - for (CDirtyRegionList::const_iterator i = markedRegions.begin(); i != markedRegions.end(); ++i) - CGUITexture::DrawQuad(*i, 0x0fff0000); - for (CDirtyRegionList::const_iterator i = dirtyRegions.begin(); i != dirtyRegions.end(); ++i) - CGUITexture::DrawQuad(*i, 0x4c00ff00); - } - -+ RenderEx(); -+ - return hasRendered; - } - -diff --git a/xbmc/guilib/GUIWindowManager.h b/xbmc/guilib/GUIWindowManager.h -index 4f1f96f..ea7239a 100644 ---- a/xbmc/guilib/GUIWindowManager.h -+++ b/xbmc/guilib/GUIWindowManager.h -@@ -144,6 +144,7 @@ public: - #endif - private: - void RenderPass() const; -+ void RenderEx() const; - - void LoadNotOnDemandWindows(); - void UnloadNotOnDemandWindows(); -diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp -index dfbf773..ed7c090 100644 ---- a/xbmc/video/windows/GUIWindowFullScreen.cpp -+++ b/xbmc/video/windows/GUIWindowFullScreen.cpp -@@ -353,6 +353,12 @@ bool CGUIWindowFullScreen::OnAction(const CAction &action) - return CGUIWindow::OnAction(action); - } - -+void CGUIWindowFullScreen::ClearBackground() -+{ -+ if (g_renderManager.IsVideoLayer()) -+ g_graphicsContext.Clear(0); -+} -+ - void CGUIWindowFullScreen::OnWindowLoaded() - { - CGUIWindow::OnWindowLoaded(); -@@ -455,6 +461,7 @@ bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) - #ifdef HAS_VIDEO_PLAYBACK - // make sure renderer is uptospeed - g_renderManager.Update(); -+ g_renderManager.FrameFinish(); - #endif - return true; - } -@@ -730,22 +737,40 @@ void CGUIWindowFullScreen::FrameMove() - SET_CONTROL_HIDDEN(BLUE_BAR); - SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER); - } -+ -+ g_renderManager.FrameMove(); - } - - void CGUIWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList &dirtyregion) - { -+ if (g_renderManager.IsGuiLayer()) -+ MarkDirtyRegion(); -+ -+ CGUIWindow::Process(currentTime, dirtyregion); -+ - // TODO: This isn't quite optimal - ideally we'd only be dirtying up the actual video render rect - // which is probably the job of the renderer as it can more easily track resizing etc. -- MarkDirtyRegion(); -- CGUIWindow::Process(currentTime, dirtyregion); - m_renderRegion.SetRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight()); - } - - void CGUIWindowFullScreen::Render() - { -+ g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), false); -+ g_renderManager.Render(true, 0, 255); -+ g_graphicsContext.SetRenderingResolution(m_coordsRes, m_needsScaling); - CGUIWindow::Render(); - } - -+void CGUIWindowFullScreen::RenderEx() -+{ -+ CGUIWindow::RenderEx(); -+ g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetVideoResolution(), false); -+#ifdef HAS_VIDEO_PLAYBACK -+ g_renderManager.Render(false, 0, 255, false); -+ g_renderManager.FrameFinish(); -+#endif -+} -+ - void CGUIWindowFullScreen::ChangetheTimeCode(int remote) - { - if (remote >= REMOTE_0 && remote <= REMOTE_9) -@@ -851,6 +876,8 @@ void CGUIWindowFullScreen::ToggleOSD() - else - pOSD->DoModal(); - } -+ -+ MarkDirtyRegion(); - } - - void CGUIWindowFullScreen::TriggerOSD() -diff --git a/xbmc/video/windows/GUIWindowFullScreen.h b/xbmc/video/windows/GUIWindowFullScreen.h -index 03608af..5a9b101 100644 ---- a/xbmc/video/windows/GUIWindowFullScreen.h -+++ b/xbmc/video/windows/GUIWindowFullScreen.h -@@ -30,9 +30,11 @@ public: - virtual ~CGUIWindowFullScreen(void); - virtual bool OnMessage(CGUIMessage& message); - virtual bool OnAction(const CAction &action); -+ virtual void ClearBackground(); - virtual void FrameMove(); - virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregion); - virtual void Render(); -+ virtual void RenderEx(); - virtual void OnWindowLoaded(); - void ChangetheTimeCode(int remote); - void ChangetheTVGroup(bool next); --- -1.9.1 - - -From b7c95f76c19aa172c6e63a9ed327369f0edb84df Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Mon, 5 Jan 2015 11:29:15 +0100 -Subject: [PATCH 4/6] guilib: mark control dirty when setting to invisible - ---- - xbmc/guilib/GUIControl.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/guilib/GUIControl.cpp b/xbmc/guilib/GUIControl.cpp -index e3d04db..ff2086b 100644 ---- a/xbmc/guilib/GUIControl.cpp -+++ b/xbmc/guilib/GUIControl.cpp -@@ -511,6 +511,8 @@ void CGUIControl::SetVisible(bool bVisible, bool setVisState) - { - m_forceHidden = !bVisible; - SetInvalid(); -+ if (m_forceHidden) -+ MarkDirtyRegion(); - } - if (m_forceHidden) - { // reset any visible animations that are in process --- -1.9.1 - - -From b5bb845c2640e8d05d88c761ce9f31a1e5bac91d Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 6 Jan 2015 13:13:27 +0100 -Subject: [PATCH 5/6] renderer: exit gfx lock when waiting for present time - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 63bbdcc..b394d7b 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -381,7 +381,10 @@ void CXBMCRenderManager::FrameFinish() - SPresent& m = m_Queue[m_presentsource]; - - if(g_graphicsContext.IsFullScreenVideo()) -+ { -+ CSingleExit lock(g_graphicsContext); - WaitPresentTime(m.timestamp); -+ } - - m_clock_framefinish = GetPresentTime(); - --- -1.9.1 - - -From a46f3062c805d98947348626651cbff0d805d912 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 23 Jan 2015 07:41:46 +0100 -Subject: [PATCH 6/6] renderer: fix sequence from WaitFrame, Render, FrameMove - to WaitFrame, FrameMove, Render - ---- - xbmc/Application.cpp | 12 +++++++++--- - xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++-- - xbmc/cores/VideoRenderers/RenderManager.h | 3 ++- - 3 files changed, 21 insertions(+), 6 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 3a222d4..5775a76 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2212,16 +2212,17 @@ void CApplication::Render() - bool limitFrames = false; - unsigned int singleFrameTime = 10; // default limit 100 fps - -+ // Whether externalplayer is playing and we're unfocused -+ bool extPlayerActive = m_pPlayer->GetCurrentPlayer() == EPC_EXTPLAYER && m_pPlayer->IsPlaying() && !m_AppFocused; -+ - { - // Less fps in DPMS - bool lowfps = m_dpmsIsActive || g_Windowing.EnableFrameLimiter(); -- // Whether externalplayer is playing and we're unfocused -- bool extPlayerActive = m_pPlayer->GetCurrentPlayer() == EPC_EXTPLAYER && m_pPlayer->IsPlaying() && !m_AppFocused; - - m_bPresentFrame = false; - if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) - { -- m_bPresentFrame = g_renderManager.FrameWait(100); -+ m_bPresentFrame = g_renderManager.HasFrame(); - } - else - { -@@ -2322,6 +2323,11 @@ void CApplication::Render() - if (flip) - g_graphicsContext.Flip(dirtyRegions); - -+ if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) -+ { -+ g_renderManager.FrameWait(100); -+ } -+ - m_lastFrameTime = XbmcThreads::SystemClockMillis(); - CTimeUtils::UpdateFrameTime(flip); - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index b394d7b..36c2842 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -316,13 +316,21 @@ void CXBMCRenderManager::Update() - m_pRenderer->Update(); - } - --bool CXBMCRenderManager::FrameWait(int ms) -+void CXBMCRenderManager::FrameWait(int ms) - { - XbmcThreads::EndTime timeout(ms); - CSingleLock lock(m_presentlock); - while(m_presentstep == PRESENT_IDLE && !timeout.IsTimePast()) - m_presentevent.wait(lock, timeout.MillisLeft()); -- return m_presentstep != PRESENT_IDLE; -+} -+ -+bool CXBMCRenderManager::HasFrame() -+{ -+ CSingleLock lock(m_presentlock); -+ if (m_presentstep == PRESENT_FRAME || m_presentstep == PRESENT_FRAME2) -+ return true; -+ else -+ return false; - } - - void CXBMCRenderManager::FrameMove() -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 7280423..b80319a 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -59,7 +59,8 @@ public: - void Update(); - void FrameMove(); - void FrameFinish(); -- bool FrameWait(int ms); -+ void FrameWait(int ms); -+ bool HasFrame(); - void Render(bool clear, DWORD flags = 0, DWORD alpha = 255, bool gui = true); - bool IsGuiLayer(); - bool IsVideoLayer(); --- -1.9.1 - diff --git a/packages/mediacenter/kodi/patches/kodi-999.97.01-fix_frametime_for_active_vsync.patch b/packages/mediacenter/kodi/patches/kodi-999.97.01-fix_frametime_for_active_vsync.patch deleted file mode 100644 index 215bac0a73..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.97.01-fix_frametime_for_active_vsync.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 07a17ab720e13d56d8438aa460b0052aa9c02060 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 20 Mar 2015 10:25:48 +0100 -Subject: [PATCH] fix frametime for active vsync - ---- - xbmc/Application.cpp | 11 ++++++++++- - xbmc/utils/TimeUtils.cpp | 23 +++++++++++++++++++---- - xbmc/utils/TimeUtils.h | 2 +- - 3 files changed, 30 insertions(+), 6 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index a79c7dd..eef7f02 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2216,6 +2216,7 @@ void CApplication::Render() - bool hasRendered = false; - bool limitFrames = false; - unsigned int singleFrameTime = 10; // default limit 100 fps -+ bool vsync = true; - - // Whether externalplayer is playing and we're unfocused - bool extPlayerActive = m_pPlayer->GetCurrentPlayer() == EPC_EXTPLAYER && m_pPlayer->IsPlaying() && !m_AppFocused; -@@ -2228,6 +2229,8 @@ void CApplication::Render() - if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) - { - m_bPresentFrame = g_renderManager.HasFrame(); -+ if (vsync_mode == VSYNC_DISABLED) -+ vsync = false; - } - else - { -@@ -2236,9 +2239,15 @@ void CApplication::Render() - // DXMERGE - we checked for g_videoConfig.GetVSyncMode() before this - // perhaps allowing it to be set differently than the UI option?? - if (vsync_mode == VSYNC_DISABLED || vsync_mode == VSYNC_VIDEO) -+ { - limitFrames = true; // not using vsync. -+ vsync = false; -+ } - else if ((g_infoManager.GetFPS() > g_graphicsContext.GetFPS() + 10) && g_infoManager.GetFPS() > 1000 / singleFrameTime) -+ { - limitFrames = true; // using vsync, but it isn't working. -+ vsync = false; -+ } - - if (limitFrames) - { -@@ -2334,7 +2343,7 @@ void CApplication::Render() - } - - m_lastFrameTime = XbmcThreads::SystemClockMillis(); -- CTimeUtils::UpdateFrameTime(flip); -+ CTimeUtils::UpdateFrameTime(flip, vsync); - - g_renderManager.UpdateResolution(); - g_renderManager.ManageCaptures(); -diff --git a/xbmc/utils/TimeUtils.cpp b/xbmc/utils/TimeUtils.cpp -index 9f2e135..57e5e90 100644 ---- a/xbmc/utils/TimeUtils.cpp -+++ b/xbmc/utils/TimeUtils.cpp -@@ -21,6 +21,7 @@ - #include "TimeUtils.h" - #include "XBDateTime.h" - #include "threads/SystemClock.h" -+#include "guilib/GraphicContext.h" - - #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) - #include "config.h" -@@ -72,12 +73,26 @@ int64_t CurrentHostFrequency(void) - CTimeSmoother CTimeUtils::frameTimer; - unsigned int CTimeUtils::frameTime = 0; - --void CTimeUtils::UpdateFrameTime(bool flip) -+void CTimeUtils::UpdateFrameTime(bool flip, bool vsync) - { - unsigned int currentTime = XbmcThreads::SystemClockMillis(); -- if (flip) -- frameTimer.AddTimeStamp(currentTime); -- frameTime = frameTimer.GetNextFrameTime(currentTime); -+ if (vsync) -+ { -+ unsigned int last = frameTime; -+ while (frameTime < currentTime) -+ { -+ frameTime += (unsigned int)(1000 / g_graphicsContext.GetFPS()); -+ // observe wrap around -+ if (frameTime < last) -+ break; -+ } -+ } -+ else -+ { -+ if (flip) -+ frameTimer.AddTimeStamp(currentTime); -+ frameTime = frameTimer.GetNextFrameTime(currentTime); -+ } - } - - unsigned int CTimeUtils::GetFrameTime() -diff --git a/xbmc/utils/TimeUtils.h b/xbmc/utils/TimeUtils.h -index f8796d5..e07540f 100644 ---- a/xbmc/utils/TimeUtils.h -+++ b/xbmc/utils/TimeUtils.h -@@ -32,7 +32,7 @@ int64_t CurrentHostFrequency(void); - class CTimeUtils - { - public: -- static void UpdateFrameTime(bool flip); ///< update the frame time. Not threadsafe -+ static void UpdateFrameTime(bool flip, bool vsync); ///< update the frame time. Not threadsafe - static unsigned int GetFrameTime(); ///< returns the frame time in MS. Not threadsafe - static CDateTime GetLocalTime(time_t time); - --- -1.9.1 - diff --git a/packages/mediacenter/kodi/patches/kodi-999.97.02-guilib-only-update-scrollinfo-if-frametime-did-chang.patch b/packages/mediacenter/kodi/patches/kodi-999.97.02-guilib-only-update-scrollinfo-if-frametime-did-chang.patch deleted file mode 100644 index 8e4cd75eb8..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.97.02-guilib-only-update-scrollinfo-if-frametime-did-chang.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 68428562758adbcb597cadc05ba124a6bde97291 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 13 Mar 2015 20:57:17 +0100 -Subject: [PATCH] guilib: only update scrollinfo if frametime did change - ---- - xbmc/guilib/GUIFont.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/guilib/GUIFont.cpp b/xbmc/guilib/GUIFont.cpp -index a7ee668..06232cb 100644 ---- a/xbmc/guilib/GUIFont.cpp -+++ b/xbmc/guilib/GUIFont.cpp -@@ -52,7 +52,8 @@ float CScrollInfo::GetPixelsPerFrame() - delta = 100; // assume a minimum of 10 fps - m_lastFrameTime = currentTime; - // do an exponential moving average of the frame time -- m_averageFrameTime = m_averageFrameTime + (delta - m_averageFrameTime) * alphaEMA; -+ if (delta) -+ m_averageFrameTime = m_averageFrameTime + (delta - m_averageFrameTime) * alphaEMA; - // and multiply by pixel speed (per ms) to get number of pixels to move this frame - return pixelSpeed * m_averageFrameTime; - } --- -1.9.1 - diff --git a/packages/mediacenter/kodi/patches/kodi-999.98-PR6408.patch b/packages/mediacenter/kodi/patches/kodi-999.98-PR6408.patch deleted file mode 100644 index 6b601f7a2b..0000000000 --- a/packages/mediacenter/kodi/patches/kodi-999.98-PR6408.patch +++ /dev/null @@ -1,73 +0,0 @@ -From d8fff72de0159160fb4ca1c249c8365e9e1b6785 Mon Sep 17 00:00:00 2001 -From: wsnipex -Date: Wed, 11 Feb 2015 16:58:25 +0100 -Subject: [PATCH] [curl] use better method to stat shoutcast and friends - ---- - xbmc/filesystem/CurlFile.cpp | 31 +++++++++++++++++++------------ - 1 file changed, 19 insertions(+), 12 deletions(-) - -diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp -index 7d68dab..ee63ff5 100644 ---- a/xbmc/filesystem/CurlFile.cpp -+++ b/xbmc/filesystem/CurlFile.cpp -@@ -123,6 +123,19 @@ extern "C" size_t header_callback(void *ptr, size_t size, size_t nmemb, void *st - return state->HeaderCallback(ptr, size, nmemb); - } - -+/* used only by CCurlFile::Stat to bail out of unwanted transfers */ -+extern "C" int transfer_abort_callback(void *clientp, -+ curl_off_t dltotal, -+ curl_off_t dlnow, -+ curl_off_t ultotal, -+ curl_off_t ulnow) -+{ -+ if(dlnow > 0) -+ return 1; -+ else -+ return 0; -+} -+ - /* fix for silly behavior of realloc */ - static inline void* realloc_simple(void *ptr, size_t size) - { -@@ -1285,7 +1298,6 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer) - SetRequestHeaders(m_state); - g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, g_advancedSettings.m_curlconnecttimeout); - g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1); -- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/ - g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME , 1); - - if(url2.IsProtocol("ftp")) -@@ -1311,25 +1323,20 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer) - || result == CURLE_RECV_ERROR /* some silly shoutcast servers */ ) - { - /* some http servers and shoutcast servers don't give us any data on a head request */ -- /* request normal and just fail out, it's their loss */ -+ /* request normal and just bail out via progress meter callback after we received data */ - /* somehow curl doesn't reset CURLOPT_NOBODY properly so reset everything */ - SetCommonOptions(m_state); - SetRequestHeaders(m_state); - g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, g_advancedSettings.m_curlconnecttimeout); -- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, "0-0"); -- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/ -- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1); -- result = g_curlInterface.easy_perform(m_state->m_easyHandle); -- } -+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1); -+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_XFERINFOFUNCTION, transfer_abort_callback); -+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOPROGRESS, 0); - -- if( result == CURLE_HTTP_RANGE_ERROR ) -- { -- /* crap can't use the range option, disable it and try again */ -- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, NULL); - result = g_curlInterface.easy_perform(m_state->m_easyHandle); -+ - } - -- if( result != CURLE_WRITE_ERROR && result != CURLE_OK ) -+ if( result != CURLE_ABORTED_BY_CALLBACK && result != CURLE_OK ) - { - g_curlInterface.easy_release(&m_state->m_easyHandle, NULL); - errno = ENOENT; diff --git a/projects/RPi/patches/kodi/kodi-001-helix_rpb_backports.patch b/projects/RPi/patches/kodi/kodi-001-helix_rpb_backports.patch deleted file mode 100644 index bad13fb7cc..0000000000 --- a/projects/RPi/patches/kodi/kodi-001-helix_rpb_backports.patch +++ /dev/null @@ -1,6575 +0,0 @@ -From 632fd2b97fbfa016fe229cf44e6d2a42e8d91edc Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 7 Apr 2014 18:19:32 +0100 -Subject: [PATCH 01/75] [rbp/omxplayer] When opening a stream don't try to - update gui so often - ---- - xbmc/dialogs/GUIDialogBusy.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/dialogs/GUIDialogBusy.cpp b/xbmc/dialogs/GUIDialogBusy.cpp -index e7cfcdd..20b99ad 100644 ---- a/xbmc/dialogs/GUIDialogBusy.cpp -+++ b/xbmc/dialogs/GUIDialogBusy.cpp -@@ -68,7 +68,11 @@ bool CGUIDialogBusy::WaitOnEvent(CEvent &event, unsigned int displaytime /* = 10 - if (dialog) - { - dialog->Show(); -+#ifdef TARGET_RASPBERRY_PI -+ while(!event.WaitMSec(100)) -+#else - while(!event.WaitMSec(1)) -+#endif - { - g_windowManager.ProcessRenderLoop(false); - if (allowCancel && dialog->IsCanceled()) - -From 3f4ea17c35b2534740ab625358dc9c3ae1d9059d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 29 Apr 2014 15:23:22 +0100 -Subject: [PATCH 02/75] [ffmpeg] Speed up wtv index creation - -The index creation is O(N^2) with number of entries (typically thousands). -On a Pi this can take more than 60 seconds to execute for a recording of a few hours. - -By replacing with an O(N) loop, this takes virtually zero time ---- - tools/depends/target/ffmpeg/Makefile | 3 +- - .../ffmpeg_Speed_up_wtv_index_creation.patch | 47 ++++++++++++++++++++++ - 2 files changed, 49 insertions(+), 1 deletion(-) - create mode 100644 tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch - -diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile -index 0e08dcf..7ce982c 100644 ---- a/tools/depends/target/ffmpeg/Makefile -+++ b/tools/depends/target/ffmpeg/Makefile -@@ -1,6 +1,6 @@ - include ../../Makefile.include - include FFMPEG-VERSION --DEPS= ../../Makefile.include FFMPEG-VERSION Makefile -+DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ffmpeg_Speed_up_wtv_index_creation.patch - - # set to "yes" to enable patching - # we don't apply patches until we move to a vanilla ffmpeg tarball -@@ -63,6 +63,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) - rm -rf $(PLATFORM); mkdir -p $(PLATFORM) - cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) - cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig \&\& pkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure -+ cd $(PLATFORM); patch -p3 < ../ffmpeg_Speed_up_wtv_index_creation.patch - cd $(PLATFORM);\ - CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ - ./configure $(ffmpg_config) -diff --git a/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch -new file mode 100644 -index 0000000..4ac5636 ---- /dev/null -+++ b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch -@@ -0,0 +1,47 @@ -+commit 0e7427498cb1131671f6fe9d054245ae7e5a36f5 -+Author: popcornmix -+Date: Tue Mar 25 19:43:07 2014 +0000 -+ -+ [ffmpeg] Speed up wtv index creation -+ -+ The index creation is O(N^2) with number of entries (typically thousands). -+ On a Pi this can take more than 60 seconds to execute for a recording of a few hours. -+ -+ By replacing with an O(N) loop, this takes virtually zero time -+ -+diff --git a/lib/ffmpeg/libavformat/wtvdec.c b/lib/ffmpeg/libavformat/wtvdec.c -+index e423370..70898bd 100644 -+--- a/lib/ffmpeg/libavformat/wtvdec.c -++++ b/lib/ffmpeg/libavformat/wtvdec.c -+@@ -980,21 +980,23 @@ static int read_header(AVFormatContext *s) -+ pb = wtvfile_open(s, root, root_size, ff_timeline_table_0_entries_Events_le16); -+ if (pb) { -+ int i; -++ AVIndexEntry *e = wtv->index_entries; -++ AVIndexEntry *e_end = wtv->index_entries + wtv->nb_index_entries - 1; -++ uint64_t last_position = 0; -+ while (1) { -+ uint64_t frame_nb = avio_rl64(pb); -+ uint64_t position = avio_rl64(pb); -++ while (frame_nb > e->size && e <= e_end) { -++ e->pos = last_position; -++ e++; -++ } -+ if (avio_feof(pb)) -+ break; -+- for (i = wtv->nb_index_entries - 1; i >= 0; i--) { -+- AVIndexEntry *e = wtv->index_entries + i; -+- if (frame_nb > e->size) -+- break; -+- if (position > e->pos) -+- e->pos = position; -+- } -++ last_position = position; -+ } -++ e_end->pos = last_position; -+ wtvfile_close(pb); -+- st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp; -++ st->duration = e_end->timestamp; -+ } -+ } -+ } - -From a7d6d41cba0dedb0e3afb819273a995e4706e0aa Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 2 Aug 2014 17:48:04 +0100 -Subject: [PATCH 03/75] [omx] Report decoded image name - ---- - xbmc/cores/omxplayer/OMXImage.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp -index aa413b9..22ec3f0 100644 ---- a/xbmc/cores/omxplayer/OMXImage.cpp -+++ b/xbmc/cores/omxplayer/OMXImage.cpp -@@ -326,6 +326,7 @@ bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, uns - { - ret = true; - *userdata = tex; -+ CLog::Log(LOGDEBUG, "%s: decoded %s %dx%d", __func__, file->GetFilename(), width, height); - } - else - { - -From 339d2a6c448685ec177367b4c20bbf2bacfcbf6a Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 8 Mar 2014 15:36:06 +0000 -Subject: [PATCH 04/75] [hifiberry] Hack: force it to be recognised as IEC958 - capable to enable passthrough options - ---- - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index df50940..2d853d6 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -1333,6 +1333,10 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev - if (snd_card_get_name(cardNr, &cardName) == 0) - info.m_displayName = cardName; - -+ // hack: hifiberry digi doesn't correctly report as iec958 device. Needs fixing in kernel driver -+ if (info.m_displayName == "snd_rpi_hifiberry_digi") -+ info.m_deviceType = AE_DEVTYPE_IEC958; -+ - if (info.m_deviceType == AE_DEVTYPE_HDMI && info.m_displayName.size() > 5 && - info.m_displayName.substr(info.m_displayName.size()-5) == " HDMI") - { - -From 9f045eb959a0cc511c83fb527bcbef0507a64964 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 11 Dec 2013 17:21:54 +0000 -Subject: [PATCH 05/75] 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 | 154 ++++++++++++++++++++----------------------- - xbmc/guilib/GUIFontTTFGL.h | 4 +- - 6 files changed, 135 insertions(+), 133 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index 4e6fb67..b1d7452 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -333,6 +333,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 1714ed7..cd35d0f 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -79,8 +79,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; }; - -@@ -171,6 +171,8 @@ class CGUIFontTTFBase - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - - 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 6a8291b..97853fd 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -53,108 +53,96 @@ CGUIFontTTFGL::~CGUIFontTTFGL(void) - { - } - --void CGUIFontTTFGL::Begin() -+bool CGUIFontTTFGL::FirstBegin() - { -- if (m_nestedBeginCount == 0 && m_texture != NULL) -+ if (m_textureStatus == TEXTURE_REALLOCATED) - { -- if (m_textureStatus == TEXTURE_REALLOCATED) -- { -- if (glIsTexture(m_nTexture)) -- g_TextureManager.ReleaseHwTexture(m_nTexture); -- m_textureStatus = TEXTURE_VOID; -- } -- -- if (m_textureStatus == TEXTURE_VOID) -- { -- // Have OpenGL generate a texture object handle for us -- glGenTextures(1, (GLuint*) &m_nTexture); -+ if (glIsTexture(m_nTexture)) -+ g_TextureManager.ReleaseHwTexture(m_nTexture); -+ m_textureStatus = TEXTURE_VOID; -+ } - -- // Bind the texture object -- glBindTexture(GL_TEXTURE_2D, m_nTexture); -+ if (m_textureStatus == TEXTURE_VOID) -+ { -+ // Have OpenGL generate a texture object handle for us -+ glGenTextures(1, (GLuint*) &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, 0); -- -- VerifyGLState(); -- m_textureStatus = TEXTURE_UPDATED; -- } -+ // 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, 0); - -- if (m_textureStatus == TEXTURE_UPDATED) -- { -- glBindTexture(GL_TEXTURE_2D, m_nTexture); -- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_updateY1, m_texture->GetWidth(), m_updateY2 - m_updateY1, GL_ALPHA, GL_UNSIGNED_BYTE, -- m_texture->GetPixels() + m_updateY1 * m_texture->GetPitch()); -- glDisable(GL_TEXTURE_2D); -- -- m_updateY1 = m_updateY2 = 0; -- m_textureStatus = TEXTURE_READY; -- } -+ VerifyGLState(); -+ m_textureStatus = TEXTURE_UPDATED; -+ } - -- // Turn Blending On -- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); -- glEnable(GL_BLEND); -+ if (m_textureStatus == TEXTURE_UPDATED) -+ { -+ glBindTexture(GL_TEXTURE_2D, m_nTexture); -+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_updateY1, m_texture->GetWidth(), m_updateY2 - m_updateY1, GL_ALPHA, GL_UNSIGNED_BYTE, -+ m_texture->GetPixels() + m_updateY1 * m_texture->GetPitch()); -+ glDisable(GL_TEXTURE_2D); -+ -+ m_updateY1 = m_updateY2 = 0; -+ m_textureStatus = TEXTURE_READY; -+ } -+ -+ // 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 c0bb53a..735fb3a 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); - -From ad4929367028c6111ce1117070fcb99f3cce9aac Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 11 Dec 2013 18:47:54 +0000 -Subject: [PATCH 06/75] 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 b1d7452..686dddf 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -160,8 +160,7 @@ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) - m_maxChars = 0; - m_nestedBeginCount = 0; - -- 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; -@@ -176,7 +175,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; - } - -@@ -237,9 +235,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(); - - m_strFileName.clear(); - m_fontFileInMemory.clear(); -@@ -337,7 +333,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++; -@@ -770,22 +766,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) -@@ -852,8 +835,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 cd35d0f..5675725 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -158,9 +158,7 @@ class CGUIFontTTFBase - - 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 97853fd..b76c6a5 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -146,13 +146,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); -@@ -168,10 +168,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/75] 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 686dddf..e6eb3f2 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -354,6 +354,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; -@@ -434,7 +436,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; -@@ -443,7 +445,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' ') -@@ -700,7 +702,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 -@@ -766,8 +768,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 5675725..a5d44f4 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -111,7 +111,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; - -From d8c252f045dee39e64df00abc4d54a4b5e7b9fcf Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 17:18:38 +0000 -Subject: [PATCH 08/75] 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. ---- - Kodi.xcodeproj/project.pbxproj | 10 ++ - project/VS2010Express/XBMC.vcxproj | 2 + - project/VS2010Express/XBMC.vcxproj.filters | 6 + - 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 ++ - 11 files changed, 456 insertions(+), 84 deletions(-) - create mode 100644 xbmc/guilib/GUIFontCache.cpp - create mode 100644 xbmc/guilib/GUIFontCache.h - -diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj -index a9ecd08..6d42c1c 100644 ---- a/Kodi.xcodeproj/project.pbxproj -+++ b/Kodi.xcodeproj/project.pbxproj -@@ -168,6 +168,9 @@ - 1D638128161E211E003603ED /* PeripheralImon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D638126161E211E003603ED /* PeripheralImon.cpp */; }; - 1DAFDB7C16DFDCA7007F8C68 /* PeripheralBusCEC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DAFDB7A16DFDCA7007F8C68 /* PeripheralBusCEC.cpp */; }; - 1DE0443515828F4B005DDB4D /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE0443315828F4B005DDB4D /* Exception.cpp */; }; -+ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; -+ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; -+ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; - 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; - 36A9443D15821E2800727135 /* DatabaseUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443B15821E2800727135 /* DatabaseUtils.cpp */; }; - 36A9444115821E7C00727135 /* SortUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443F15821E7C00727135 /* SortUtils.cpp */; }; -@@ -4021,6 +4024,8 @@ - 1DAFDB7B16DFDCA7007F8C68 /* PeripheralBusCEC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBusCEC.h; sourceTree = ""; }; - 1DE0443315828F4B005DDB4D /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Exception.cpp; path = commons/Exception.cpp; sourceTree = ""; }; - 1DE0443415828F4B005DDB4D /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Exception.h; path = commons/Exception.h; sourceTree = ""; }; -+ 2F4564D31970129A00396109 /* GUIFontCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIFontCache.cpp; sourceTree = ""; }; -+ 2F4564D41970129A00396109 /* GUIFontCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIFontCache.h; sourceTree = ""; }; - 32C631261423A90F00F18420 /* JpegIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JpegIO.cpp; sourceTree = ""; }; - 32C631271423A90F00F18420 /* JpegIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JpegIO.h; sourceTree = ""; }; - 36A9443B15821E2800727135 /* DatabaseUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseUtils.cpp; sourceTree = ""; }; -@@ -6537,6 +6542,8 @@ - 18B7C7101294222D009E7A26 /* GUIFixedListContainer.h */, - 18B7C76B1294222E009E7A26 /* GUIFont.cpp */, - 18B7C7111294222D009E7A26 /* GUIFont.h */, -+ 2F4564D31970129A00396109 /* GUIFontCache.cpp */, -+ 2F4564D41970129A00396109 /* GUIFontCache.h */, - 18B7C76C1294222E009E7A26 /* GUIFontManager.cpp */, - 18B7C7121294222D009E7A26 /* GUIFontManager.h */, - 18B7C76D1294222E009E7A26 /* GUIFontTTF.cpp */, -@@ -11045,6 +11052,7 @@ - 7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */, - F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */, - F54C51D20F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp in Sources */, -+ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */, - F54C51D50F1E784800D46E3C /* karaokelyricscdg.cpp in Sources */, - F54C51D80F1E785700D46E3C /* karaokelyrics.cpp in Sources */, - F54C51E50F1E787700D46E3C /* karaokelyricstextkar.cpp in Sources */, -@@ -12721,6 +12729,7 @@ - DFF0F45B17528350002DA3A4 /* Control.cpp in Sources */, - DFF0F45C17528350002DA3A4 /* Dialog.cpp in Sources */, - DFF0F45D17528350002DA3A4 /* File.cpp in Sources */, -+ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */, - DFF0F45E17528350002DA3A4 /* InfoTagMusic.cpp in Sources */, - DFF0F45F17528350002DA3A4 /* InfoTagVideo.cpp in Sources */, - DFF0F46017528350002DA3A4 /* Keyboard.cpp in Sources */, -@@ -13517,6 +13526,7 @@ - E499131D174E5DAD00741B6D /* GUIVisualisationControl.cpp in Sources */, - E499131E174E5DAD00741B6D /* GUIWindow.cpp in Sources */, - E499131F174E5DAD00741B6D /* GUIWindowManager.cpp in Sources */, -+ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */, - E4991320174E5DAD00741B6D /* GUIWrappingListContainer.cpp in Sources */, - E4991321174E5DAD00741B6D /* imagefactory.cpp in Sources */, - E4991322174E5DAD00741B6D /* IWindowManagerCallback.cpp in Sources */, -diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj -index 5dd6967..86b983c 100644 ---- a/project/VS2010Express/XBMC.vcxproj -+++ b/project/VS2010Express/XBMC.vcxproj -@@ -427,6 +427,7 @@ - - - -+ - - - -@@ -1754,6 +1755,7 @@ - - - -+ - - - -diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters -index 58d782a..3f937de 100644 ---- a/project/VS2010Express/XBMC.vcxproj.filters -+++ b/project/VS2010Express/XBMC.vcxproj.filters -@@ -994,6 +994,9 @@ - - guilib - -+ -+ guilib -+ - - guilib - -@@ -3900,6 +3903,9 @@ - - guilib - -+ -+ guilib -+ - - guilib - -diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp -new file mode 100644 -index 0000000..2c72f9c ---- /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.template get().find(key); -+ if (i == m_list.template get().end()) -+ { -+ /* Cache miss */ -+ EntryAgeIterator oldest = m_list.template get().begin(); -+ if (!m_list.template get().empty() && nowMillis - oldest->m_lastUsedMillis > FONT_CACHE_TIME_LIMIT) -+ { -+ /* The oldest existing entry is old enough to expire and reuse */ -+ m_list.template get().modify(m_list.template project(oldest), typename CGUIFontCacheEntry::Reassign(key, nowMillis)); -+ m_list.template get().relocate(m_list.template 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.template get().push_back(CGUIFontCacheEntry(*this, key, nowMillis)); -+ } -+ dirtyCache = true; -+ return (--m_list.template 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.template get().relocate(m_list.template get().end(), m_list.template project(i)); -+ dirtyCache = false; -+ return i->m_value; -+ } -+} -+ -+template -+void CGUIFontCache::Flush() -+{ -+ m_list.template 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 e6eb3f2..6a40e9c 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -29,6 +29,7 @@ - #include "windowing/WindowingFactory.h" - #include "URL.h" - #include "filesystem/File.h" -+#include "threads/SystemClock.h" - - #include - -@@ -153,7 +154,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; -@@ -354,108 +355,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 a5d44f4..3b93672 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -66,6 +66,9 @@ struct SVertex - }; - - -+#include "GUIFontCache.h" -+ -+ - class CGUIFontTTFBase - { - friend class CGUIFont; -@@ -168,6 +171,8 @@ class CGUIFontTTFBase - CStdString m_strFileName; - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - -+ 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 b76c6a5..9935ea4 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -221,6 +221,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 c2a4c16..a385eb4 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); -+} - -From 824d5347910e00b9e0c44deffaff4d2b6db6bca3 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 23 Jan 2014 22:24:17 +0000 -Subject: [PATCH 09/75] 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 6a40e9c..a8f5e67 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -734,7 +734,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 23cb84f..5d836cee 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/WindowingFactory.h" -+#include "guilib/GraphicContext.h" - - using namespace Shaders; - -@@ -88,8 +90,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 f7b5d9a..fdf7452 100644 ---- a/xbmc/guilib/GUIShader.h -+++ b/xbmc/guilib/GUIShader.h -@@ -39,6 +39,11 @@ class CGUIShader : public Shaders::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; -@@ -54,6 +59,12 @@ class CGUIShader : public Shaders::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 d40e7a7..3cb5587 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 a385eb4..2904c1b 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(); - - -From b201e727e19af94c6d58528ebcd5960baafee499 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 23 Jan 2014 16:42:22 +0000 -Subject: [PATCH 10/75] 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 2c72f9c..df466a5 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.template get().relocate(m_list.template get().end(), m_list.template 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 a8f5e67..91bf91b 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -154,7 +154,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; -@@ -356,13 +356,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 -@@ -465,10 +480,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 3b93672..258dffa 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -172,6 +172,7 @@ class CGUIFontTTFBase - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - - CGUIFontCache m_staticCache; -+ CGUIFontCache m_dynamicCache; - - private: - virtual bool FirstBegin() = 0; - -From 818067e098f2b2f0fe8c816775646eef96f3b7b9 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 8 Jan 2014 12:16:33 +0000 -Subject: [PATCH 11/75] 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 844f960..5859d9f 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 8d985cf..a8e20fc 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 != "") -@@ -174,7 +176,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 5383156..41f9bc2 100644 ---- a/xbmc/utils/RssReader.cpp -+++ b/xbmc/utils/RssReader.cpp -@@ -55,7 +55,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 2cda726..fbc579e 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(); - -From 92fa695abd21992829758d5978f98f81ea99a3c5 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Mon, 27 Jan 2014 23:21:10 +0000 -Subject: [PATCH 12/75] 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 91bf91b..b1d00e5 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -236,6 +236,7 @@ void CGUIFontTTFBase::Clear() - g_freeTypeLibrary.ReleaseStroker(m_stroker); - m_stroker = NULL; - -+ m_vertexTrans.clear(); - m_vertex.clear(); - - m_strFileName.clear(); -@@ -334,6 +335,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. -@@ -481,23 +483,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 258dffa..40bf430 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -63,6 +63,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; -+ } - }; - - -@@ -161,6 +169,15 @@ class CGUIFontTTFBase - - 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 9935ea4..18c9358 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -167,34 +167,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); -@@ -222,6 +253,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) - -From 81abd97bf3d135acc7be29f201ea53657c7727d2 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 15:28:06 +0000 -Subject: [PATCH 13/75] 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 40bf430..49222a4 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -63,14 +63,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 18c9358..ea08bf4 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 -@@ -166,6 +167,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); -@@ -204,25 +206,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 fdf7452..abbe21c 100644 ---- a/xbmc/guilib/GUIShader.h -+++ b/xbmc/guilib/GUIShader.h -@@ -39,6 +39,7 @@ class CGUIShader : public Shaders::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; - -From 0112e23ceb86275743bb929c50db98928a7c635b Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 29 Jan 2014 13:21:19 +0000 -Subject: [PATCH 14/75] Enable hardware clipping. - ---- - xbmc/guilib/GUIFontTTF.cpp | 4 ++-- - xbmc/guilib/GUIFontTTF.h | 4 +++- - xbmc/guilib/GUIFontTTFGL.cpp | 6 ++++++ - 3 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index b1d00e5..ff51c89 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -483,10 +483,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 49222a4..77b324f 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -28,6 +28,7 @@ - */ - - #include "utils/auto_buffer.h" -+#include "Geometry.h" - - // forward definition - class CBaseTexture; -@@ -167,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 ea08bf4..b63e337 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -206,6 +206,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_Windowing.SetScissors(clip); -+ - // Apply the translation to the currently active (top-of-stack) model view matrix - g_matrices.MatrixMode(MM_MODELVIEW); - g_matrices.PushMatrix(); -@@ -233,6 +237,8 @@ void CGUIFontTTFGL::LastEnd() - - g_matrices.PopMatrix(); - } -+ // Restore the original scissor rectangle -+ g_Windowing.ResetScissors(); - // Restore the original model view matrix - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW)); - } - -From 7a633290e3614e6ff0d073e2653e080d5e2ac8fd Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 15:32:51 +0000 -Subject: [PATCH 15/75] 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 b63e337..b00055d 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -228,12 +228,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(); - } -@@ -241,6 +253,8 @@ void CGUIFontTTFGL::LastEnd() - g_Windowing.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 - -From 243c446cdb97ab29e1a75b70c244ad5b741dce57 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 16:04:04 +0000 -Subject: [PATCH 16/75] 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 df466a5..bd84b9a 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 CGUIFontCacheDynamicValue; -+struct CVertexBuffer -+{ -+ void *bufferHandle; -+ size_t size; -+ CVertexBuffer() : bufferHandle(NULL), size(0), m_font(NULL) {} -+ CVertexBuffer(void *bufferHandle, size_t size, const CGUIFontTTFBase *font) : bufferHandle(bufferHandle), size(size), m_font(font) {} -+ CVertexBuffer(const CVertexBuffer &other) : bufferHandle(other.bufferHandle), size(other.size), m_font(other.m_font) -+ { -+ /* In practice, the copy constructor is only called before a vertex buffer -+ * has been attached. If this should ever change, we'll need another support -+ * function in GUIFontTTFGL/DX to duplicate a buffer, given its handle. */ -+ assert(other.bufferHandle == 0); -+ } -+ CVertexBuffer &operator=(CVertexBuffer &other) -+ { -+ /* This is used with move-assignment semantics for initialising the object in the font cache */ -+ assert(bufferHandle == 0); -+ bufferHandle = other.bufferHandle; -+ other.bufferHandle = 0; -+ size = other.size; -+ m_font = other.m_font; -+ return *this; -+ } -+ void clear(); -+private: -+ const CGUIFontTTFBase *m_font; -+}; -+ -+typedef CVertexBuffer CGUIFontCacheDynamicValue; - - inline bool Match(const CGUIFontCacheDynamicPosition &a, const TransformMatrix &a_m, - const CGUIFontCacheDynamicPosition &b, const TransformMatrix &b_m, -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index ff51c89..7d4fc88 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -367,13 +367,18 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - g_graphicsContext.ScaleFinalYCoord(x, y), - g_graphicsContext.ScaleFinalZCoord(x, y)); - } -- std::vector &vertices = hardwareClipping ? -+ CVertexBuffer unusedVertexBuffer; -+ CVertexBuffer &vertexBuffer = hardwareClipping ? - m_dynamicCache.Lookup(dynamicPos, - colors, text, - alignment, maxPixelWidth, - scrolling, - XbmcThreads::SystemClockMillis(), - dirtyCache) : -+ unusedVertexBuffer; -+ std::vector tempVertices; -+ std::vector &vertices = hardwareClipping ? -+ tempVertices : - m_staticCache.Lookup(staticPos, - colors, text, - alignment, maxPixelWidth, -@@ -483,10 +488,14 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - cursorX += ch->advance; - } - if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertices, g_graphicsContext.GetClipRegion())); -+ { -+ CVertexBuffer newVertexBuffer = CreateVertexBuffer(tempVertices); -+ vertexBuffer = newVertexBuffer; -+ m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertexBuffer, g_graphicsContext.GetClipRegion())); -+ } - } - else if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertices, g_graphicsContext.GetClipRegion())); -+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, 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 77b324f..caa1e62 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -85,6 +85,9 @@ class CGUIFontTTFBase - - void Begin(); - void End(); -+ /* The next two should only be called if we've declared we can do hardware clipping */ -+ virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const { assert(false); return CVertexBuffer(); } -+ virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const {} - - const CStdString& GetFileName() const { return m_strFileName; }; - -@@ -167,9 +170,9 @@ class CGUIFontTTFBase - float translateX; - float translateY; - float translateZ; -- const std::vector *vertexBuffer; -+ const CVertexBuffer *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) {} -+ CTranslatedVertices(float translateX, float translateY, float translateZ, const CVertexBuffer *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 b00055d..aabb9a6 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -52,6 +52,10 @@ CGUIFontTTFGL::CGUIFontTTFGL(const CStdString& strFileName) - - CGUIFontTTFGL::~CGUIFontTTFGL(void) - { -+ // It's important that all the CGUIFontCacheEntry objects are -+ // destructed before the CGUIFontTTFGL goes out of scope, because -+ // our virtual methods won't be accessible after this point -+ m_dynamicCache.Flush(); - } - - bool CGUIFontTTFGL::FirstBegin() -@@ -203,7 +207,6 @@ void CGUIFontTTFGL::LastEnd() - if (m_vertexTrans.size() > 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++) - { - // Apply the clip rectangle -@@ -216,36 +219,17 @@ void CGUIFontTTFGL::LastEnd() - 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]); -- 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]; -- -- // 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); -+ glBindBuffer(GL_ARRAY_BUFFER, (GLuint) m_vertexTrans[i].vertexBuffer->bufferHandle); -+ - // 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); -+ glDrawArrays(GL_TRIANGLES, 0, 6 * m_vertexTrans[i].vertexBuffer->size); - - g_matrices.PopMatrix(); - } -@@ -266,6 +250,48 @@ void CGUIFontTTFGL::LastEnd() - #endif - } - -+#if HAS_GLES -+CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vertices) const -+{ -+ // Rearrange the vertices to describe triangles -+ std::vector triangleVertices; -+ triangleVertices.reserve(vertices.size() * 6 / 4); -+ for (size_t i = 0; i < vertices.size(); i += 4) -+ { -+ triangleVertices.push_back(vertices[i]); -+ triangleVertices.push_back(vertices[i+1]); -+ triangleVertices.push_back(vertices[i+2]); -+ triangleVertices.push_back(vertices[i+1]); -+ triangleVertices.push_back(vertices[i+3]); -+ triangleVertices.push_back(vertices[i+2]); -+ } -+ -+ // Generate a unique buffer object name and put it in bufferHandle -+ GLuint bufferHandle; -+ glGenBuffers(1, &bufferHandle); -+ // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point -+ glBindBuffer(GL_ARRAY_BUFFER, bufferHandle); -+ // 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, triangleVertices.size() * sizeof (SVertex), &triangleVertices[0], GL_STATIC_DRAW); -+ // Unbind GL_ARRAY_BUFFER -+ glBindBuffer(GL_ARRAY_BUFFER, 0); -+ -+ return CVertexBuffer((void *) bufferHandle, vertices.size() / 4, this); -+} -+ -+void CGUIFontTTFGL::DestroyVertexBuffer(CVertexBuffer &buffer) const -+{ -+ if (buffer.bufferHandle != 0) -+ { -+ // Release the buffer name for reuse -+ glDeleteBuffers(1, (GLuint *) &buffer.bufferHandle); -+ buffer.bufferHandle = 0; -+ } -+} -+#endif -+ - CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight) - { - newHeight = CBaseTexture::PadPow2(newHeight); -diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h -index 735fb3a..6102c90 100644 ---- a/xbmc/guilib/GUIFontTTFGL.h -+++ b/xbmc/guilib/GUIFontTTFGL.h -@@ -29,6 +29,7 @@ - - - #include "GUIFontTTF.h" -+#include "system.h" - - - /*! -@@ -43,6 +44,10 @@ class CGUIFontTTFGL : public CGUIFontTTFBase - - virtual bool FirstBegin(); - virtual void LastEnd(); -+#if HAS_GLES -+ virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const; -+ virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const; -+#endif - - protected: - virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); - -From 2c1526c28ea480fdf884904a4e21db9ad514855b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 1 Nov 2014 22:15:13 +0000 -Subject: [PATCH 17/75] Switch from glDrawArrays() to glDrawElements(). - -This involves setting up a static VBO containing the indexes necessary to -convert from quads to triangles on the fly in the GPU. ---- - xbmc/guilib/GUIFontTTFGL.cpp | 72 +++++++++++++++++++++++++------------ - xbmc/guilib/GUIFontTTFGL.h | 11 +++++- - xbmc/windowing/egl/WinSystemEGL.cpp | 17 +++++++++ - 3 files changed, 77 insertions(+), 23 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp -index aabb9a6..812662c 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -207,6 +207,10 @@ void CGUIFontTTFGL::LastEnd() - if (m_vertexTrans.size() > 0) - { - // Deal with the vertices that can be hardware clipped and therefore translated -+ -+ // Bind our pre-calculated array to GL_ELEMENT_ARRAY_BUFFER -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementArrayHandle); -+ - for (size_t i = 0; i < m_vertexTrans.size(); i++) - { - // Apply the clip rectangle -@@ -222,14 +226,21 @@ void CGUIFontTTFGL::LastEnd() - // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point - glBindBuffer(GL_ARRAY_BUFFER, (GLuint) m_vertexTrans[i].vertexBuffer->bufferHandle); - -- // 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, split into groups of characters no -+ // larger than the pre-determined size of the element array -+ for (size_t character = 0; m_vertexTrans[i].vertexBuffer->size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) -+ { -+ size_t count = m_vertexTrans[i].vertexBuffer->size - character; -+ count = std::min(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); -+ -+ // 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 *) (character*sizeof(SVertex)*4 + offsetof(SVertex, x))); -+ glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, r))); -+ glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, u))); - -- // Do the actual drawing operation, using the full set of vertices in the buffer -- glDrawArrays(GL_TRIANGLES, 0, 6 * m_vertexTrans[i].vertexBuffer->size); -+ glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0); -+ } - - g_matrices.PopMatrix(); - } -@@ -237,8 +248,9 @@ void CGUIFontTTFGL::LastEnd() - g_Windowing.ResetScissors(); - // Restore the original model view matrix - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW)); -- // Unbind GL_ARRAY_BUFFER -+ // Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER - glBindBuffer(GL_ARRAY_BUFFER, 0); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - // Disable the attributes used by this shader -@@ -253,19 +265,6 @@ void CGUIFontTTFGL::LastEnd() - #if HAS_GLES - CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vertices) const - { -- // Rearrange the vertices to describe triangles -- std::vector triangleVertices; -- triangleVertices.reserve(vertices.size() * 6 / 4); -- for (size_t i = 0; i < vertices.size(); i += 4) -- { -- triangleVertices.push_back(vertices[i]); -- triangleVertices.push_back(vertices[i+1]); -- triangleVertices.push_back(vertices[i+2]); -- triangleVertices.push_back(vertices[i+1]); -- triangleVertices.push_back(vertices[i+3]); -- triangleVertices.push_back(vertices[i+2]); -- } -- - // Generate a unique buffer object name and put it in bufferHandle - GLuint bufferHandle; - glGenBuffers(1, &bufferHandle); -@@ -274,7 +273,7 @@ CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vert - // 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, triangleVertices.size() * sizeof (SVertex), &triangleVertices[0], GL_STATIC_DRAW); -+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof (SVertex), &vertices[0], GL_STATIC_DRAW); - // Unbind GL_ARRAY_BUFFER - glBindBuffer(GL_ARRAY_BUFFER, 0); - -@@ -393,4 +392,33 @@ void CGUIFontTTFGL::DeleteHardwareTexture() - } - } - -+#if HAS_GLES -+void CGUIFontTTFGL::CreateStaticVertexBuffers(void) -+{ -+ // Bind a new buffer to the OpenGL context's GL_ELEMENT_ARRAY_BUFFER binding point -+ glGenBuffers(1, &m_elementArrayHandle); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementArrayHandle); -+ // Create an array holding the mesh indices to convert quads to triangles -+ GLushort index[ELEMENT_ARRAY_MAX_CHAR_INDEX][6]; -+ for (size_t i = 0; i < ELEMENT_ARRAY_MAX_CHAR_INDEX; i++) -+ { -+ index[i][0] = 4*i; -+ index[i][1] = 4*i+1; -+ index[i][2] = 4*i+2; -+ index[i][3] = 4*i+1; -+ index[i][4] = 4*i+3; -+ index[i][5] = 4*i+2; -+ } -+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof index, index, GL_STATIC_DRAW); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -+} -+ -+void CGUIFontTTFGL::DestroyStaticVertexBuffers(void) -+{ -+ glDeleteBuffers(1, &m_elementArrayHandle); -+} -+ -+GLuint CGUIFontTTFGL::m_elementArrayHandle; -+#endif -+ - #endif -diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h -index 6102c90..dcf9ca1 100644 ---- a/xbmc/guilib/GUIFontTTFGL.h -+++ b/xbmc/guilib/GUIFontTTFGL.h -@@ -30,6 +30,7 @@ - - #include "GUIFontTTF.h" - #include "system.h" -+#include "system_gl.h" - - - /*! -@@ -47,13 +48,21 @@ class CGUIFontTTFGL : public CGUIFontTTFBase - #if HAS_GLES - virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const; - virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const; -+ static void CreateStaticVertexBuffers(void); -+ static void DestroyStaticVertexBuffers(void); - #endif - - protected: - virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); - virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); - virtual void DeleteHardwareTexture(); -- -+ -+#if HAS_GLES -+#define ELEMENT_ARRAY_MAX_CHAR_INDEX (1000) -+ -+ static GLuint m_elementArrayHandle; -+#endif -+ - private: - unsigned int m_updateY1; - unsigned int m_updateY2; -diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp -index 2bdd4fa..68f0117 100644 ---- a/xbmc/windowing/egl/WinSystemEGL.cpp -+++ b/xbmc/windowing/egl/WinSystemEGL.cpp -@@ -29,6 +29,7 @@ - #include "settings/AdvancedSettings.h" - #include "settings/Settings.h" - #include "settings/DisplaySettings.h" -+#include "guilib/GUIFontTTFGL.h" - #include "guilib/DispResource.h" - #include "threads/SingleLock.h" - #include "utils/log.h" -@@ -207,6 +208,9 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - return false; - } - -+#if HAS_GLES -+ bool newContext = false; -+#endif - if (m_context == EGL_NO_CONTEXT) - { - if (!m_egl->CreateContext(m_display, m_config, contextAttrs, &m_context)) -@@ -214,6 +218,9 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - CLog::Log(LOGERROR, "%s: Could not create context",__FUNCTION__); - return false; - } -+#if HAS_GLES -+ newContext = true; -+#endif - } - - if (!m_egl->BindContext(m_display, m_surface, m_context)) -@@ -222,6 +229,11 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - return false; - } - -+#if HAS_GLES -+ if (newContext) -+ CGUIFontTTFGL::CreateStaticVertexBuffers(); -+#endif -+ - // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates - if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION || - g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION) -@@ -243,7 +255,12 @@ bool CWinSystemEGL::DestroyWindowSystem() - DestroyWindow(); - - if (m_context != EGL_NO_CONTEXT) -+ { -+#if HAS_GLES -+ CGUIFontTTFGL::DestroyStaticVertexBuffers(); -+#endif - m_egl->DestroyContext(m_display, m_context); -+ } - m_context = EGL_NO_CONTEXT; - - if (m_display != EGL_NO_DISPLAY) - -From 0581bdecd8c045559dcf682ea7e4bbd5a7849653 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 1 May 2014 16:28:39 +0100 -Subject: [PATCH 18/75] Improved file buffering in CArchive - -Even though memcpy is typically inlined by the compiler into byte/word loads -and stores (at least for release builds), the frequency with which 1, 2 and 4 -byte loads/stores are encountered in cases where the size is *not* -determinable at compile time is still high enough that it's worth handling -these specially. On the ARM1176JZF-S in the Raspberry Pi, this improves the -total time to open a library (in the case where it's fetched from a CArchive) -by around 4%. - -It should be noted that this code uses 16-bit and 32-bit word loads and -stores that are not necessarily aligned to their respective widths. It is -possible that there are some architectures out there which do not support -this, although all ARMs since ARMv6 have supported it (and ARMs earlier than -that are probably not powerful enough to be good targets for XBMC). ---- - xbmc/utils/Archive.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/xbmc/utils/Archive.h b/xbmc/utils/Archive.h -index 6ed0f8f..8506d95 100644 ---- a/xbmc/utils/Archive.h -+++ b/xbmc/utils/Archive.h -@@ -154,9 +154,17 @@ class CArchive - * than waiting until we attempt to put more data into an already full buffer */ - if (m_BufferRemain > size) - { -+ switch (size) -+ { -+ case 1: *m_BufferPos++ = *ptr; m_BufferRemain--; break; -+ case 2: *(uint16_t *) m_BufferPos = *(const uint16_t *) ptr; m_BufferPos += 2; m_BufferRemain -= 2; break; -+ case 4: *(uint32_t *) m_BufferPos = *(const uint32_t *) ptr; m_BufferPos += 4; m_BufferRemain -= 4; break; -+ default: - memcpy(m_BufferPos, ptr, size); - m_BufferPos += size; - m_BufferRemain -= size; -+ break; -+ } - return *this; - } - else -@@ -171,9 +179,17 @@ class CArchive - /* Note, refilling the buffer is deferred until we know we need to read more from it */ - if (m_BufferRemain >= size) - { -+ switch (size) -+ { -+ case 1: *ptr = *m_BufferPos++; m_BufferRemain--; break; -+ case 2: *(uint16_t *) ptr = *(const uint16_t *) m_BufferPos; m_BufferPos += 2; m_BufferRemain -= 2; break; -+ case 4: *(uint32_t *) ptr = *(const uint32_t *) m_BufferPos; m_BufferPos += 4; m_BufferRemain -= 4; break; -+ default: - memcpy(ptr, m_BufferPos, size); - m_BufferPos += size; - m_BufferRemain -= size; -+ break; -+ } - return *this; - } - else - -From 0dc98aba1e8c9bf8d63bcd12bbc18a5a6021231f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 10 Sep 2014 22:07:21 +0100 -Subject: [PATCH 19/75] [mmal] Allow mmal codec for dvd stills - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index 10648c5..bea5e4f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -194,6 +194,10 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - #endif - CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); - -+#if defined(HAS_MMAL) -+ // mmal can handle dvd playback including stills -+ if (!CSettings::Get().GetBool("videoplayer.usemmal")) -+#endif - if (hint.stills && (hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_MPEG1VIDEO)) - { - // If dvd is an mpeg2 and hint.stills - -From d46182be867dae3e4405be4558275250f87ea3c5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 12 Aug 2014 00:31:36 +0100 -Subject: [PATCH 20/75] [omxcodec] Don't force software codec with dvds - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index aae59dc..12a3ed6 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -3225,7 +3225,9 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) - hint.aspect = aspect; - hint.forced_aspect = true; - } -+#ifndef TARGET_RASPBERRY_PI - hint.software = true; -+#endif - } - - CDVDInputStream::IMenus* pMenus = dynamic_cast(m_pInputStream); - -From 7026b367733a3529f98c3ccb56b16adb6324d320 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 16 Apr 2014 21:18:06 +0100 -Subject: [PATCH 21/75] [omxplayer] Don't propagate 3d flags based on supported - 3d modes - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 29 ++++------------------------- - 1 file changed, 4 insertions(+), 25 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index ac838ce..605318c9 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -759,36 +759,15 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height, f - unsigned flags = 0; - ERenderFormat format = RENDER_FMT_BYPASS; - -+ /* figure out steremode expected based on user settings and hints */ -+ unsigned int stereo_flags = GetStereoModeFlags(GetStereoMode()); -+ - if(m_bAllowFullscreen) - { - flags |= CONF_FLAGS_FULLSCREEN; - m_bAllowFullscreen = false; // only allow on first configure - } -- -- flags |= GetStereoModeFlags(GetStereoMode()); -- -- if(flags & CONF_FLAGS_STEREO_MODE_SBS) -- { -- if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DSBS)) -- CLog::Log(LOGNOTICE, "3DSBS movie found"); -- else -- { -- flags &= ~CONF_FLAGS_STEREO_MODE_MASK(~0); -- CLog::Log(LOGNOTICE, "3DSBS movie found but not supported"); -- } -- } -- else if(flags & CONF_FLAGS_STEREO_MODE_TAB) -- { -- if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DTB)) -- CLog::Log(LOGNOTICE, "3DTB movie found"); -- else -- { -- flags &= ~CONF_FLAGS_STEREO_MODE_MASK(~0); -- CLog::Log(LOGNOTICE, "3DTB movie found but not supported"); -- } -- } -- else -- CLog::Log(LOGNOTICE, "not a 3D movie"); -+ flags |= stereo_flags; - - unsigned int iDisplayWidth = width; - unsigned int iDisplayHeight = height; - -From 9b5da40db6647d40a2c17ab957a3058622472898 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:00:52 +0100 -Subject: [PATCH 22/75] [graphics] Don't set stereo mode based on resolution - -The resolution change should follow stereo mode ---- - xbmc/guilib/GraphicContext.cpp | 35 +++++++++++++++++++---------------- - 1 file changed, 19 insertions(+), 16 deletions(-) - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index 3cb5587..fe6ebf4 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -436,26 +436,29 @@ void CGraphicContext::SetVideoResolutionInternal(RESOLUTION res, bool forceUpdat - RESOLUTION_INFO info_org = CDisplaySettings::Get().GetResolutionInfo(res); - RESOLUTION_INFO info_last = CDisplaySettings::Get().GetResolutionInfo(lastRes); - -- RENDER_STEREO_MODE stereo_mode = m_stereoMode; -- - // if the new mode is an actual stereo mode, switch to that - // if the old mode was an actual stereo mode, switch to no 3d mode -- if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DTB) -- stereo_mode = RENDER_STEREO_MODE_SPLIT_HORIZONTAL; -- else if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -- stereo_mode = RENDER_STEREO_MODE_SPLIT_VERTICAL; -- else if ((info_last.dwFlags & D3DPRESENTFLAG_MODE3DSBS) != 0 -- || (info_last.dwFlags & D3DPRESENTFLAG_MODE3DTB) != 0) -- stereo_mode = RENDER_STEREO_MODE_OFF; -- -- if(stereo_mode != m_stereoMode) -+ // only do this if 3D flags have changed -+ if ((info_org.dwFlags ^ info_last.dwFlags) & (D3DPRESENTFLAG_MODE3DTB | D3DPRESENTFLAG_MODE3DSBS)) - { -- m_stereoView = RENDER_STEREO_VIEW_OFF; -- m_stereoMode = stereo_mode; -- m_nextStereoMode = stereo_mode; -- CSettings::Get().SetInt("videoscreen.stereoscopicmode", (int)m_stereoMode); -- } -+ RENDER_STEREO_MODE stereo_mode = m_stereoMode; -+ -+ if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DTB) -+ stereo_mode = RENDER_STEREO_MODE_SPLIT_HORIZONTAL; -+ else if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -+ stereo_mode = RENDER_STEREO_MODE_SPLIT_VERTICAL; -+ else if ((info_last.dwFlags & D3DPRESENTFLAG_MODE3DSBS) != 0 -+ || (info_last.dwFlags & D3DPRESENTFLAG_MODE3DTB) != 0) -+ stereo_mode = RENDER_STEREO_MODE_OFF; - -+ if(stereo_mode != m_stereoMode) -+ { -+ m_stereoView = RENDER_STEREO_VIEW_OFF; -+ m_stereoMode = stereo_mode; -+ m_nextStereoMode = stereo_mode; -+ CSettings::Get().SetInt("videoscreen.stereoscopicmode", (int)m_stereoMode); -+ } -+ } - RESOLUTION_INFO info_mod = GetResInfo(res); - - m_iScreenWidth = info_mod.iWidth; - -From 47fab3f66ff687e42456d0ae5f94dd5df359285e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:01:51 +0100 -Subject: [PATCH 23/75] [graphics] Allow switching to a more suitable 3D - resolution - ---- - xbmc/guilib/GraphicContext.cpp | 40 +++++++++++++++++++++++++++++++++++++++- - xbmc/guilib/GraphicContext.h | 1 + - 2 files changed, 40 insertions(+), 1 deletion(-) - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index fe6ebf4..04d0756 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -35,6 +35,7 @@ - #include "utils/JobManager.h" - #include "video/VideoReferenceClock.h" - #include "cores/IPlayer.h" -+#include - - using namespace std; - -@@ -500,6 +501,43 @@ RESOLUTION CGraphicContext::GetVideoResolution() const - return m_Resolution; - } - -+RESOLUTION CGraphicContext::Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const -+{ -+ RESOLUTION best = resolution; -+ RESOLUTION_INFO curr = CDisplaySettings::Get().GetResolutionInfo(best); -+ // Find closest refresh rate -+ for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) -+ { -+ const RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo((RESOLUTION)i); -+ -+ //discard resolutions that are not the same width and height (and interlaced/3D flags) -+ //or have a too low refreshrate -+ if (info.iScreenWidth != curr.iScreenWidth -+ || info.iScreenHeight != curr.iScreenHeight -+ || info.iScreen != curr.iScreen -+ || (info.dwFlags & D3DPRESENTFLAG_INTERLACED) != (curr.dwFlags & D3DPRESENTFLAG_INTERLACED) -+ || fabs(info.fRefreshRate - curr.fRefreshRate) >= FLT_EPSILON) -+ continue; -+ -+ if (mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ else if (mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && info.dwFlags & D3DPRESENTFLAG_MODE3DTB) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ else if ((mode == RENDER_STEREO_MODE_OFF || mode == RENDER_STEREO_MODE_MONO) && !(info.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB))) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ } -+ return best; -+} -+ - void CGraphicContext::ResetOverscan(RESOLUTION_INFO &res) - { - res.Overscan.left = 0; -@@ -1037,7 +1075,7 @@ void CGraphicContext::Flip(const CDirtyRegionList& dirty) - if(m_stereoMode != m_nextStereoMode) - { - m_stereoMode = m_nextStereoMode; -- SetVideoResolution(GetVideoResolution(), true); -+ SetVideoResolution(Get3DVideoResolution(m_Resolution, m_stereoMode), true); - g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_RENDERER_RESET); - } - } -diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h -index 2904c1b..8d3774f 100644 ---- a/xbmc/guilib/GraphicContext.h -+++ b/xbmc/guilib/GraphicContext.h -@@ -108,6 +108,7 @@ class CGraphicContext : public CCriticalSection, - bool IsValidResolution(RESOLUTION res); - void SetVideoResolution(RESOLUTION res, bool forceUpdate = false); - RESOLUTION GetVideoResolution() const; -+ RESOLUTION Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const; - void ResetOverscan(RESOLUTION res, OVERSCAN &overscan); - void ResetOverscan(RESOLUTION_INFO &resinfo); - void ResetScreenParameters(RESOLUTION res); - -From d5838e37d76f6a0e7054d7e9cbb7beab41b2f63b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:38:55 +0100 -Subject: [PATCH 24/75] [3D] Support switching to 3D resolutions - -Include matching 3D flags (SBS/TAB) in the score of a resolution to switch to, to enable switching to 3d modes. -Also remove the old code that treated 3D modes differently when assigning a score. ---- - xbmc/cores/VideoRenderers/BaseRenderer.cpp | 47 +++++++++++------------------- - 1 file changed, 17 insertions(+), 30 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -index 83c3adb..8076e76 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -@@ -222,10 +222,14 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight) - { - RESOLUTION_INFO curr = g_graphicsContext.GetResInfo(current); -+ RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode(); - - float fRefreshRate = fps; - -- float last_diff = fRefreshRate; -+ int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -+ if (!(stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) != !(curr.dwFlags & D3DPRESENTFLAG_MODE3DSBS) || -+ !(stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) != !(curr.dwFlags & D3DPRESENTFLAG_MODE3DTB)) -+ c_weight += 1000; - - // Find closest refresh rate - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) -@@ -241,40 +245,23 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES - || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; - -- // For 3D choose the closest refresh rate -- if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) -- { -- float diff = (info.fRefreshRate - fRefreshRate); -- if(diff < 0) -- diff *= -1.0f; -+ int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); - -- if(diff < last_diff) -- { -- last_diff = diff; -- current = (RESOLUTION)i; -- curr = info; -- } -- } -- else -- { -- int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -- int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -+ if (!(stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) != !(info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) || -+ !(stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) != !(info.dwFlags & D3DPRESENTFLAG_MODE3DTB)) -+ i_weight += 1000; - -- // Closer the better, prefer higher refresh rate if the same -- if ((i_weight < c_weight) -- || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) -- { -- current = (RESOLUTION)i; -- curr = info; -- } -+ // Closer the better, prefer higher refresh rate if the same -+ if ((i_weight < c_weight) -+ || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) -+ { -+ current = (RESOLUTION)i; -+ curr = info; -+ c_weight = i_weight; - } - } - -- // For 3D overwrite weight -- if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) -- weight = 0; -- else -- weight = RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier); -+ weight = RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier); - - return current; - } - -From e397abe59fbddcaf141d261855278cb6048e136f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 23 Apr 2014 00:05:07 +0100 -Subject: [PATCH 25/75] [graphics] Make pixel ratio for 3d modes consistent - -Note: Use the stored stereo flags from lists of resolutions. -Use current stereo mode for current resolution. ---- - xbmc/cores/VideoRenderers/BaseRenderer.cpp | 10 +++---- - xbmc/guilib/GraphicContext.cpp | 37 ++++++++++++------------- - xbmc/guilib/GraphicContext.h | 12 ++++++-- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 8 ------ - 4 files changed, 32 insertions(+), 35 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -index 8076e76..9118cb0 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -@@ -119,7 +119,7 @@ bool CBaseRenderer::FindResolutionFromOverride(float fps, float& weight, bool fa - - for (size_t j = (int)RES_DESKTOP; j < CDisplaySettings::Get().ResolutionInfoSize(); j++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)j); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)j, g_graphicsContext.GetStereoMode((RESOLUTION)j)); - - if (info.iScreenWidth == curr.iScreenWidth - && info.iScreenHeight == curr.iScreenHeight -@@ -179,7 +179,7 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - //get the resolution with the refreshrate closest to 60 hertz - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - if (MathUtils::round_int(info.fRefreshRate) == 60 - && info.iScreenWidth == curr.iScreenWidth -@@ -200,7 +200,7 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - CLog::Log(LOGDEBUG, "60 hertz refreshrate not available, choosing highest"); - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - if (info.fRefreshRate > curr.fRefreshRate - && info.iScreenWidth == curr.iScreenWidth -@@ -234,14 +234,14 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES - // Find closest refresh rate - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - //discard resolutions that are not the same width and height (and interlaced/3D flags) - //or have a too low refreshrate - if (info.iScreenWidth != curr.iScreenWidth - || info.iScreenHeight != curr.iScreenHeight - || info.iScreen != curr.iScreen -- || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) -+ || (info.dwFlags & D3DPRESENTFLAG_INTERLACED) != (curr.dwFlags & D3DPRESENTFLAG_INTERLACED) - || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index 04d0756..93bd207 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -747,32 +747,33 @@ void CGraphicContext::ApplyStateBlock() - g_Windowing.ApplyStateBlock(); - } - --const RESOLUTION_INFO CGraphicContext::GetResInfo(RESOLUTION res) const -+RENDER_STEREO_MODE CGraphicContext::GetStereoMode(RESOLUTION res) const - { - RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res); -+ return (info.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? RENDER_STEREO_MODE_SPLIT_HORIZONTAL : -+ (info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? RENDER_STEREO_MODE_SPLIT_VERTICAL : RENDER_STEREO_MODE_OFF; -+} - -- if(m_stereoMode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) -+const RESOLUTION_INFO CGraphicContext::GetResInfo(RESOLUTION res, RENDER_STEREO_MODE stereoMode) const -+{ -+ RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res); -+ -+ if(stereoMode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) - { -- if((info.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0) -- { -- info.fPixelRatio /= 2; -- info.iBlanking = 0; -- info.dwFlags |= D3DPRESENTFLAG_MODE3DTB; -- } -+ info.fPixelRatio /= 2; -+ info.iBlanking = 0; -+ info.dwFlags |= D3DPRESENTFLAG_MODE3DTB; - info.iHeight = (info.iHeight - info.iBlanking) / 2; - info.Overscan.top /= 2; - info.Overscan.bottom = (info.Overscan.bottom - info.iBlanking) / 2; - info.iSubtitles = (info.iSubtitles - info.iBlanking) / 2; - } - -- if(m_stereoMode == RENDER_STEREO_MODE_SPLIT_VERTICAL) -+ if(stereoMode == RENDER_STEREO_MODE_SPLIT_VERTICAL) - { -- if((info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) == 0) -- { -- info.fPixelRatio *= 2; -- info.iBlanking = 0; -- info.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -- } -+ info.fPixelRatio *= 2; -+ info.iBlanking = 0; -+ info.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - info.iWidth = (info.iWidth - info.iBlanking) / 2; - info.Overscan.left /= 2; - info.Overscan.right = (info.Overscan.right - info.iBlanking) / 2; -@@ -790,16 +791,14 @@ void CGraphicContext::SetResInfo(RESOLUTION res, const RESOLUTION_INFO& info) - if(info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) - { - curr.Overscan.right = info.Overscan.right * 2 + info.iBlanking; -- if((curr.dwFlags & D3DPRESENTFLAG_MODE3DSBS) == 0) -- curr.fPixelRatio /= 2.0; -+ curr.fPixelRatio /= 2.0; - } - - if(info.dwFlags & D3DPRESENTFLAG_MODE3DTB) - { - curr.Overscan.bottom = info.Overscan.bottom * 2 + info.iBlanking; - curr.iSubtitles = info.iSubtitles * 2 + info.iBlanking; -- if((curr.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0) -- curr.fPixelRatio *= 2.0; -+ curr.fPixelRatio *= 2.0; - } - } - -diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h -index 8d3774f..f2e122d 100644 ---- a/xbmc/guilib/GraphicContext.h -+++ b/xbmc/guilib/GraphicContext.h -@@ -120,11 +120,15 @@ class CGraphicContext : public CCriticalSection, - void GetAllowedResolutions(std::vector &res); - - // output scaling -+ const RESOLUTION_INFO GetResInfo(RESOLUTION res) const -+ { -+ return GetResInfo(res, GetStereoMode()); -+ } - const RESOLUTION_INFO GetResInfo() const - { - return GetResInfo(m_Resolution); - } -- const RESOLUTION_INFO GetResInfo(RESOLUTION res) const; -+ const RESOLUTION_INFO GetResInfo(RESOLUTION res, RENDER_STEREO_MODE stereo_mode) const; - void SetResInfo(RESOLUTION res, const RESOLUTION_INFO& info); - - /* \brief Get UI scaling information from a given resolution to the screen resolution. -@@ -161,9 +165,11 @@ class CGraphicContext : public CCriticalSection, - void RestoreOrigin(); - void SetCameraPosition(const CPoint &camera); - void SetStereoView(RENDER_STEREO_VIEW view); -- RENDER_STEREO_VIEW GetStereoView() { return m_stereoView; } -+ RENDER_STEREO_VIEW GetStereoView() const { return m_stereoView; } - void SetStereoMode(RENDER_STEREO_MODE mode) { m_nextStereoMode = mode; } -- RENDER_STEREO_MODE GetStereoMode() { return m_stereoMode; } -+ RENDER_STEREO_MODE GetStereoMode() const { return m_stereoMode; } -+ RENDER_STEREO_MODE GetStereoMode(RESOLUTION res) const; -+ - void RestoreCameraPosition(); - /*! \brief Set a region in which to clip all rendering - Anything that is rendered after setting a clip region will be clipped so that no part renders -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index c58c28a..bf1e589 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -449,15 +449,9 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - // Also add 3D flags - if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) -- { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -- m_desktopRes.fPixelRatio *= 2.0; -- } - else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF) -- { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DTB; -- m_desktopRes.fPixelRatio *= 0.5; -- } - HDMI_PROPERTY_PARAM_T property; - property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; - vc_tv_hdmi_get_property(&property); -@@ -600,7 +594,6 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v - RESOLUTION_INFO res2 = res; - res2.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - res2.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight); -- res2.fPixelRatio *= 2.0f; - res2.iSubtitles = (int)(0.965 * res2.iHeight); - - AddUniqueResolution(res2, resolutions); -@@ -616,7 +609,6 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v - RESOLUTION_INFO res2 = res; - res2.dwFlags |= D3DPRESENTFLAG_MODE3DTB; - res2.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight); -- res2.fPixelRatio *= 0.5f; - res2.iSubtitles = (int)(0.965 * res2.iHeight); - - AddUniqueResolution(res2, resolutions); - -From 00d11452657c179a50e9754838753b4dd1e3742e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 10 Aug 2014 16:45:16 +0100 -Subject: [PATCH 26/75] filesystem: Make support of browsing into archives - optional - -The ability to browse, scan and play content in archives can cause problems on low powered/low memory devices. -It's quite common to see reports of a large rar file that causes xbmc to crash with an out-of-memory error when browsing or scanning. -It also can be slow as any archive in the directory is opened and extracted. - -Add a settings option to enable this feature and default to disabled on Pi ---- - language/English/strings.po | 9 +++++++++ - system/settings/rbp.xml | 10 ++++++++++ - system/settings/settings.xml | 5 +++++ - xbmc/filesystem/FileDirectoryFactory.cpp | 4 ++++ - 4 files changed, 28 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 15090fc..8e67be0 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16115,4 +16115,13 @@ msgstr "" - #: system/settings/rbp.xml - msgctxt "#38010" - msgid "GPU accelerated" -+ -+#: system/settings/settings.xml -+msgctxt "#38020" -+msgid "Support browsing into archives" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38021" -+msgid "Allow viewing and playing files in archives (e.g. zip, rar)" - msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index f572eed..f3c8a01 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -1,5 +1,15 @@ - - -+
-+ -+ -+ -+ false -+ -+ -+ -+
-+ -
- - -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 367542d..0db66a2 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -226,6 +226,11 @@ - false - - -+ -+ 1 -+ true -+ -+ - - - -diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp -index 2fd8777..3b294cd 100644 ---- a/xbmc/filesystem/FileDirectoryFactory.cpp -+++ b/xbmc/filesystem/FileDirectoryFactory.cpp -@@ -46,6 +46,7 @@ - #include "Directory.h" - #include "File.h" - #include "ZipManager.h" -+#include "settings/Settings.h" - #include "settings/AdvancedSettings.h" - #include "FileItem.h" - #include "utils/StringUtils.h" -@@ -142,6 +143,8 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem, - return NULL; - } - #endif -+ if (CSettings::Get().GetBool("filelists.browsearchives")) -+ { - if (url.IsFileType("zip")) - { - CURL zipURL = URIUtils::CreateArchivePath("zip", url); -@@ -215,6 +218,7 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem, - } - return NULL; - } -+ } - if (url.IsFileType("xsp")) - { // XBMC Smart playlist - just XML renamed to XSP - // read the name of the playlist in - -From 7d1f22e56a754a0723d7245baf7505665e0bebeb Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 27 Oct 2014 13:06:57 +0000 -Subject: [PATCH 28/75] [rbp] Make cachemembuffersize default depend on memory - size - ---- - xbmc/linux/RBP.cpp | 5 +++++ - xbmc/settings/AdvancedSettings.cpp | 5 +++++ - 2 files changed, 10 insertions(+) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index ba1a3d0..5119949 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -22,6 +22,7 @@ - #if defined(TARGET_RASPBERRY_PI) - - #include "settings/Settings.h" -+#include "settings/AdvancedSettings.h" - #include "utils/log.h" - - #include "cores/omxplayer/OMXImage.h" -@@ -84,6 +85,9 @@ bool CRBP::Initialize() - if (!m_gui_resolution_limit) - m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080; - -+ if (g_advancedSettings.m_cacheMemBufferSize == ~0U) -+ g_advancedSettings.m_cacheMemBufferSize = m_arm_mem < 256 ? 1024 * 1024 * 2 : 1024 * 1024 * 20; -+ - g_OMXImage.Initialize(); - m_omx_image_init = true; - return true; -@@ -96,6 +100,7 @@ void CRBP::LogFirmwareVerison() - response[sizeof(response) - 1] = '\0'; - CLog::Log(LOGNOTICE, "Raspberry PI firmware version: %s", response); - CLog::Log(LOGNOTICE, "ARM mem: %dMB GPU mem: %dMB MPG2:%d WVC1:%d", m_arm_mem, m_gpu_mem, m_codec_mpg2_enabled, m_codec_wvc1_enabled); -+ CLog::Log(LOGNOTICE, "cacheMemBufferSize: %dMB", g_advancedSettings.m_cacheMemBufferSize >> 20); - m_DllBcmHost->vc_gencmd(response, sizeof response, "get_config int"); - response[sizeof(response) - 1] = '\0'; - CLog::Log(LOGNOTICE, "Config:\n%s", response); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index a1b68b5..e9cd63a 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -366,7 +366,12 @@ void CAdvancedSettings::Initialize() - m_bPVRAutoScanIconsUserSet = false; - m_iPVRNumericChannelSwitchTimeout = 1000; - -+#ifdef TARGET_RASPBERRY_PI -+ // want default to be memory dependent, but interface to gpu not available yet, so set in RBP.cpp -+ m_cacheMemBufferSize = ~0; -+#else - m_cacheMemBufferSize = 1024 * 1024 * 20; -+#endif - m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems) - // the following setting determines the readRate of a player data - // as multiply of the default data read rate - - -From 62ecc2e30e189aedac46f4be65186803bfa82f18 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 16 Jun 2014 19:06:00 +0100 -Subject: [PATCH 30/75] [experimental] Disable quiet-noise generation - ---- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -index b391ff3..463a89c 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -@@ -873,6 +873,7 @@ void CActiveAESink::SwapInit(CSampleBuffer* samples) - - void CActiveAESink::GenerateNoise() - { -+#ifndef TARGET_RASPBERRY_PI - int nb_floats = m_sampleOfSilence.pkt->max_nb_samples; - nb_floats *= m_sampleOfSilence.pkt->config.channels; - -@@ -913,6 +914,7 @@ void CActiveAESink::GenerateNoise() - - _aligned_free(noise); - delete resampler; -+#endif - } - - void CActiveAESink::SetSilenceTimer() - -From 009d4c64318bcdc5e032fa0b7cee597b5a681d54 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 30 May 2014 14:58:43 +0100 -Subject: [PATCH 31/75] [settings] Experiment: Report DESKTOP resolution in - video settings - ---- - xbmc/settings/DisplaySettings.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index 6902f83..50c5f97 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -674,6 +674,9 @@ void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting, - vector resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate); - for (vector::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); ++resolution) - { -+if (resolution->ResInfo_Index == RES_DESKTOP) -+ list.push_back(make_pair(StringUtils::Format("DESKTOP"), resolution->ResInfo_Index)); -+else - list.push_back(make_pair( - StringUtils::Format("%dx%d%s", resolution->width, resolution->height, - ModeFlagsToString(resolution->flags, false).c_str()), - -From 725c75575238ea8e0de9eba52323dd9a391ac355 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 16 Aug 2014 21:01:42 +0100 -Subject: [PATCH 32/75] omxrender: Hacks to reduce GUI rendering rate when - playing video - ---- - language/English/strings.po | 27 +++++++++++++++++++++++++++ - system/settings/rbp.xml | 16 ++++++++++++++++ - xbmc/Application.cpp | 17 +++++++++++++++++ - 3 files changed, 60 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 8e67be0..8acc0e9 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16125,3 +16125,30 @@ msgstr "" - msgctxt "#38021" - msgid "Allow viewing and playing files in archives (e.g. zip, rar)" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38000" -+msgid "Limit GUI updates when playing video" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38001" -+msgid "This can reduce CPU when playing video by updating the overlays less often" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38002" -+msgid "Off" -+msgstr "" -+ -+msgctxt "#38003" -+msgid "5 fps" -+msgstr "" -+ -+msgctxt "#38004" -+msgid "10 fps" -+msgstr "" -+ -+msgctxt "#38005" -+msgid "24 fps" -+msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index f3c8a01..2996c29 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -25,6 +25,22 @@ - - - -+ -+ -+ 2 -+ 10 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -
- -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 5425322..1df2418 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2212,6 +2212,23 @@ void CApplication::Render() - if (m_bStop) - return; - -+#ifdef TARGET_RASPBERRY_PI -+ if (g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) -+ { -+ int fps = CSettings::Get().GetInt("videoplayer.limitguiupdate"); -+ unsigned int now = XbmcThreads::SystemClockMillis(); -+ unsigned int frameTime = now - m_lastFrameTime; -+ if (fps > 0 && frameTime * fps < 1000) -+ { -+ g_renderManager.FrameWait(100); -+ g_infoManager.UpdateFPS(); -+ g_renderManager.FrameMove(); -+ g_renderManager.FrameFinish(); -+ return; -+ } -+ } -+#endif -+ - MEASURE_FUNCTION; - - int vsync_mode = CSettings::Get().GetInt("videoscreen.vsync"); - -From a284f50bd2047bc50af73aa75a44020dfa3cde42 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 9 Sep 2014 12:04:26 +0100 -Subject: [PATCH 33/75] egl: Treat unknown display aspect ratio as square pixel - ---- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index bf1e589..a25eb86 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -446,7 +446,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.iScreenWidth = tv_state.display.hdmi.width; - m_desktopRes.iScreenHeight= tv_state.display.hdmi.height; - m_desktopRes.dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); -- m_desktopRes.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); -+ m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - // Also add 3D flags - if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -@@ -467,7 +467,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.iScreenHeight= tv_state.display.sdtv.height; - m_desktopRes.dwFlags = D3DPRESENTFLAG_INTERLACED; - m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate; -- m_desktopRes.fPixelRatio = get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); -+ m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - } - - SetResolutionString(m_desktopRes); - -From 212072cd72b7b11e45fe2582a2f442edf889f55c Mon Sep 17 00:00:00 2001 -From: anaconda -Date: Thu, 11 Sep 2014 21:30:43 +0200 -Subject: [PATCH 34/75] Disable textbox autoscrolling while on screensaver. - -SQUASH: only if dim or black ---- - xbmc/Application.cpp | 7 +++++++ - xbmc/Application.h | 2 ++ - xbmc/guilib/GUITextBox.cpp | 5 ++++- - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 1df2418..80350c4 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -5894,3 +5894,10 @@ void CApplication::CloseNetworkShares() - CSFTPSessionManager::DisconnectAllSessions(); - #endif - } -+ -+std::string CApplication::GetScreenSaverId() -+{ -+ if (m_screenSaver) -+ return m_screenSaver->ID(); -+ return ""; -+} -diff --git a/xbmc/Application.h b/xbmc/Application.h -index 0a332ff..15efc90 100644 ---- a/xbmc/Application.h -+++ b/xbmc/Application.h -@@ -380,6 +380,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs - - void SetLoggingIn(bool loggingIn) { m_loggingIn = loggingIn; } - -+ std::string GetScreenSaverId(); -+ - protected: - virtual bool OnSettingsSaving() const; - -diff --git a/xbmc/guilib/GUITextBox.cpp b/xbmc/guilib/GUITextBox.cpp -index c0e2fa5..0eca360 100644 ---- a/xbmc/guilib/GUITextBox.cpp -+++ b/xbmc/guilib/GUITextBox.cpp -@@ -23,6 +23,7 @@ - #include "utils/XBMCTinyXML.h" - #include "utils/MathUtils.h" - #include "utils/StringUtils.h" -+#include "Application.h" - - using namespace std; - -@@ -132,7 +133,9 @@ void CGUITextBox::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio - // update our auto-scrolling as necessary - if (m_autoScrollTime && m_lines.size() > m_itemsPerPage) - { -- if (!m_autoScrollCondition || m_autoScrollCondition->Get()) -+ if ((!m_autoScrollCondition || m_autoScrollCondition->Get()) && !(g_application.IsInScreenSaver() && -+ (g_application.GetScreenSaverId() == "screensaver.xbmc.builtin.black" || -+ g_application.GetScreenSaverId() == "screensaver.xbmc.builtin.dim"))) - { - if (m_lastRenderTime) - m_autoScrollDelayTime += currentTime - m_lastRenderTime; - -From 3220e1f7f63c9d9d4b50088a6f8627770658a582 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 18 Sep 2014 14:24:56 +0100 -Subject: [PATCH 35/75] [omxplayer] Only enable audio clock master when A/V - sync method is set to audio clock - ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 5475570..7c07b57 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -246,7 +246,8 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") -+ if((CSettings::Get().GetBool("videoplayer.usedisplayasclock") && CSettings::Get().GetInt("videoplayer.synctype") == SYNC_DISCON) || -+ CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); -@@ -272,7 +273,7 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock")) -+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && CSettings::Get().GetInt("videoplayer.synctype") == SYNC_DISCON) - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); - -From 222992a4992f1eee0e343b072b59b7680d46162b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 19 Sep 2014 11:54:49 +0100 -Subject: [PATCH 36/75] [dvdplayer/rbp] Add pi specific option to maintain - vsync with pll adjustment - -New A/V sync option in settings/video/playback to do "Adjust PLL". -This uses video clock (so perfect video syncing) but avoids having to resample -or drop/dupe audio packets which is normally required. - -Needed updated firmware ---- - language/English/strings.po | 5 +++++ - system/settings/rbp.xml | 20 ++++++++++++++++++ - xbmc/cores/AudioEngine/Utils/AEUtil.h | 3 ++- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 36 +++++++++++++++++++++++++++++++-- - xbmc/cores/dvdplayer/DVDPlayerAudio.h | 1 + - xbmc/linux/RBP.cpp | 14 +++++++++++++ - xbmc/linux/RBP.h | 1 + - 7 files changed, 77 insertions(+), 3 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 8acc0e9..a3b71e8 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16152,3 +16152,8 @@ msgstr "" - msgctxt "#38005" - msgid "24 fps" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38006" -+msgid "Adjust PLL" -+msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 2996c29..79853a8 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -11,6 +11,26 @@ - - -
-+ -+ -+ -+ 2 -+ 2 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ true -+ -+ -+ -+ -+ - - - false -diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.h b/xbmc/cores/AudioEngine/Utils/AEUtil.h -index 782a9ba..3e0390c 100644 ---- a/xbmc/cores/AudioEngine/Utils/AEUtil.h -+++ b/xbmc/cores/AudioEngine/Utils/AEUtil.h -@@ -57,7 +57,8 @@ enum AVSync - { - SYNC_DISCON = 0, - SYNC_SKIPDUP, -- SYNC_RESAMPLE -+ SYNC_RESAMPLE, -+ SYNC_PLLADJUST - }; - - struct AEDelayStatus -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index c1a5b8d..fe76917 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -113,6 +113,7 @@ CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent) - m_started = false; - m_silence = false; - m_resampleratio = 1.0; -+ m_plladjust = 1.0f; - m_synctype = SYNC_DISCON; - m_setsynctype = SYNC_DISCON; - m_prevsynctype = -1; -@@ -475,6 +476,8 @@ void CDVDPlayerAudio::UpdatePlayerInfo() - //if the resample ratio is 0.5, then we're playing twice as fast - if (m_synctype == SYNC_RESAMPLE) - s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio; -+ if (m_synctype == SYNC_PLLADJUST) -+ s << ", pll:" << fixed << setprecision(5) << 1.0 / m_plladjust; - - s << ", att:" << fixed << setprecision(1) << log(GetCurrentAttenuation()) * 20.0f << " dB"; - -@@ -627,8 +630,8 @@ void CDVDPlayerAudio::SetSyncType(bool passthrough) - - if (m_synctype != m_prevsynctype) - { -- const char *synctypes[] = {"clock feedback", "skip/duplicate", "resample", "invalid"}; -- int synctype = (m_synctype >= 0 && m_synctype <= 2) ? m_synctype : 3; -+ const char *synctypes[] = {"clock feedback", "skip/duplicate", "resample", "pll adjust", "invalid"}; -+ int synctype = (m_synctype >= 0 && m_synctype <= 3) ? m_synctype : 4; - CLog::Log(LOGDEBUG, "CDVDPlayerAudio:: synctype set to %i: %s", m_synctype, synctypes[synctype]); - m_prevsynctype = m_synctype; - } -@@ -702,6 +705,31 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - } - m_resampleratio = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; - } -+ else if (m_synctype == SYNC_PLLADJUST) -+ { -+#if defined(TARGET_RASPBERRY_PI) -+ //reset the integral on big errors, failsafe -+ if (fabs(m_error) > DVD_TIME_BASE) -+ m_integral = 0; -+ else if (fabs(m_error) > DVD_MSEC_TO_TIME(5)) -+ m_integral += m_error / DVD_TIME_BASE / INTEGRAL; -+ -+ double proportional = 0.0; -+ -+ //on big errors use more proportional -+ if (fabs(m_error / DVD_TIME_BASE) > 0.0) -+ { -+ double proportionaldiv = PROPORTIONAL * (PROPREF / fabs(m_error / DVD_TIME_BASE)); -+ if (proportionaldiv < PROPDIVMIN) proportionaldiv = PROPDIVMIN; -+ else if (proportionaldiv > PROPDIVMAX) proportionaldiv = PROPDIVMAX; -+ -+ proportional = m_error / DVD_TIME_BASE / proportionaldiv; -+ } -+ m_plladjust = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -+ double new_adjust = g_RBP.AdjustHDMIClock(m_plladjust); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.4f (%.4f) proportional:%.4f integral:%.4f", __FUNCTION__, m_plladjust, new_adjust, proportional, m_integral); -+#endif -+ } - } - } - -@@ -740,6 +768,10 @@ bool CDVDPlayerAudio::OutputPacket(DVDAudioFrame &audioframe) - m_dvdAudio.SetResampleRatio(m_resampleratio); - m_dvdAudio.AddPackets(audioframe); - } -+ else if (m_synctype == SYNC_PLLADJUST) -+ { -+ m_dvdAudio.AddPackets(audioframe); -+ } - - return true; - } -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -index e8b2ab6..02c64a0 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -@@ -232,6 +232,7 @@ class CDVDPlayerAudio : public CThread, public IDVDStreamPlayerAudio - bool m_prevskipped; - double m_maxspeedadjust; - double m_resampleratio; //resample ratio when using SYNC_RESAMPLE, used for the codec info -+ double m_plladjust; // for display using SYNC_PLLADJUST - - struct SInfo - { -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 5119949..ce09fce 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -212,4 +212,18 @@ void CRBP::Deinitialize() - m_initialized = false; - m_omx_initialized = false; - } -+ -+double CRBP::AdjustHDMIClock(double adjust) -+{ -+ char response[80]; -+ vc_gencmd(response, sizeof response, "hdmi_adjust_clock %f", adjust); -+ float new_adjust = 1.0f; -+ char *p = strchr(response, '='); -+ if (p) -+ new_adjust = atof(p+1); -+ CLog::Log(LOGDEBUG, "CRBP::%s(%.4f) = %.4f", __func__, adjust, new_adjust); -+ return new_adjust; -+} -+ -+ - #endif -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index 4fd18f3..6456657 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -58,6 +58,7 @@ class CRBP - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); - DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } - void WaitVsync(); -+ double AdjustHDMIClock(double adjust); - - private: - DllBcmHost *m_DllBcmHost; - -From 29a77a2507e861a52bec8c00547c566803610109 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 27 Sep 2014 15:32:37 +0100 -Subject: [PATCH 37/75] [dvdplayer] exerimental: don't raise priority of audio - thread - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 12a3ed6..cb512ed 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -3210,7 +3210,11 @@ bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset) - m_dvdPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1); - - /* audio normally won't consume full cpu, so let it have prio */ -+#ifdef TARGET_RASPBERRY_PI -+ m_dvdPlayerAudio->SetPriority(GetPriority()); -+#else - m_dvdPlayerAudio->SetPriority(GetPriority()+1); -+#endif - return true; - } - - -From eedd135d8bb82fdd8bdc965513beb2dc3e62c66e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 28 Sep 2014 19:28:17 +0100 -Subject: [PATCH 38/75] [mmalcodec] Introduce a preroll period to buffer up - frames on startup - ---- - .../DVDCodecs/Video/DVDVideoCodecMMAL.cpp | 5 ++++ - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h | 1 + - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 30 +++++++++++++++++----- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h | 3 +++ - 4 files changed, 33 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -index 55b9969..262283d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -@@ -96,4 +96,9 @@ bool CDVDVideoCodecMMAL::GetCodecStats(double &pts, int &droppedPics) - return m_decoder->GetCodecStats(pts, droppedPics); - } - -+void CDVDVideoCodecMMAL::SetSpeed(int iSpeed) -+{ -+ m_decoder->SetSpeed(iSpeed); -+} -+ - #endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -index 67aa505..a768e70 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -@@ -42,6 +42,7 @@ class CDVDVideoCodecMMAL : public CDVDVideoCodec - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void); - virtual bool GetCodecStats(double &pts, int &droppedPics); -+ virtual void SetSpeed(int iSpeed); - - protected: - MMALVideoPtr m_decoder; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index 098910e..6742e0e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -128,6 +128,8 @@ CMMALVideo::CMMALVideo() - m_output_busy = 0; - m_demux_queue_length = 0; - m_es_format = mmal_format_alloc(); -+ m_preroll = true; -+ m_speed = DVD_PLAYSPEED_NORMAL; - } - - CMMALVideo::~CMMALVideo() -@@ -696,6 +698,8 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - - m_drop_state = false; - m_startframe = false; -+ m_preroll = !m_hints.stills; -+ m_speed = DVD_PLAYSPEED_NORMAL; - - return true; - } -@@ -904,23 +908,29 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) - break; - } - int ret = 0; -- if (!m_output_ready.empty()) -+ if (mmal_queue_length(m_dec_input_pool->queue) > 0 && !m_demux_queue_length) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s - got space for output: demux_queue(%d) space(%d)", CLASSNAME, __func__, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size); -- ret |= VC_PICTURE; -+ ret |= VC_BUFFER; - } -- if (mmal_queue_length(m_dec_input_pool->queue) > 0 && !m_demux_queue_length) -+ else -+ m_preroll = false; -+ -+ if (m_preroll && m_output_ready.size() >= GetAllowedReferences()) -+ m_preroll = false; -+ -+ if (!m_output_ready.empty() && !m_preroll) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s - got output picture:%d", CLASSNAME, __func__, m_output_ready.size()); -- ret |= VC_BUFFER; -+ ret |= VC_PICTURE; - } - if (!ret) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) -- CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d)", -- CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size); -+ CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d) preroll(%d)", -+ CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size, m_preroll); - Sleep(10); // otherwise we busy spin - } - return ret; -@@ -963,8 +973,16 @@ void CMMALVideo::Reset(void) - m_decoderPts = DVD_NOPTS_VALUE; - m_droppedPics = 0; - m_decode_frame_number = 1; -+ m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE); - } - -+void CMMALVideo::SetSpeed(int iSpeed) -+{ -+ if (g_advancedSettings.CanLogComponent(LOGVIDEO)) -+ CLog::Log(LOGDEBUG, "%s::%s %d->%d", CLASSNAME, __func__, m_speed, iSpeed); -+ -+ m_speed = iSpeed; -+} - - void CMMALVideo::ReturnBuffer(CMMALVideoBuffer *buffer) - { -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -index b4aa571..4f81bbd 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -@@ -90,6 +90,7 @@ class CMMALVideo - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void) { return (const char*)m_pFormatName; } - virtual bool GetCodecStats(double &pts, int &droppedPics); -+ virtual void SetSpeed(int iSpeed); - - // MMAL decoder callback routines. - void ReleaseBuffer(CMMALVideoBuffer *buffer); -@@ -140,6 +141,8 @@ class CMMALVideo - unsigned int m_decode_frame_number; - double m_decoderPts; - unsigned int m_droppedPics; -+ int m_speed; -+ bool m_preroll; - - MMAL_COMPONENT_T *m_dec; - MMAL_PORT_T *m_dec_input; - -From 84916f93b7d3c7a740a4669c3d36f3314a773b54 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 24 Sep 2014 23:13:52 +0100 -Subject: [PATCH 39/75] [audio] Add settings option to boost centre channel - when downmixing - -This allows a dB volume increase to be added to centre channel. -This can help improve dialgue in the presence of background music/effects. -It can go up to 30dB for testing purposes, but value of 6 is probably more reasonable. -It is recommended to ensure "Normalise levels on downmix" is enabled when boosting by large values to avoid clipping. - -Should work with Pi Sink (dvdplayer/paplayer) and omxplayer ---- - language/English/strings.po | 15 +++++++++++++++ - system/settings/settings.xml | 12 ++++++++++++ - .../Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp | 7 +++++++ - .../AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 6 ++++++ - xbmc/cores/omxplayer/OMXAudio.cpp | 6 ++++++ - 5 files changed, 46 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index a3b71e8..24f9636 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16157,3 +16157,18 @@ msgstr "" - msgctxt "#38006" - msgid "Adjust PLL" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38007" -+msgid "Boost centre channel when downmixing" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38008" -+msgid "Increase this value to make the dialogue louder compared to background sounds when downmixing multichannel audio" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38009" -+msgid "%i dB" -+msgstr "" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 0db66a2..dbddcb6 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2451,6 +2451,18 @@ - true - - -+ -+ 2 -+ 0 -+ -+ 0 -+ 1 -+ 30 -+ -+ -+ 38009 -+ -+ - - HAS_AE_QUALITY_LEVELS - 2 -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -index de188e7..449a500 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -@@ -20,6 +20,7 @@ - - #include "cores/AudioEngine/Utils/AEUtil.h" - #include "ActiveAEResampleFFMPEG.h" -+#include "settings/Settings.h" - #include "utils/log.h" - - extern "C" { -@@ -105,6 +106,12 @@ bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, i - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - if (remapLayout) - { -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index 96f79b7..84505bf 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -162,6 +162,12 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - if (remapLayout) - { -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 7c07b57..ef4c3d4 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -633,6 +633,12 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - // stereo upmix - if (upmix && m_src_channels == 2 && m_dst_channels > 2) - -From 138475ea18c50ffb151d83b4498065f6fd177a4c Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 3 Oct 2014 18:38:07 +0100 -Subject: [PATCH 40/75] [omxcore] Skip out of flush on error - ---- - xbmc/linux/OMXCore.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp -index 4ae29ba..4caa304 100644 ---- a/xbmc/linux/OMXCore.cpp -+++ b/xbmc/linux/OMXCore.cpp -@@ -419,7 +419,7 @@ void COMXCoreComponent::FlushAll() - - void COMXCoreComponent::FlushInput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; -@@ -436,7 +436,7 @@ void COMXCoreComponent::FlushInput() - - void COMXCoreComponent::FlushOutput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; - -From 02de40bac468886dcb16dbbfc6175a1d7167ffb3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 3 Oct 2014 18:40:06 +0100 -Subject: [PATCH 41/75] [SinkPi] Handle multichannel layout more like OMXAudio - ---- - xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -index 89684e4..fd9a03d 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -@@ -92,9 +92,9 @@ static void SetAudioProps(bool stream_channels, uint32_t channel_map) - CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map); - } - --static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) -+static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough) - { -- unsigned int channels = format.m_channelLayout.Count(); -+ unsigned int channels = channelLayout.Count(); - uint32_t channel_map = 0; - if (passthrough) - return 0; -@@ -133,12 +133,12 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels - // but no BR BL channels, we use the wide map in order to open only the num of channels really - // needed. -- if (format.m_channelLayout.HasChannel(AE_CH_BL) && !format.m_channelLayout.HasChannel(AE_CH_SL)) -+ if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL)) - map = map_back; - - for (unsigned int i = 0; i < channels; ++i) - { -- AEChannel c = format.m_channelLayout[i]; -+ AEChannel c = channelLayout[i]; - unsigned int chan = 0; - if ((unsigned int)c < sizeof map_normal / sizeof *map_normal) - chan = map[(unsigned int)c]; -@@ -169,9 +169,9 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - 0xff, // 7 - 0x13, // 7.1 - }; -- uint8_t cea = format.m_channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; -+ uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; - if (cea == 0xff) -- CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, format.m_channelLayout.HasChannel(AE_CH_LFE), channels); -+ CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels); - - channel_map |= cea << 24; - -@@ -208,7 +208,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER / NUM_OMX_BUFFERS; - format.m_frameSamples = format.m_frames * channels; - -- SetAudioProps(m_passthrough, GetChannelMap(format, m_passthrough)); -+ SetAudioProps(m_passthrough, GetChannelMap(format.m_channelLayout, m_passthrough)); - - m_format = format; - m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); - -From 960a504f649cd7b044244c57baad37ed51e0254a Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 27 Oct 2014 15:23:51 +0000 -Subject: [PATCH 42/75] [rbp] Default extract thumbnails to false - -It can take 80 seconds for a single file on a Pi. It can cause crashes with out-of-memory errors. -It genereates a lot of support issues. Best to default to disabled and let users enable it if they must ---- - system/settings/rbp.xml | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 79853a8..4c2ef41 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -62,6 +62,16 @@ - - - -+ -+ -+ -+ false -+ -+ -+ false -+ -+ -+ -
- -
- -From 23830676efe433f73e747f68bebbea710bbeb88e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 11 Nov 2014 18:14:23 +0000 -Subject: [PATCH 43/75] [resamplepi] Try to report the same numbers as ffmpeg - ---- - .../cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index 84505bf..2b5bef2 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -544,9 +544,10 @@ int CActiveAEResamplePi::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t - - int64_t CActiveAEResamplePi::GetDelay(int64_t base) - { -- int ret = m_dst_rate ? 1000 * GetBufferedSamples() / m_dst_rate : 0; -+ int64_t ret = av_rescale_rnd(GetBufferedSamples(), m_dst_rate, base, AV_ROUND_UP); -+ - #ifdef DEBUG_VERBOSE -- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, (int)ret); - #endif - return ret; - } -@@ -567,7 +568,7 @@ int CActiveAEResamplePi::GetBufferedSamples() - - int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) - { -- int ret = ((long long)src_samples * dst_rate + src_rate-1) / src_rate; -+ int ret = av_rescale_rnd(src_samples, dst_rate, src_rate, AV_ROUND_UP); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif -@@ -576,7 +577,7 @@ int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int s - - int CActiveAEResamplePi::GetSrcBufferSize(int samples) - { -- int ret = 0; -+ int ret = av_samples_get_buffer_size(NULL, m_src_channels, samples, m_src_fmt, 1); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif -@@ -585,7 +586,7 @@ int CActiveAEResamplePi::GetSrcBufferSize(int samples) - - int CActiveAEResamplePi::GetDstBufferSize(int samples) - { -- int ret = CalcDstSampleCount(samples, m_dst_rate, m_src_rate); -+ int ret = av_samples_get_buffer_size(NULL, m_dst_channels, samples, m_dst_fmt, 1); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif - -From dff457e218d695b32a4ad362e9cd96595e677fd4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 11 Nov 2014 20:49:30 +0000 -Subject: [PATCH 44/75] [dvdplayer] New scheme for PLL adjustment for video - clock - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 40 +++++++++++++-------------------- - xbmc/cores/dvdplayer/DVDPlayerAudio.h | 2 ++ - 2 files changed, 18 insertions(+), 24 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index fe76917..4f25feb 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -113,7 +113,9 @@ CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent) - m_started = false; - m_silence = false; - m_resampleratio = 1.0; -- m_plladjust = 1.0f; -+ m_plladjust = 1.0; -+ m_last_plladjust = 1.0; -+ m_last_error = 0.0; - m_synctype = SYNC_DISCON; - m_setsynctype = SYNC_DISCON; - m_prevsynctype = -1; -@@ -192,6 +194,8 @@ void CDVDPlayerAudio::OpenStream( CDVDStreamInfo &hints, CDVDAudioCodec* codec ) - - m_error = 0; - m_errors.Flush(); -+ m_plladjust = 1.0; -+ m_last_plladjust = 1.0; - m_integral = 0; - m_prevskipped = false; - m_syncclock = true; -@@ -234,7 +238,6 @@ void CDVDPlayerAudio::CloseStream(bool bWaitForBuffers) - - // uninit queue - m_messageQueue.End(); -- - CLog::Log(LOGNOTICE, "Deleting audio codec"); - if (m_pAudioCodec) - { -@@ -475,9 +478,11 @@ void CDVDPlayerAudio::UpdatePlayerInfo() - //print the inverse of the resample ratio, since that makes more sense - //if the resample ratio is 0.5, then we're playing twice as fast - if (m_synctype == SYNC_RESAMPLE) -- s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio; -+ s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; -+ if (m_synctype == SYNC_SKIPDUP) -+ s << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; - if (m_synctype == SYNC_PLLADJUST) -- s << ", pll:" << fixed << setprecision(5) << 1.0 / m_plladjust; -+ s << ", pll:" << fixed << setprecision(5) << m_last_plladjust << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; - - s << ", att:" << fixed << setprecision(1) << log(GetCurrentAttenuation()) * 20.0f << " dB"; - -@@ -651,6 +656,7 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - m_pClock->Update(clock+error, absolute, 0.0, "CDVDPlayerAudio::HandleSyncError1"); - m_errors.Flush(); - m_error = 0; -+ m_plladjust = 1.0; - m_syncclock = false; - - return; -@@ -704,32 +710,18 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - proportional = m_error / DVD_TIME_BASE / proportionaldiv; - } - m_resampleratio = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s rr:%.5f error:%.3fms", __FUNCTION__, m_resampleratio, m_error * 1e-3); - } - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- //reset the integral on big errors, failsafe -- if (fabs(m_error) > DVD_TIME_BASE) -- m_integral = 0; -- else if (fabs(m_error) > DVD_MSEC_TO_TIME(5)) -- m_integral += m_error / DVD_TIME_BASE / INTEGRAL; -- -- double proportional = 0.0; -- -- //on big errors use more proportional -- if (fabs(m_error / DVD_TIME_BASE) > 0.0) -- { -- double proportionaldiv = PROPORTIONAL * (PROPREF / fabs(m_error / DVD_TIME_BASE)); -- if (proportionaldiv < PROPDIVMIN) proportionaldiv = PROPDIVMIN; -- else if (proportionaldiv > PROPDIVMAX) proportionaldiv = PROPDIVMAX; -- -- proportional = m_error / DVD_TIME_BASE / proportionaldiv; -- } -- m_plladjust = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -- double new_adjust = g_RBP.AdjustHDMIClock(m_plladjust); -- CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.4f (%.4f) proportional:%.4f integral:%.4f", __FUNCTION__, m_plladjust, new_adjust, proportional, m_integral); -+ double e = std::max(std::min(m_error, DVD_MSEC_TO_TIME(10)), -DVD_MSEC_TO_TIME(10)); -+ m_plladjust = 1.0 + e * 1.5e-8; -+ m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * 1.5e-8 ); - #endif - } -+ m_last_error = m_error; - } - } - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -index 02c64a0..37bf4bd 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -@@ -233,6 +233,8 @@ class CDVDPlayerAudio : public CThread, public IDVDStreamPlayerAudio - double m_maxspeedadjust; - double m_resampleratio; //resample ratio when using SYNC_RESAMPLE, used for the codec info - double m_plladjust; // for display using SYNC_PLLADJUST -+ double m_last_error; // for display using SYNC_PLLADJUST -+ double m_last_plladjust; // for display using SYNC_PLLADJUST - - struct SInfo - { - -From 063facdddb659360288c377eb4a11aa25427ac74 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 15 Nov 2014 12:03:34 +0000 -Subject: [PATCH 45/75] [dvdplayer] Add lock for player creation - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 3 +++ - xbmc/cores/dvdplayer/DVDPlayer.h | 1 + - 2 files changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index cb512ed..a27291b 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -494,6 +494,7 @@ void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer, std:: - - void CDVDPlayer::CreatePlayers() - { -+ CSingleLock lock(m_players_lock); - #ifdef HAS_OMXPLAYER - if (m_omxplayer_mode && OMXPlayerUnsuitable(m_HasVideo, m_HasAudio, m_pDemuxer, m_pInputStream, m_SelectionStreams)) - { -@@ -523,6 +524,7 @@ void CDVDPlayer::CreatePlayers() - - void CDVDPlayer::DestroyPlayers() - { -+ CSingleLock lock(m_players_lock); - if (!m_players_created) - return; - delete m_dvdPlayerVideo; -@@ -4015,6 +4017,7 @@ double CDVDPlayer::GetQueueTime() - - void CDVDPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info) - { -+ CSingleLock lock(m_players_lock); - info.bitrate = m_dvdPlayerVideo->GetVideoBitrate(); - - std::string retVal; -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index ef64076..7ea6ea6 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -554,4 +554,5 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer - // omxplayer variables - struct SOmxPlayerState m_OmxPlayerState; - bool m_omxplayer_mode; // using omxplayer acceleration -+ CCriticalSection m_players_lock; - }; - -From ec8eebaab2cbc09a09f6435d51cfdf946368a2a3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 19 Nov 2014 13:29:43 +0000 -Subject: [PATCH 46/75] [dvdplayeraudio] Add advancedsetting for configuring - max pll adjustment - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 8 +++++--- - xbmc/settings/AdvancedSettings.cpp | 2 ++ - xbmc/settings/AdvancedSettings.h | 1 + - 3 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index 4f25feb..3cfe8ad 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -25,6 +25,7 @@ - #include "DVDCodecs/DVDCodecs.h" - #include "DVDCodecs/DVDFactoryCodec.h" - #include "settings/Settings.h" -+#include "settings/AdvancedSettings.h" - #include "video/VideoReferenceClock.h" - #include "utils/log.h" - #include "utils/TimeUtils.h" -@@ -715,10 +716,11 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- double e = std::max(std::min(m_error, DVD_MSEC_TO_TIME(10)), -DVD_MSEC_TO_TIME(10)); -- m_plladjust = 1.0 + e * 1.5e-8; -+ double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(10), 1.0), -1.0); -+ double adjust = g_advancedSettings.m_maxPllAdjust * 1e-6; -+ m_plladjust = 1.0 + e * adjust; - m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -- CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * 1.5e-8 ); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f a:%f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * adjust, adjust ); - #endif - } - m_last_error = m_error; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index e9cd63a..3a266f8 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -108,6 +108,7 @@ void CAdvancedSettings::Initialize() - - m_audioHeadRoom = 0; - m_ac3Gain = 12.0f; -+ m_maxPllAdjust = 300; - m_audioApplyDrc = true; - m_dvdplayerIgnoreDTSinWAV = false; - -@@ -482,6 +483,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - if (pElement) - { - XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f); -+ XMLUtils::GetInt(pElement, "maxplladjust", m_maxPllAdjust, 0, 1000000); - XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12); - XMLUtils::GetString(pElement, "defaultplayer", m_audioDefaultPlayer); - // 101 on purpose - can be used to never automark as watched -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index ed91aba..eccc62f 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -137,6 +137,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - - int m_audioHeadRoom; - float m_ac3Gain; -+ int m_maxPllAdjust; - CStdString m_audioDefaultPlayer; - float m_audioPlayCountMinimumPercent; - bool m_dvdplayerIgnoreDTSinWAV; - -From 7f6ceceb2f69718018c768a6bdad004b8d8cbb88 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 19 Nov 2014 17:35:44 +0000 -Subject: [PATCH 47/75] [mmalrender] Skip some log message in bypass mode - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 03a05de..c0ff30d 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -298,6 +298,9 @@ int CMMALRenderer::GetImage(YV12Image *image, int source, bool readonly) - - void CMMALRenderer::ReleaseBuffer(int idx) - { -+ if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -+ return; -+ - #if defined(MMAL_DEBUG_VERBOSE) - CLog::Log(LOGDEBUG, "%s::%s - %d", CLASSNAME, __func__, idx); - #endif -@@ -366,13 +369,13 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - - void CMMALRenderer::FlipPage(int source) - { -+ if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -+ return; -+ - #if defined(MMAL_DEBUG_VERBOSE) - CLog::Log(LOGDEBUG, "%s::%s - %d", CLASSNAME, __func__, source); - #endif - -- if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -- return; -- - YUVBUFFER *buffer = &m_buffers[source]; - // we only want to upload frames once - if (buffer->flipindex++) - -From e1b8916187049e731b79ea1550b1d2bd393f4014 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 24 Nov 2014 21:24:25 +0000 -Subject: [PATCH 48/75] [mmalcodec] Avoid deinterlace for dvd menus for now - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index 6742e0e..a1f11e9 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -883,7 +883,7 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) - - bool deinterlace = m_interlace_mode != MMAL_InterlaceProgressive; - -- if (deinterlace_request == VS_DEINTERLACEMODE_OFF) -+ if (m_hints.stills || deinterlace_request == VS_DEINTERLACEMODE_OFF) - deinterlace = false; - else if (deinterlace_request == VS_DEINTERLACEMODE_FORCE) - deinterlace = true; - -From be0e902ee3257fb5a3ffc27cdeecad337b506c30 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 24 Nov 2014 22:07:25 +0000 -Subject: [PATCH 49/75] [dvdplayervideo] Prod decoder when in stills mode - -An asynchronous hardware decoder doesn't only produce output pictures when new packets arrive. -In dvd stills mode give it a chance to return pictures that weren't ready when frame was decoded. ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 46 ++++++++++++++++++++------------- - 1 file changed, 28 insertions(+), 18 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index f030e37..7a8fc10 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -324,7 +324,8 @@ void CDVDPlayerVideo::Process() - - while (!m_bStop) - { -- int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000; -+ bool bPictureWaiting = m_hints.stills && (m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE) & VC_PICTURE); -+ int iQueueTimeOut = (int)(bPictureWaiting ? 0 : (m_hints.stills || m_stalled) ? frametime / 4 : frametime * 10) / 1000; - int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0; - - CDVDMsg* pMsg; -@@ -341,27 +342,36 @@ void CDVDPlayerVideo::Process() - if( iPriority ) - continue; - -- //Okey, start rendering at stream fps now instead, we are likely in a stillframe -- if( !m_stalled ) -+ // check for picture waiting -+ if (bPictureWaiting) - { -- if(m_started) -- CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate); -- m_stalled = true; -- pts+= frametime*4; -+ // create a dummy demuxer packet to prod the decode logic -+ pMsg = new CDVDMsgDemuxerPacket(CDVDDemuxUtils::AllocateDemuxPacket(0), false); - } -- -- //Waiting timed out, output last picture -- if( picture.iFlags & DVP_FLAG_ALLOCATED ) -+ else - { -- //Remove interlaced flag before outputting -- //no need to output this as if it was interlaced -- picture.iFlags &= ~DVP_FLAG_INTERLACED; -- picture.iFlags |= DVP_FLAG_NOSKIP; -- OutputPicture(&picture, pts); -- pts+= frametime; -- } -+ //Okey, start rendering at stream fps now instead, we are likely in a stillframe -+ if( !m_stalled ) -+ { -+ if(m_started) -+ CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate); -+ m_stalled = true; -+ pts+= frametime*4; -+ } - -- continue; -+ //Waiting timed out, output last picture -+ if( picture.iFlags & DVP_FLAG_ALLOCATED ) -+ { -+ //Remove interlaced flag before outputting -+ //no need to output this as if it was interlaced -+ picture.iFlags &= ~DVP_FLAG_INTERLACED; -+ picture.iFlags |= DVP_FLAG_NOSKIP; -+ OutputPicture(&picture, pts); -+ pts+= frametime; -+ } -+ -+ continue; -+ } - } - - if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) - -From bb7e171804ee58a781715cce47c51fd53614c667 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 16:20:56 +0000 -Subject: [PATCH 50/75] [mmalcodec] Skip some setup that is not required when - closing - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 27 ++++++++++++---------- - 1 file changed, 15 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index a1f11e9..a11fa65 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -708,11 +708,11 @@ void CMMALVideo::Dispose() - { - // we are happy to exit, but let last shared pointer being deleted trigger the destructor - bool done = false; -+ m_finished = true; - Reset(); - pthread_mutex_lock(&m_output_mutex); - if (!m_output_busy) - done = true; -- m_finished = true; - pthread_mutex_unlock(&m_output_mutex); - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s dts_queue(%d) ready_queue(%d) busy_queue(%d) done:%d", CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, done); -@@ -941,19 +941,21 @@ void CMMALVideo::Reset(void) - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - -- if (m_dec_input) -+ if (m_dec_input && m_dec_input->is_enabled) - mmal_port_disable(m_dec_input); -- if (m_deint_connection) -+ if (m_deint_connection && m_deint_connection->is_enabled) - mmal_connection_disable(m_deint_connection); -- if (m_dec_output) -+ if (m_dec_output && m_dec_output->is_enabled) - mmal_port_disable(m_dec_output); -- if (m_dec_input) -- mmal_port_enable(m_dec_input, dec_input_port_cb); -- if (m_deint_connection) -- mmal_connection_enable(m_deint_connection); -- if (m_dec_output) -- mmal_port_enable(m_dec_output, dec_output_port_cb_static); -- -+ if (!m_finished) -+ { -+ if (m_dec_input) -+ mmal_port_enable(m_dec_input, dec_input_port_cb); -+ if (m_deint_connection) -+ mmal_connection_enable(m_deint_connection); -+ if (m_dec_output) -+ mmal_port_enable(m_dec_output, dec_output_port_cb_static); -+ } - // blow all ready video frames - bool old_drop_state = m_drop_state; - SetDropState(true); -@@ -967,7 +969,8 @@ void CMMALVideo::Reset(void) - if (!old_drop_state) - SetDropState(false); - -- SendCodecConfigData(); -+ if (!m_finished) -+ SendCodecConfigData(); - - m_startframe = false; - m_decoderPts = DVD_NOPTS_VALUE; - -From 5930f4130c9d65fd93e58e2e4982948d2040f52f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 16:31:56 +0000 -Subject: [PATCH 51/75] [languageinvoker] Reduce priority of python threads - ---- - xbmc/interfaces/generic/LanguageInvokerThread.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/xbmc/interfaces/generic/LanguageInvokerThread.cpp b/xbmc/interfaces/generic/LanguageInvokerThread.cpp -index 7b0d903..f92aa3e 100644 ---- a/xbmc/interfaces/generic/LanguageInvokerThread.cpp -+++ b/xbmc/interfaces/generic/LanguageInvokerThread.cpp -@@ -51,6 +51,11 @@ bool CLanguageInvokerThread::execute(const std::string &script, const std::vecto - m_args = arguments; - - Create(); -+ #ifdef TARGET_RASPBERRY_PI -+ /* low prio */ -+ SetPriority(GetPriority()-1); -+ #endif -+ - return true; - } - - -From cf8ad14e8e9035e4d29ca3e1b34c87a736418de0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 17:53:46 +0000 -Subject: [PATCH 52/75] [mmalcodec] Try reducing number of video frames - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index a11fa65..dd08c95 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -628,7 +628,7 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); - -- status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, NUM_BUFFERS); -+ status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, GetAllowedReferences()); - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -index 4f81bbd..79a4bfd 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -@@ -86,7 +86,7 @@ class CMMALVideo - virtual void Reset(void); - virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); - virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture); -- virtual unsigned GetAllowedReferences() { return NUM_BUFFERS; } -+ virtual unsigned GetAllowedReferences() { return 3; } - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void) { return (const char*)m_pFormatName; } - virtual bool GetCodecStats(double &pts, int &droppedPics); - -From 8674e33d70b70cbdddb884150f9367913281c822 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 1 Dec 2014 17:31:00 +0000 -Subject: [PATCH 53/75] [mmalcodec] Ensure we have requested number of buffers - in non-accelerated case - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index c0ff30d..6d461bd 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -100,7 +100,7 @@ bool CMMALRenderer::init_vout(MMAL_ES_FORMAT_T *format) - return false; - } - -- m_vout_input->buffer_num = m_vout_input->buffer_num_recommended; -+ m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers); - m_vout_input->buffer_size = m_vout_input->buffer_size_recommended; - - status = mmal_port_enable(m_vout_input, vout_input_port_cb_static); - -From 9f8efa4d26372a517b28da10b46e761efb08fd82 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 3 Dec 2014 21:17:53 +0000 -Subject: [PATCH 54/75] [omxplayer] Add some info about hdmi sync to codec - overlay - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 8 +++++++- - xbmc/cores/omxplayer/OMXVideo.cpp | 24 ++++++++++++++++++++++++ - xbmc/cores/omxplayer/OMXVideo.h | 1 + - 3 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 605318c9..77b9461 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -618,12 +618,18 @@ void OMXPlayerVideo::SetSpeed(int speed) - - std::string OMXPlayerVideo::GetPlayerInfo() - { -+ double match = 0.0f, phase = 0.0f, pll = 0.0f; - std::ostringstream s; - s << "fr:" << fixed << setprecision(3) << m_fFrameRate; - s << ", vq:" << setw(2) << min(99,GetLevel()) << "%"; - s << ", dc:" << m_codecname; - s << ", Mb/s:" << fixed << setprecision(2) << (double)GetVideoBitrate() / (1024.0*1024.0); -- -+ if (m_omxVideo.GetPlayerInfo(match, phase, pll)) -+ { -+ s << ", match:" << fixed << setprecision(2) << match; -+ s << ", phase:" << fixed << setprecision(2) << phase; -+ s << ", pll:" << fixed << setprecision(5) << pll; -+ } - return s.str(); - } - -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index 99bb7eb..dea0e11 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -759,6 +759,30 @@ unsigned int COMXVideo::GetSize() - return m_omx_decoder.GetInputBufferSize(); - } - -+bool COMXVideo::GetPlayerInfo(double &match, double &phase, double &pll) -+{ -+ CSingleLock lock (m_critSection); -+ OMX_ERRORTYPE omx_err; -+ OMX_CONFIG_BRCMRENDERSTATSTYPE renderstats; -+ -+ if (!m_hdmi_clock_sync || !m_omx_render.IsInitialized()) -+ return false; -+ OMX_INIT_STRUCTURE(renderstats); -+ renderstats.nPortIndex = m_omx_render.GetInputPort(); -+ -+ omx_err = m_omx_render.GetParameter(OMX_IndexConfigBrcmRenderStats, &renderstats); -+ if(omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "COMXVideo::GetPlayerInfo error GetParameter OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); -+ return false; -+ } -+ match = renderstats.nMatch * 1e-6; -+ phase = (double)renderstats.nPhase / (double)renderstats.nPeriod; -+ pll = (double)renderstats.nPixelClock / (double)renderstats.nPixelClockNominal; -+ return true; -+} -+ -+ - int COMXVideo::Decode(uint8_t *pData, int iSize, double pts) - { - CSingleLock lock (m_critSection); -diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h -index c8fd5fb..9f26427 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.h -+++ b/xbmc/cores/omxplayer/OMXVideo.h -@@ -61,6 +61,7 @@ class COMXVideo - std::string GetDecoderName() { return m_video_codec_name; }; - void SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode); - int GetInputBufferSize(); -+ bool GetPlayerInfo(double &match, double &phase, double &pll); - void SubmitEOS(); - bool IsEOS(); - bool SubmittedEOS() const { return m_submitted_eos; } - -From c3220a3ed4bf509aa691979a3e341574eb2b940b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 7 Dec 2014 15:21:18 +0000 -Subject: [PATCH 55/75] [omxplayer] Remove test of removed setting, avoids a - log message - ---- - xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -index 66014d4..c2da2d2 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -@@ -525,17 +525,17 @@ AEDataFormat OMXPlayerAudio::GetDataFormat(CDVDStreamInfo hints) - /* check our audio capabilties */ - - /* pathrought is overriding hw decode*/ -- if(hints.codec == AV_CODEC_ID_AC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_AC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate)) - { - dataFormat = AE_FMT_AC3; - m_passthrough = true; - } -- if(hints.codec == AV_CODEC_ID_EAC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate * 4) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_EAC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate * 4)) - { - dataFormat = AE_FMT_EAC3; - m_passthrough = true; - } -- if(hints.codec == AV_CODEC_ID_DTS && CAEFactory::SupportsRaw(AE_FMT_DTS, hints.samplerate) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_DTS && CAEFactory::SupportsRaw(AE_FMT_DTS, hints.samplerate)) - { - dataFormat = AE_FMT_DTS; - m_passthrough = true; - -From 38648532ae2482c5923009a8085665d721630b6d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 28 Dec 2014 19:13:51 +0000 -Subject: [PATCH 56/75] [omxplayer] Skip packet concatenation for WMAV2 files - -See: http://forum.kodi.tv/showthread.php?tid=212552 ---- - xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -index 94b673e..1a920f7 100644 ---- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -+++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -@@ -97,8 +97,8 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) - if (m_pCodecContext->request_channel_layout) - CLog::Log(LOGNOTICE,"COMXAudioCodecOMX::Open() Requesting channel layout of %x", (unsigned)m_pCodecContext->request_channel_layout); - -- // vorbis has variable sized planar output, so skip concatenation -- if (hints.codec == AV_CODEC_ID_VORBIS) -+ // vorbis and wma2v2 have variable sized planar output, so skip concatenation -+ if (hints.codec == AV_CODEC_ID_VORBIS || hints.codec == AV_CODEC_ID_WMAV2) - m_bNoConcatenate = true; - - if(m_pCodecContext->bits_per_coded_sample == 0) - -From a10151bb193d6c832c1700be0bbabedae32f8b80 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 31 Dec 2014 17:08:52 +0000 -Subject: [PATCH 57/75] filesystem: Make browsing into archives enbabled by - default on Pi - -This causes issues for people who scan library with archives disabled, then subsequently enable it. -The library has the .rar files in which don't play without removing and re-adding. - -We'll let people who don't use archives disable it manually ---- - system/settings/rbp.xml | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 4c2ef41..3260465 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -1,15 +1,5 @@ - - --
-- -- -- -- false -- -- -- --
-- -
- - - -From 1b25d3a54d15b90d76dcbcdceebb719ea18c24a3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 31 Dec 2014 16:03:32 +0000 -Subject: [PATCH 58/75] [PVR] Fix for slow metadata updates of recordings - -See: http://forum.kodi.tv/showthread.php?tid=210774 - -metaron identified that entering the recordings screen wih 850 recordings on a Pi -was taking about 40 seconds. The database is opened and closed for every recording, -and this dominates the time taken. With the database open/close pulled out of the loop -it now takes 1.4 seconds. - -squash: Changes suggested by Jalle19 ---- - xbmc/pvr/recordings/PVRRecording.cpp | 20 +++++++------------- - xbmc/pvr/recordings/PVRRecording.h | 4 +++- - xbmc/pvr/recordings/PVRRecordings.cpp | 27 +++++++++++++++++---------- - xbmc/pvr/recordings/PVRRecordings.h | 4 +++- - 4 files changed, 30 insertions(+), 25 deletions(-) - -diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp -index ccf2693..905f42c 100644 ---- a/xbmc/pvr/recordings/PVRRecording.cpp -+++ b/xbmc/pvr/recordings/PVRRecording.cpp -@@ -221,7 +221,7 @@ bool CPVRRecording::SetPlayCount(int count) - return true; - } - --void CPVRRecording::UpdateMetadata(void) -+void CPVRRecording::UpdateMetadata(CVideoDatabase &db) - { - if (m_bGotMetaData) - return; -@@ -231,20 +231,14 @@ void CPVRRecording::UpdateMetadata(void) - - if (!supportsPlayCount || !supportsLastPlayed) - { -- CVideoDatabase db; -- if (db.Open()) -+ if (!supportsPlayCount) - { -- if (!supportsPlayCount) -- { -- CFileItem pFileItem(*this); -- m_playCount = db.GetPlayCount(pFileItem); -- } -- -- if (!supportsLastPlayed) -- db.GetResumeBookMark(m_strFileNameAndPath, m_resumePoint); -- -- db.Close(); -+ CFileItem pFileItem(*this); -+ m_playCount = db.GetPlayCount(pFileItem); - } -+ -+ if (!supportsLastPlayed) -+ db.GetResumeBookMark(m_strFileNameAndPath, m_resumePoint); - } - - m_bGotMetaData = true; -diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h -index 91af28a..c9d9359 100644 ---- a/xbmc/pvr/recordings/PVRRecording.h -+++ b/xbmc/pvr/recordings/PVRRecording.h -@@ -39,6 +39,8 @@ - #include "video/VideoInfoTag.h" - #include "XBDateTime.h" - -+class CVideoDatabase; -+ - namespace PVR - { - class CPVRRecording; -@@ -149,7 +151,7 @@ namespace PVR - * @brief Get the resume point and play count from the database if the - * client doesn't handle it itself. - */ -- void UpdateMetadata(void); -+ void UpdateMetadata(CVideoDatabase &db); - - /*! - * @brief Update this tag with the contents of the given tag. -diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp -index 34ef40f..7741efc 100644 ---- a/xbmc/pvr/recordings/PVRRecordings.cpp -+++ b/xbmc/pvr/recordings/PVRRecordings.cpp -@@ -43,7 +43,14 @@ CPVRRecordings::CPVRRecordings(void) : - m_iLastId(0), - m_bGroupItems(true) - { -+ m_database.Open(); -+} - -+CPVRRecordings::~CPVRRecordings() -+{ -+ Clear(); -+ if (m_database.IsOpen()) -+ m_database.Close(); - } - - void CPVRRecordings::UpdateFromClients(void) -@@ -119,8 +126,9 @@ void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList - strFilePath = StringUtils::Format("pvr://recordings/%s/%s/", strUseBase.c_str(), strCurrent.c_str()); - - CFileItemPtr pFileItem; -- current->UpdateMetadata(); -- -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); -+ - if (!results->Contains(strFilePath)) - { - pFileItem.reset(new CFileItem(strCurrent, true)); -@@ -250,8 +258,7 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) - { - bool bResult = false; - -- CVideoDatabase database; -- if (database.Open()) -+ if (m_database.IsOpen()) - { - bResult = true; - -@@ -291,15 +298,13 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) - // Clear resume bookmark - if (count > 0) - { -- database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); -+ m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); - recording->SetLastPlayedPosition(0); - } - -- database.SetPlayCount(*pItem, count); -+ m_database.SetPlayCount(*pItem, count); - } - } -- -- database.Close(); - } - - return bResult; -@@ -330,7 +335,8 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite - if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory)) - continue; - -- current->UpdateMetadata(); -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); - CFileItemPtr pFileItem(new CFileItem(*current)); - pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); - pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); -@@ -369,7 +375,8 @@ void CPVRRecordings::GetAll(CFileItemList &items) - for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) - { - CPVRRecordingPtr current = it->second; -- current->UpdateMetadata(); -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); - - CFileItemPtr pFileItem(new CFileItem(*current)); - pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); -diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h -index 6b8cb14..2bcc834 100644 ---- a/xbmc/pvr/recordings/PVRRecordings.h -+++ b/xbmc/pvr/recordings/PVRRecordings.h -@@ -24,6 +24,7 @@ - #include "threads/Thread.h" - #include "utils/Observer.h" - #include "video/VideoThumbLoader.h" -+#include "video/VideoDatabase.h" - - #define PVR_ALL_RECORDINGS_PATH_EXTENSION "-1" - -@@ -40,6 +41,7 @@ namespace PVR - PVR_RECORDINGMAP m_recordings; - unsigned int m_iLastId; - bool m_bGroupItems; -+ CVideoDatabase m_database; - - virtual void UpdateFromClients(void); - virtual std::string TrimSlashes(const std::string &strOrig) const; -@@ -58,7 +60,7 @@ namespace PVR - - public: - CPVRRecordings(void); -- virtual ~CPVRRecordings(void) { Clear(); }; -+ virtual ~CPVRRecordings(void); - - int Load(); - void Unload(); - -From 1da99439c1b3502111974ddce6f033b9d59675a0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Dec 2014 17:20:00 +0000 -Subject: [PATCH 59/75] [dvdplayer] Allow pll adjustment to go higher, but tail - off more gradually - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 2 +- - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index 3cfe8ad..5db48a8 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -716,7 +716,7 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(10), 1.0), -1.0); -+ double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(50), 1.0), -1.0); - double adjust = g_advancedSettings.m_maxPllAdjust * 1e-6; - m_plladjust = 1.0 + e * adjust; - m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 3a266f8..f007f42 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -108,7 +108,7 @@ void CAdvancedSettings::Initialize() - - m_audioHeadRoom = 0; - m_ac3Gain = 12.0f; -- m_maxPllAdjust = 300; -+ m_maxPllAdjust = 1000; - m_audioApplyDrc = true; - m_dvdplayerIgnoreDTSinWAV = false; - - -From 884b78280878f6ab25f51f3e0b3ab49376320219 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 11 Dec 2014 17:00:57 +0000 -Subject: [PATCH 60/75] Fix for UI not showing both extractflags and - extractthumb - ---- - language/English/strings.po | 11 ++++++++--- - system/settings/settings.xml | 10 +++++----- - 2 files changed, 13 insertions(+), 8 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 24f9636..c54cb25 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -10790,7 +10790,7 @@ msgstr "" - - #: system/settings/settings.xml - msgctxt "#20433" --msgid "Extract thumbnails and video information" -+msgid "Extract video information from files" - msgstr "" - - #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp -@@ -14164,7 +14164,7 @@ msgstr "" - #. Description of setting "Videos -> File lists -> Extract thumbnails and video information" with label #20433 - #: system/settings/settings.xml - msgctxt "#36178" --msgid "Extract thumbnails and metadata information such as codec and aspect ratio from videos." -+msgid "Extract metadata information such as codec and aspect ratio from videos." - msgstr "" - - #. Description of setting "Videos -> File lists -> Replace file names with library titles" with label #20419 -@@ -14176,7 +14176,7 @@ msgstr "" - #. Description of setting "Videos -> File lists -> Extract thumbnails and video information" with label #20433 - #: system/settings/settings.xml - msgctxt "#36180" --msgid "Extract thumbnails and information, such as codecs and aspect ratio, to display in Library Mode." -+msgid "Extract thumbnails, to display in Library Mode." - msgstr "" - - #: system/settings/settings.xml -@@ -16172,3 +16172,8 @@ msgstr "" - msgctxt "#38009" - msgid "%i dB" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38015" -+msgid "Extract thumbnails from video files" -+msgstr "" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index dbddcb6..756475f 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -802,17 +802,17 @@ - - - -- 1 -+ 3 - true - - -- -- 1 -+ -+ 3 - true - - -- -- 4 -+ -+ 1 - true - - - -From be43189486ef1b1886d116e8d875d7e1548c6dee Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 26 Jan 2015 19:24:17 +0000 -Subject: [PATCH 61/75] Fix for occasinal heap corruption with font cache - -See: PR 4143 issuecomment-71114810 ---- - xbmc/guilib/GUIFontCache.h | 10 +++++++++- - xbmc/guilib/GUIFontTTF.cpp | 43 ++++++++++++++++++++++++++++++++----------- - 2 files changed, 41 insertions(+), 12 deletions(-) - -diff --git a/xbmc/guilib/GUIFontCache.h b/xbmc/guilib/GUIFontCache.h -index ff766bf..575ee7d 100644 ---- a/xbmc/guilib/GUIFontCache.h -+++ b/xbmc/guilib/GUIFontCache.h -@@ -38,6 +38,7 @@ - #include "boost/multi_index/sequenced_index.hpp" - #include "boost/multi_index/hashed_index.hpp" - #include "boost/multi_index/member.hpp" -+#include "boost/shared_ptr.hpp" - - #include "TransformMatrix.h" - -@@ -201,7 +202,14 @@ struct CGUIFontCacheStaticPosition - void UpdateWithOffsets(const CGUIFontCacheStaticPosition &cached, bool scrolling) {} - }; - --typedef std::vector CGUIFontCacheStaticValue; -+struct CGUIFontCacheStaticValue : public boost::shared_ptr > -+{ -+ void clear() -+ { -+ if (*this) -+ (*this)->clear(); -+ } -+}; - - inline bool Match(const CGUIFontCacheStaticPosition &a, const TransformMatrix &a_m, - const CGUIFontCacheStaticPosition &b, const TransformMatrix &b_m, -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index 7d4fc88..4110546 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -30,6 +30,7 @@ - #include "URL.h" - #include "filesystem/File.h" - #include "threads/SystemClock.h" -+#include "boost/make_shared.hpp" - - #include - -@@ -357,6 +358,7 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - { - Begin(); - -+ uint32_t rawAlignment = alignment; - bool dirtyCache; - bool hardwareClipping = g_Windowing.ScissorsCanEffectClipping(); - CGUIFontCacheStaticPosition staticPos(x, y); -@@ -376,8 +378,8 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - XbmcThreads::SystemClockMillis(), - dirtyCache) : - unusedVertexBuffer; -- std::vector tempVertices; -- std::vector &vertices = hardwareClipping ? -+ boost::shared_ptr > tempVertices = boost::make_shared >(); -+ boost::shared_ptr > &vertices = hardwareClipping ? - tempVertices : - m_staticCache.Lookup(staticPos, - colors, text, -@@ -467,7 +469,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, vertices); -+ RenderCharacter(startX + cursorX, startY, period, color, !scrolling, *tempVertices); - cursorX += period->advance; - } - break; -@@ -476,7 +478,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, vertices); -+ RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, *tempVertices); - if ( alignment & XBFONT_JUSTIFIED ) - { - if ((*pos & 0xffff) == L' ') -@@ -489,17 +491,36 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - } - if (hardwareClipping) - { -- CVertexBuffer newVertexBuffer = CreateVertexBuffer(tempVertices); -+ CVertexBuffer &vertexBuffer = m_dynamicCache.Lookup(dynamicPos, -+ colors, text, -+ rawAlignment, maxPixelWidth, -+ scrolling, -+ XbmcThreads::SystemClockMillis(), -+ dirtyCache); -+ CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices); - vertexBuffer = newVertexBuffer; - m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertexBuffer, g_graphicsContext.GetClipRegion())); - } -+ else -+ { -+ m_staticCache.Lookup(staticPos, -+ colors, text, -+ rawAlignment, maxPixelWidth, -+ scrolling, -+ XbmcThreads::SystemClockMillis(), -+ dirtyCache) = *static_cast(&tempVertices); -+ /* Append the new vertices to the set collected since the first Begin() call */ -+ m_vertex.insert(m_vertex.end(), tempVertices->begin(), tempVertices->end()); -+ } -+ } -+ else -+ { -+ if (hardwareClipping) -+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, g_graphicsContext.GetClipRegion())); -+ else -+ /* Append the vertices from the cache to the set collected since the first Begin() call */ -+ m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end()); - } -- else if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, g_graphicsContext.GetClipRegion())); -- 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(); - } - -From 232c2dc0a1a51436a44678437ce55080ff124914 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 4 Feb 2015 22:02:33 +0000 -Subject: [PATCH 62/75] [omxplayer] Avoid extra frame allocation when - deinterlace might be enabled - -Requires updated firmware ---- - xbmc/cores/omxplayer/OMXVideo.cpp | 16 ---------------- - 1 file changed, 16 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index dea0e11..55e16c4 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -610,22 +610,6 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, EDEINTERLACEMODE de - return false; - } - -- if (m_deinterlace_request != VS_DEINTERLACEMODE_OFF) -- { -- // the deinterlace component requires 3 additional video buffers in addition to the DPB (this is normally 2). -- OMX_PARAM_U32TYPE extra_buffers; -- OMX_INIT_STRUCTURE(extra_buffers); -- extra_buffers.nU32 = 3; -- -- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamBrcmExtraBuffers, &extra_buffers); -- if(omx_err != OMX_ErrorNone) -- { -- CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamBrcmExtraBuffers omx_err(0x%08x)\n", omx_err); -- return false; -- } -- } -- -- - // broadcom omx entension: - // When enabled, the timestamp fifo mode will change the way incoming timestamps are associated with output images. - // In this mode the incoming timestamps get used without re-ordering on output images. - -From 7e18dad8c601498c8d15b2d916b0524716b49f11 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 18 Jan 2015 16:45:51 +0000 -Subject: [PATCH 63/75] [rbp] Enable error concealment by default - -Firmware now supports parsing SEI recovery points meaning streams without -IDR frames don't get discarded completely when error concealment is enabled. - -This should avoid the garbled frames that appear when seeking non-indexed (e.g. mpegts) files. -Requires updated firmware ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index dd08c95..1bfec44 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -623,7 +623,7 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - - error_concealment.hdr.id = MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT; - error_concealment.hdr.size = sizeof(MMAL_PARAMETER_BOOLEAN_T); -- error_concealment.enable = MMAL_FALSE; -+ error_concealment.enable = g_advancedSettings.m_omxDecodeStartWithValidFrame; - status = mmal_port_parameter_set(m_dec_input, &error_concealment.hdr); - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index f007f42..9f00cf4 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -117,7 +117,7 @@ void CAdvancedSettings::Initialize() - m_limiterRelease = 0.1f; - - m_omxHWAudioDecode = false; -- m_omxDecodeStartWithValidFrame = false; -+ m_omxDecodeStartWithValidFrame = true; - - m_karaokeSyncDelayCDG = 0.0f; - m_karaokeSyncDelayLRC = 0.0f; - -From feca09cb89fda6814030d0a0a62d92400625bfe0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 26 Jan 2015 17:54:07 +0000 -Subject: [PATCH 64/75] [mmalrenderer] Avoid grabbing the g_graphicsContext - lock - it can deadlock - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 6d461bd..11a6f10 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -404,7 +404,6 @@ void CMMALRenderer::FlipPage(int source) - - unsigned int CMMALRenderer::PreInit() - { -- CSingleLock lock(g_graphicsContext); - m_bConfigured = false; - UnInit(); - -@@ -434,7 +433,6 @@ void CMMALRenderer::ReleaseBuffers() - - void CMMALRenderer::UnInit() - { -- CSingleLock lock(g_graphicsContext); - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - if (m_vout) - { - -From 348995898891377b83f550f25fc657d167eecdde Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 15 Feb 2015 14:06:12 +0000 -Subject: [PATCH 65/75] [mmal] Use libmpeg2 when mpeg2 codec licence is not - available - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index bea5e4f..e4f59d7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -49,6 +49,9 @@ - #include "Video/DVDVideoCodecAndroidMediaCodec.h" - #include "android/activity/AndroidFeatures.h" - #endif -+#if defined(HAS_MMAL) -+#include "linux/RBP.h" -+#endif - #include "Audio/DVDAudioCodecFFmpeg.h" - #include "Audio/DVDAudioCodecPassthrough.h" - #include "Overlay/DVDOverlayCodecSSA.h" -@@ -196,7 +199,7 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - - #if defined(HAS_MMAL) - // mmal can handle dvd playback including stills -- if (!CSettings::Get().GetBool("videoplayer.usemmal")) -+ if (!CSettings::Get().GetBool("videoplayer.usemmal") || !g_RBP.GetCodecMpg2()) - #endif - if (hint.stills && (hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_MPEG1VIDEO)) - { - -From 232f0dafea51c319364b314b2e2277429c5bcdd7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 28 Feb 2015 22:34:52 +0000 -Subject: [PATCH 66/75] [mmalrender] Fix for hang on shutdown - -mmal_queue_push doesn't allow null pointers, so use a unique packet for signalling quit ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 5 +++-- - xbmc/cores/VideoRenderers/MMALRenderer.h | 2 ++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 11a6f10..a70eeb0 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -132,7 +132,7 @@ bool CMMALRenderer::init_vout(MMAL_ES_FORMAT_T *format) - void CMMALRenderer::Process() - { - MMAL_BUFFER_HEADER_T *buffer; -- while (buffer = mmal_queue_wait(m_release_queue), buffer) -+ while (buffer = mmal_queue_wait(m_release_queue), buffer && buffer != &m_quit_packet) - { - CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data; - omvb->Release(); -@@ -148,6 +148,7 @@ CMMALRenderer::CMMALRenderer() - m_vout_input = NULL; - m_vout_input_pool = NULL; - memset(m_buffers, 0, sizeof m_buffers); -+ mmal_buffer_header_reset(&m_quit_packet); - m_release_queue = mmal_queue_create(); - Create(); - } -@@ -156,7 +157,7 @@ CMMALRenderer::~CMMALRenderer() - { - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - // shutdown thread -- mmal_queue_put(m_release_queue, NULL); -+ mmal_queue_put(m_release_queue, &m_quit_packet); - m_sync.Wait(); - mmal_queue_destroy(m_release_queue); - UnInit(); -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.h b/xbmc/cores/VideoRenderers/MMALRenderer.h -index 8ca0b94..a5c248c 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.h -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.h -@@ -116,6 +116,8 @@ class CMMALRenderer : public CBaseRenderer, public CThread - - MMAL_QUEUE_T *m_release_queue; - CEvent m_sync; -+ MMAL_BUFFER_HEADER_T m_quit_packet; -+ - bool init_vout(MMAL_ES_FORMAT_T *m_format); - void ReleaseBuffers(); - }; - -From 69fa623c46a38f94b8a4e3eabc5cd108bc55b925 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 27 Feb 2015 19:07:17 +0000 -Subject: [PATCH 67/75] [omxplayer] Attempt to fix missing subtitles after seek - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 77b9461..2a3619f 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -295,7 +295,7 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - const double preroll = DVD_MSEC_TO_TIME(100); - double media_pts = m_av_clock->OMXMediaTime(); - -- if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts + preroll <= m_nextOverlay) -+ if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts != 0.0 && media_pts + preroll <= m_nextOverlay) - return; - - int buffer = g_renderManager.WaitForBuffer(CThread::m_bStop); - -From f12f1a04a761c73ed1bb1fd49caef5246743f5b4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 1 Mar 2015 14:49:12 +0000 -Subject: [PATCH 69/75] [omxplayer] Fix for volume being treated as a linear - scale - -The volume in kodi is actually 0.0=-60dB to 1.0=0dB. omxplayer was treating this as a linear scale. -That's correct for 0.0 and 1.0, but too loud for 0.5. - -The fix has been tested with white noise sample and decibel meter smartphone app, and now omxplayer and -dvdplayer produce the same output ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index ef4c3d4..c16ae2e 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -1056,6 +1056,8 @@ bool COMXAudio::ApplyVolume(void) - return false; - - float fVolume = m_Mute ? VOLUME_MINIMUM : m_CurrentVolume; -+ // need to convert a log scale of 0.0=-60dB, 1.0=0dB to a linear scale (0.0=silence, 1.0=full) -+ fVolume = CAEUtil::GainToScale(CAEUtil::PercentToGain(fVolume)); - - // the analogue volume is too quiet for some. Allow use of an advancedsetting to boost this (at risk of distortion) (deprecated) - double gain = pow(10, (g_advancedSettings.m_ac3Gain - 12.0f) / 20.0); - -From 6da1be424f1c9c115352e2812a96f038bef188c5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 24 Feb 2015 00:09:19 +0000 -Subject: [PATCH 70/75] [omxplayer] Limit subtitle updates to 10fps to avoid - stuttering with closed captions - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 2a3619f..6ae404df 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -221,7 +221,7 @@ double OMXPlayerVideo::NextOverlay(double pts) - else if (delta_stop > 0.0 && (min_delta == DVD_NOPTS_VALUE || delta_stop < min_delta)) - min_delta = delta_stop; - } -- return min_delta == DVD_NOPTS_VALUE ? pts+DVD_MSEC_TO_TIME(500) : pts+min_delta; -+ return min_delta == DVD_NOPTS_VALUE ? pts+DVD_MSEC_TO_TIME(500) : pts+std::max(min_delta, DVD_MSEC_TO_TIME(100)); - } - - -@@ -305,9 +305,9 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - double subtitle_pts = m_nextOverlay; - double time = subtitle_pts != DVD_NOPTS_VALUE ? subtitle_pts - media_pts : 0.0; - -- m_nextOverlay = NextOverlay(media_pts); -+ m_nextOverlay = NextOverlay(media_pts + preroll); - -- ProcessOverlays(media_pts); -+ ProcessOverlays(media_pts + preroll); - - time += m_av_clock->GetAbsoluteClock(); - g_renderManager.FlipPage(CThread::m_bStop, time/DVD_TIME_BASE); - -From 2563cbc8489b33d5a1067d439683e41c2d090496 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 17 Mar 2015 20:52:28 +0000 -Subject: [PATCH 71/75] [omxplayer] Allow HDMI output to work when unsupported - ALSA card is selected - -See: http://forum.kodi.tv/showthread.php?tid=221118&pid=1958062#pid1958062 - -Basically omxplayer doesn't support ALSA and can only drive HDMI or the analogue output. -In the past users have made use of this fact to effictively get HDMI output for videos, and ALSA output for music. - -In some of the code restructuring using omxplayer with ALSA enabled no longer works - you just get errors in the log. -A trivial change allows this to work again ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index c16ae2e..95db68c 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -128,7 +128,7 @@ bool COMXAudio::PortSettingsChanged() - if(!m_omx_render_analog.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; - } -- if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:HDMI") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") - { - if(!m_omx_render_hdmi.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; - -From a960108065b8effd7673c89542392e8ff600c548 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 27 Mar 2015 22:20:39 +0000 -Subject: [PATCH 75/75] Revert "[omxplayer] Attempt to fix missing subtitles - after seek" - -This reverts commit cb2e41c82fd58fd87ddfd632b847fef5e287b97e. ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 6ae404df..028b8cd 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -295,7 +295,7 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - const double preroll = DVD_MSEC_TO_TIME(100); - double media_pts = m_av_clock->OMXMediaTime(); - -- if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts != 0.0 && media_pts + preroll <= m_nextOverlay) -+ if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts + preroll <= m_nextOverlay) - return; - - int buffer = g_renderManager.WaitForBuffer(CThread::m_bStop); diff --git a/projects/RPi2/patches/kodi/kodi-001-helix_rpb_backports.patch b/projects/RPi2/patches/kodi/kodi-001-helix_rpb_backports.patch deleted file mode 100644 index bad13fb7cc..0000000000 --- a/projects/RPi2/patches/kodi/kodi-001-helix_rpb_backports.patch +++ /dev/null @@ -1,6575 +0,0 @@ -From 632fd2b97fbfa016fe229cf44e6d2a42e8d91edc Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 7 Apr 2014 18:19:32 +0100 -Subject: [PATCH 01/75] [rbp/omxplayer] When opening a stream don't try to - update gui so often - ---- - xbmc/dialogs/GUIDialogBusy.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/dialogs/GUIDialogBusy.cpp b/xbmc/dialogs/GUIDialogBusy.cpp -index e7cfcdd..20b99ad 100644 ---- a/xbmc/dialogs/GUIDialogBusy.cpp -+++ b/xbmc/dialogs/GUIDialogBusy.cpp -@@ -68,7 +68,11 @@ bool CGUIDialogBusy::WaitOnEvent(CEvent &event, unsigned int displaytime /* = 10 - if (dialog) - { - dialog->Show(); -+#ifdef TARGET_RASPBERRY_PI -+ while(!event.WaitMSec(100)) -+#else - while(!event.WaitMSec(1)) -+#endif - { - g_windowManager.ProcessRenderLoop(false); - if (allowCancel && dialog->IsCanceled()) - -From 3f4ea17c35b2534740ab625358dc9c3ae1d9059d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 29 Apr 2014 15:23:22 +0100 -Subject: [PATCH 02/75] [ffmpeg] Speed up wtv index creation - -The index creation is O(N^2) with number of entries (typically thousands). -On a Pi this can take more than 60 seconds to execute for a recording of a few hours. - -By replacing with an O(N) loop, this takes virtually zero time ---- - tools/depends/target/ffmpeg/Makefile | 3 +- - .../ffmpeg_Speed_up_wtv_index_creation.patch | 47 ++++++++++++++++++++++ - 2 files changed, 49 insertions(+), 1 deletion(-) - create mode 100644 tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch - -diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile -index 0e08dcf..7ce982c 100644 ---- a/tools/depends/target/ffmpeg/Makefile -+++ b/tools/depends/target/ffmpeg/Makefile -@@ -1,6 +1,6 @@ - include ../../Makefile.include - include FFMPEG-VERSION --DEPS= ../../Makefile.include FFMPEG-VERSION Makefile -+DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ffmpeg_Speed_up_wtv_index_creation.patch - - # set to "yes" to enable patching - # we don't apply patches until we move to a vanilla ffmpeg tarball -@@ -63,6 +63,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) - rm -rf $(PLATFORM); mkdir -p $(PLATFORM) - cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) - cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig \&\& pkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure -+ cd $(PLATFORM); patch -p3 < ../ffmpeg_Speed_up_wtv_index_creation.patch - cd $(PLATFORM);\ - CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ - ./configure $(ffmpg_config) -diff --git a/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch -new file mode 100644 -index 0000000..4ac5636 ---- /dev/null -+++ b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch -@@ -0,0 +1,47 @@ -+commit 0e7427498cb1131671f6fe9d054245ae7e5a36f5 -+Author: popcornmix -+Date: Tue Mar 25 19:43:07 2014 +0000 -+ -+ [ffmpeg] Speed up wtv index creation -+ -+ The index creation is O(N^2) with number of entries (typically thousands). -+ On a Pi this can take more than 60 seconds to execute for a recording of a few hours. -+ -+ By replacing with an O(N) loop, this takes virtually zero time -+ -+diff --git a/lib/ffmpeg/libavformat/wtvdec.c b/lib/ffmpeg/libavformat/wtvdec.c -+index e423370..70898bd 100644 -+--- a/lib/ffmpeg/libavformat/wtvdec.c -++++ b/lib/ffmpeg/libavformat/wtvdec.c -+@@ -980,21 +980,23 @@ static int read_header(AVFormatContext *s) -+ pb = wtvfile_open(s, root, root_size, ff_timeline_table_0_entries_Events_le16); -+ if (pb) { -+ int i; -++ AVIndexEntry *e = wtv->index_entries; -++ AVIndexEntry *e_end = wtv->index_entries + wtv->nb_index_entries - 1; -++ uint64_t last_position = 0; -+ while (1) { -+ uint64_t frame_nb = avio_rl64(pb); -+ uint64_t position = avio_rl64(pb); -++ while (frame_nb > e->size && e <= e_end) { -++ e->pos = last_position; -++ e++; -++ } -+ if (avio_feof(pb)) -+ break; -+- for (i = wtv->nb_index_entries - 1; i >= 0; i--) { -+- AVIndexEntry *e = wtv->index_entries + i; -+- if (frame_nb > e->size) -+- break; -+- if (position > e->pos) -+- e->pos = position; -+- } -++ last_position = position; -+ } -++ e_end->pos = last_position; -+ wtvfile_close(pb); -+- st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp; -++ st->duration = e_end->timestamp; -+ } -+ } -+ } - -From a7d6d41cba0dedb0e3afb819273a995e4706e0aa Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 2 Aug 2014 17:48:04 +0100 -Subject: [PATCH 03/75] [omx] Report decoded image name - ---- - xbmc/cores/omxplayer/OMXImage.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp -index aa413b9..22ec3f0 100644 ---- a/xbmc/cores/omxplayer/OMXImage.cpp -+++ b/xbmc/cores/omxplayer/OMXImage.cpp -@@ -326,6 +326,7 @@ bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, uns - { - ret = true; - *userdata = tex; -+ CLog::Log(LOGDEBUG, "%s: decoded %s %dx%d", __func__, file->GetFilename(), width, height); - } - else - { - -From 339d2a6c448685ec177367b4c20bbf2bacfcbf6a Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 8 Mar 2014 15:36:06 +0000 -Subject: [PATCH 04/75] [hifiberry] Hack: force it to be recognised as IEC958 - capable to enable passthrough options - ---- - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index df50940..2d853d6 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -1333,6 +1333,10 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev - if (snd_card_get_name(cardNr, &cardName) == 0) - info.m_displayName = cardName; - -+ // hack: hifiberry digi doesn't correctly report as iec958 device. Needs fixing in kernel driver -+ if (info.m_displayName == "snd_rpi_hifiberry_digi") -+ info.m_deviceType = AE_DEVTYPE_IEC958; -+ - if (info.m_deviceType == AE_DEVTYPE_HDMI && info.m_displayName.size() > 5 && - info.m_displayName.substr(info.m_displayName.size()-5) == " HDMI") - { - -From 9f045eb959a0cc511c83fb527bcbef0507a64964 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 11 Dec 2013 17:21:54 +0000 -Subject: [PATCH 05/75] 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 | 154 ++++++++++++++++++++----------------------- - xbmc/guilib/GUIFontTTFGL.h | 4 +- - 6 files changed, 135 insertions(+), 133 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index 4e6fb67..b1d7452 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -333,6 +333,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 1714ed7..cd35d0f 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -79,8 +79,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; }; - -@@ -171,6 +171,8 @@ class CGUIFontTTFBase - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - - 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 6a8291b..97853fd 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -53,108 +53,96 @@ CGUIFontTTFGL::~CGUIFontTTFGL(void) - { - } - --void CGUIFontTTFGL::Begin() -+bool CGUIFontTTFGL::FirstBegin() - { -- if (m_nestedBeginCount == 0 && m_texture != NULL) -+ if (m_textureStatus == TEXTURE_REALLOCATED) - { -- if (m_textureStatus == TEXTURE_REALLOCATED) -- { -- if (glIsTexture(m_nTexture)) -- g_TextureManager.ReleaseHwTexture(m_nTexture); -- m_textureStatus = TEXTURE_VOID; -- } -- -- if (m_textureStatus == TEXTURE_VOID) -- { -- // Have OpenGL generate a texture object handle for us -- glGenTextures(1, (GLuint*) &m_nTexture); -+ if (glIsTexture(m_nTexture)) -+ g_TextureManager.ReleaseHwTexture(m_nTexture); -+ m_textureStatus = TEXTURE_VOID; -+ } - -- // Bind the texture object -- glBindTexture(GL_TEXTURE_2D, m_nTexture); -+ if (m_textureStatus == TEXTURE_VOID) -+ { -+ // Have OpenGL generate a texture object handle for us -+ glGenTextures(1, (GLuint*) &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, 0); -- -- VerifyGLState(); -- m_textureStatus = TEXTURE_UPDATED; -- } -+ // 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, 0); - -- if (m_textureStatus == TEXTURE_UPDATED) -- { -- glBindTexture(GL_TEXTURE_2D, m_nTexture); -- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_updateY1, m_texture->GetWidth(), m_updateY2 - m_updateY1, GL_ALPHA, GL_UNSIGNED_BYTE, -- m_texture->GetPixels() + m_updateY1 * m_texture->GetPitch()); -- glDisable(GL_TEXTURE_2D); -- -- m_updateY1 = m_updateY2 = 0; -- m_textureStatus = TEXTURE_READY; -- } -+ VerifyGLState(); -+ m_textureStatus = TEXTURE_UPDATED; -+ } - -- // Turn Blending On -- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); -- glEnable(GL_BLEND); -+ if (m_textureStatus == TEXTURE_UPDATED) -+ { -+ glBindTexture(GL_TEXTURE_2D, m_nTexture); -+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_updateY1, m_texture->GetWidth(), m_updateY2 - m_updateY1, GL_ALPHA, GL_UNSIGNED_BYTE, -+ m_texture->GetPixels() + m_updateY1 * m_texture->GetPitch()); -+ glDisable(GL_TEXTURE_2D); -+ -+ m_updateY1 = m_updateY2 = 0; -+ m_textureStatus = TEXTURE_READY; -+ } -+ -+ // 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 c0bb53a..735fb3a 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); - -From ad4929367028c6111ce1117070fcb99f3cce9aac Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 11 Dec 2013 18:47:54 +0000 -Subject: [PATCH 06/75] 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 b1d7452..686dddf 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -160,8 +160,7 @@ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) - m_maxChars = 0; - m_nestedBeginCount = 0; - -- 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; -@@ -176,7 +175,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; - } - -@@ -237,9 +235,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(); - - m_strFileName.clear(); - m_fontFileInMemory.clear(); -@@ -337,7 +333,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++; -@@ -770,22 +766,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) -@@ -852,8 +835,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 cd35d0f..5675725 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -158,9 +158,7 @@ class CGUIFontTTFBase - - 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 97853fd..b76c6a5 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -146,13 +146,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); -@@ -168,10 +168,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/75] 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 686dddf..e6eb3f2 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -354,6 +354,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; -@@ -434,7 +436,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; -@@ -443,7 +445,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' ') -@@ -700,7 +702,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 -@@ -766,8 +768,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 5675725..a5d44f4 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -111,7 +111,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; - -From d8c252f045dee39e64df00abc4d54a4b5e7b9fcf Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 17:18:38 +0000 -Subject: [PATCH 08/75] 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. ---- - Kodi.xcodeproj/project.pbxproj | 10 ++ - project/VS2010Express/XBMC.vcxproj | 2 + - project/VS2010Express/XBMC.vcxproj.filters | 6 + - 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 ++ - 11 files changed, 456 insertions(+), 84 deletions(-) - create mode 100644 xbmc/guilib/GUIFontCache.cpp - create mode 100644 xbmc/guilib/GUIFontCache.h - -diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj -index a9ecd08..6d42c1c 100644 ---- a/Kodi.xcodeproj/project.pbxproj -+++ b/Kodi.xcodeproj/project.pbxproj -@@ -168,6 +168,9 @@ - 1D638128161E211E003603ED /* PeripheralImon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D638126161E211E003603ED /* PeripheralImon.cpp */; }; - 1DAFDB7C16DFDCA7007F8C68 /* PeripheralBusCEC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DAFDB7A16DFDCA7007F8C68 /* PeripheralBusCEC.cpp */; }; - 1DE0443515828F4B005DDB4D /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE0443315828F4B005DDB4D /* Exception.cpp */; }; -+ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; -+ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; -+ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F4564D31970129A00396109 /* GUIFontCache.cpp */; }; - 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; - 36A9443D15821E2800727135 /* DatabaseUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443B15821E2800727135 /* DatabaseUtils.cpp */; }; - 36A9444115821E7C00727135 /* SortUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443F15821E7C00727135 /* SortUtils.cpp */; }; -@@ -4021,6 +4024,8 @@ - 1DAFDB7B16DFDCA7007F8C68 /* PeripheralBusCEC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBusCEC.h; sourceTree = ""; }; - 1DE0443315828F4B005DDB4D /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Exception.cpp; path = commons/Exception.cpp; sourceTree = ""; }; - 1DE0443415828F4B005DDB4D /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Exception.h; path = commons/Exception.h; sourceTree = ""; }; -+ 2F4564D31970129A00396109 /* GUIFontCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIFontCache.cpp; sourceTree = ""; }; -+ 2F4564D41970129A00396109 /* GUIFontCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIFontCache.h; sourceTree = ""; }; - 32C631261423A90F00F18420 /* JpegIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JpegIO.cpp; sourceTree = ""; }; - 32C631271423A90F00F18420 /* JpegIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JpegIO.h; sourceTree = ""; }; - 36A9443B15821E2800727135 /* DatabaseUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseUtils.cpp; sourceTree = ""; }; -@@ -6537,6 +6542,8 @@ - 18B7C7101294222D009E7A26 /* GUIFixedListContainer.h */, - 18B7C76B1294222E009E7A26 /* GUIFont.cpp */, - 18B7C7111294222D009E7A26 /* GUIFont.h */, -+ 2F4564D31970129A00396109 /* GUIFontCache.cpp */, -+ 2F4564D41970129A00396109 /* GUIFontCache.h */, - 18B7C76C1294222E009E7A26 /* GUIFontManager.cpp */, - 18B7C7121294222D009E7A26 /* GUIFontManager.h */, - 18B7C76D1294222E009E7A26 /* GUIFontTTF.cpp */, -@@ -11045,6 +11052,7 @@ - 7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */, - F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */, - F54C51D20F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp in Sources */, -+ 2F4564D51970129A00396109 /* GUIFontCache.cpp in Sources */, - F54C51D50F1E784800D46E3C /* karaokelyricscdg.cpp in Sources */, - F54C51D80F1E785700D46E3C /* karaokelyrics.cpp in Sources */, - F54C51E50F1E787700D46E3C /* karaokelyricstextkar.cpp in Sources */, -@@ -12721,6 +12729,7 @@ - DFF0F45B17528350002DA3A4 /* Control.cpp in Sources */, - DFF0F45C17528350002DA3A4 /* Dialog.cpp in Sources */, - DFF0F45D17528350002DA3A4 /* File.cpp in Sources */, -+ 2F4564D71970129A00396109 /* GUIFontCache.cpp in Sources */, - DFF0F45E17528350002DA3A4 /* InfoTagMusic.cpp in Sources */, - DFF0F45F17528350002DA3A4 /* InfoTagVideo.cpp in Sources */, - DFF0F46017528350002DA3A4 /* Keyboard.cpp in Sources */, -@@ -13517,6 +13526,7 @@ - E499131D174E5DAD00741B6D /* GUIVisualisationControl.cpp in Sources */, - E499131E174E5DAD00741B6D /* GUIWindow.cpp in Sources */, - E499131F174E5DAD00741B6D /* GUIWindowManager.cpp in Sources */, -+ 2F4564D61970129A00396109 /* GUIFontCache.cpp in Sources */, - E4991320174E5DAD00741B6D /* GUIWrappingListContainer.cpp in Sources */, - E4991321174E5DAD00741B6D /* imagefactory.cpp in Sources */, - E4991322174E5DAD00741B6D /* IWindowManagerCallback.cpp in Sources */, -diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj -index 5dd6967..86b983c 100644 ---- a/project/VS2010Express/XBMC.vcxproj -+++ b/project/VS2010Express/XBMC.vcxproj -@@ -427,6 +427,7 @@ - - - -+ - - - -@@ -1754,6 +1755,7 @@ - - - -+ - - - -diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters -index 58d782a..3f937de 100644 ---- a/project/VS2010Express/XBMC.vcxproj.filters -+++ b/project/VS2010Express/XBMC.vcxproj.filters -@@ -994,6 +994,9 @@ - - guilib - -+ -+ guilib -+ - - guilib - -@@ -3900,6 +3903,9 @@ - - guilib - -+ -+ guilib -+ - - guilib - -diff --git a/xbmc/guilib/GUIFontCache.cpp b/xbmc/guilib/GUIFontCache.cpp -new file mode 100644 -index 0000000..2c72f9c ---- /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.template get().find(key); -+ if (i == m_list.template get().end()) -+ { -+ /* Cache miss */ -+ EntryAgeIterator oldest = m_list.template get().begin(); -+ if (!m_list.template get().empty() && nowMillis - oldest->m_lastUsedMillis > FONT_CACHE_TIME_LIMIT) -+ { -+ /* The oldest existing entry is old enough to expire and reuse */ -+ m_list.template get().modify(m_list.template project(oldest), typename CGUIFontCacheEntry::Reassign(key, nowMillis)); -+ m_list.template get().relocate(m_list.template 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.template get().push_back(CGUIFontCacheEntry(*this, key, nowMillis)); -+ } -+ dirtyCache = true; -+ return (--m_list.template 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.template get().relocate(m_list.template get().end(), m_list.template project(i)); -+ dirtyCache = false; -+ return i->m_value; -+ } -+} -+ -+template -+void CGUIFontCache::Flush() -+{ -+ m_list.template 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 e6eb3f2..6a40e9c 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -29,6 +29,7 @@ - #include "windowing/WindowingFactory.h" - #include "URL.h" - #include "filesystem/File.h" -+#include "threads/SystemClock.h" - - #include - -@@ -153,7 +154,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; -@@ -354,108 +355,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 a5d44f4..3b93672 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -66,6 +66,9 @@ struct SVertex - }; - - -+#include "GUIFontCache.h" -+ -+ - class CGUIFontTTFBase - { - friend class CGUIFont; -@@ -168,6 +171,8 @@ class CGUIFontTTFBase - CStdString m_strFileName; - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - -+ 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 b76c6a5..9935ea4 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -221,6 +221,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 c2a4c16..a385eb4 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); -+} - -From 824d5347910e00b9e0c44deffaff4d2b6db6bca3 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 23 Jan 2014 22:24:17 +0000 -Subject: [PATCH 09/75] 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 6a40e9c..a8f5e67 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -734,7 +734,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 23cb84f..5d836cee 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/WindowingFactory.h" -+#include "guilib/GraphicContext.h" - - using namespace Shaders; - -@@ -88,8 +90,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 f7b5d9a..fdf7452 100644 ---- a/xbmc/guilib/GUIShader.h -+++ b/xbmc/guilib/GUIShader.h -@@ -39,6 +39,11 @@ class CGUIShader : public Shaders::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; -@@ -54,6 +59,12 @@ class CGUIShader : public Shaders::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 d40e7a7..3cb5587 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 a385eb4..2904c1b 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(); - - -From b201e727e19af94c6d58528ebcd5960baafee499 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 23 Jan 2014 16:42:22 +0000 -Subject: [PATCH 10/75] 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 2c72f9c..df466a5 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.template get().relocate(m_list.template get().end(), m_list.template 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 a8f5e67..91bf91b 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -154,7 +154,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; -@@ -356,13 +356,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 -@@ -465,10 +480,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 3b93672..258dffa 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -172,6 +172,7 @@ class CGUIFontTTFBase - XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() - - CGUIFontCache m_staticCache; -+ CGUIFontCache m_dynamicCache; - - private: - virtual bool FirstBegin() = 0; - -From 818067e098f2b2f0fe8c816775646eef96f3b7b9 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 8 Jan 2014 12:16:33 +0000 -Subject: [PATCH 11/75] 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 844f960..5859d9f 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 8d985cf..a8e20fc 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 != "") -@@ -174,7 +176,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 5383156..41f9bc2 100644 ---- a/xbmc/utils/RssReader.cpp -+++ b/xbmc/utils/RssReader.cpp -@@ -55,7 +55,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 2cda726..fbc579e 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(); - -From 92fa695abd21992829758d5978f98f81ea99a3c5 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Mon, 27 Jan 2014 23:21:10 +0000 -Subject: [PATCH 12/75] 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 91bf91b..b1d00e5 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -236,6 +236,7 @@ void CGUIFontTTFBase::Clear() - g_freeTypeLibrary.ReleaseStroker(m_stroker); - m_stroker = NULL; - -+ m_vertexTrans.clear(); - m_vertex.clear(); - - m_strFileName.clear(); -@@ -334,6 +335,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. -@@ -481,23 +483,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 258dffa..40bf430 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -63,6 +63,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; -+ } - }; - - -@@ -161,6 +169,15 @@ class CGUIFontTTFBase - - 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 9935ea4..18c9358 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -167,34 +167,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); -@@ -222,6 +253,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) - -From 81abd97bf3d135acc7be29f201ea53657c7727d2 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 15:28:06 +0000 -Subject: [PATCH 13/75] 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 40bf430..49222a4 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -63,14 +63,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 18c9358..ea08bf4 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 -@@ -166,6 +167,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); -@@ -204,25 +206,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 fdf7452..abbe21c 100644 ---- a/xbmc/guilib/GUIShader.h -+++ b/xbmc/guilib/GUIShader.h -@@ -39,6 +39,7 @@ class CGUIShader : public Shaders::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; - -From 0112e23ceb86275743bb929c50db98928a7c635b Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 29 Jan 2014 13:21:19 +0000 -Subject: [PATCH 14/75] Enable hardware clipping. - ---- - xbmc/guilib/GUIFontTTF.cpp | 4 ++-- - xbmc/guilib/GUIFontTTF.h | 4 +++- - xbmc/guilib/GUIFontTTFGL.cpp | 6 ++++++ - 3 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index b1d00e5..ff51c89 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -483,10 +483,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 49222a4..77b324f 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -28,6 +28,7 @@ - */ - - #include "utils/auto_buffer.h" -+#include "Geometry.h" - - // forward definition - class CBaseTexture; -@@ -167,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 ea08bf4..b63e337 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -206,6 +206,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_Windowing.SetScissors(clip); -+ - // Apply the translation to the currently active (top-of-stack) model view matrix - g_matrices.MatrixMode(MM_MODELVIEW); - g_matrices.PushMatrix(); -@@ -233,6 +237,8 @@ void CGUIFontTTFGL::LastEnd() - - g_matrices.PopMatrix(); - } -+ // Restore the original scissor rectangle -+ g_Windowing.ResetScissors(); - // Restore the original model view matrix - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW)); - } - -From 7a633290e3614e6ff0d073e2653e080d5e2ac8fd Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 15:32:51 +0000 -Subject: [PATCH 15/75] 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 b63e337..b00055d 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -228,12 +228,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(); - } -@@ -241,6 +253,8 @@ void CGUIFontTTFGL::LastEnd() - g_Windowing.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 - -From 243c446cdb97ab29e1a75b70c244ad5b741dce57 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Wed, 15 Jan 2014 16:04:04 +0000 -Subject: [PATCH 16/75] 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 df466a5..bd84b9a 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 CGUIFontCacheDynamicValue; -+struct CVertexBuffer -+{ -+ void *bufferHandle; -+ size_t size; -+ CVertexBuffer() : bufferHandle(NULL), size(0), m_font(NULL) {} -+ CVertexBuffer(void *bufferHandle, size_t size, const CGUIFontTTFBase *font) : bufferHandle(bufferHandle), size(size), m_font(font) {} -+ CVertexBuffer(const CVertexBuffer &other) : bufferHandle(other.bufferHandle), size(other.size), m_font(other.m_font) -+ { -+ /* In practice, the copy constructor is only called before a vertex buffer -+ * has been attached. If this should ever change, we'll need another support -+ * function in GUIFontTTFGL/DX to duplicate a buffer, given its handle. */ -+ assert(other.bufferHandle == 0); -+ } -+ CVertexBuffer &operator=(CVertexBuffer &other) -+ { -+ /* This is used with move-assignment semantics for initialising the object in the font cache */ -+ assert(bufferHandle == 0); -+ bufferHandle = other.bufferHandle; -+ other.bufferHandle = 0; -+ size = other.size; -+ m_font = other.m_font; -+ return *this; -+ } -+ void clear(); -+private: -+ const CGUIFontTTFBase *m_font; -+}; -+ -+typedef CVertexBuffer CGUIFontCacheDynamicValue; - - inline bool Match(const CGUIFontCacheDynamicPosition &a, const TransformMatrix &a_m, - const CGUIFontCacheDynamicPosition &b, const TransformMatrix &b_m, -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index ff51c89..7d4fc88 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -367,13 +367,18 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - g_graphicsContext.ScaleFinalYCoord(x, y), - g_graphicsContext.ScaleFinalZCoord(x, y)); - } -- std::vector &vertices = hardwareClipping ? -+ CVertexBuffer unusedVertexBuffer; -+ CVertexBuffer &vertexBuffer = hardwareClipping ? - m_dynamicCache.Lookup(dynamicPos, - colors, text, - alignment, maxPixelWidth, - scrolling, - XbmcThreads::SystemClockMillis(), - dirtyCache) : -+ unusedVertexBuffer; -+ std::vector tempVertices; -+ std::vector &vertices = hardwareClipping ? -+ tempVertices : - m_staticCache.Lookup(staticPos, - colors, text, - alignment, maxPixelWidth, -@@ -483,10 +488,14 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - cursorX += ch->advance; - } - if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertices, g_graphicsContext.GetClipRegion())); -+ { -+ CVertexBuffer newVertexBuffer = CreateVertexBuffer(tempVertices); -+ vertexBuffer = newVertexBuffer; -+ m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertexBuffer, g_graphicsContext.GetClipRegion())); -+ } - } - else if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertices, g_graphicsContext.GetClipRegion())); -+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, 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 77b324f..caa1e62 100644 ---- a/xbmc/guilib/GUIFontTTF.h -+++ b/xbmc/guilib/GUIFontTTF.h -@@ -85,6 +85,9 @@ class CGUIFontTTFBase - - void Begin(); - void End(); -+ /* The next two should only be called if we've declared we can do hardware clipping */ -+ virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const { assert(false); return CVertexBuffer(); } -+ virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const {} - - const CStdString& GetFileName() const { return m_strFileName; }; - -@@ -167,9 +170,9 @@ class CGUIFontTTFBase - float translateX; - float translateY; - float translateZ; -- const std::vector *vertexBuffer; -+ const CVertexBuffer *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) {} -+ CTranslatedVertices(float translateX, float translateY, float translateZ, const CVertexBuffer *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 b00055d..aabb9a6 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -52,6 +52,10 @@ CGUIFontTTFGL::CGUIFontTTFGL(const CStdString& strFileName) - - CGUIFontTTFGL::~CGUIFontTTFGL(void) - { -+ // It's important that all the CGUIFontCacheEntry objects are -+ // destructed before the CGUIFontTTFGL goes out of scope, because -+ // our virtual methods won't be accessible after this point -+ m_dynamicCache.Flush(); - } - - bool CGUIFontTTFGL::FirstBegin() -@@ -203,7 +207,6 @@ void CGUIFontTTFGL::LastEnd() - if (m_vertexTrans.size() > 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++) - { - // Apply the clip rectangle -@@ -216,36 +219,17 @@ void CGUIFontTTFGL::LastEnd() - 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]); -- 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]; -- -- // 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); -+ glBindBuffer(GL_ARRAY_BUFFER, (GLuint) m_vertexTrans[i].vertexBuffer->bufferHandle); -+ - // 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); -+ glDrawArrays(GL_TRIANGLES, 0, 6 * m_vertexTrans[i].vertexBuffer->size); - - g_matrices.PopMatrix(); - } -@@ -266,6 +250,48 @@ void CGUIFontTTFGL::LastEnd() - #endif - } - -+#if HAS_GLES -+CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vertices) const -+{ -+ // Rearrange the vertices to describe triangles -+ std::vector triangleVertices; -+ triangleVertices.reserve(vertices.size() * 6 / 4); -+ for (size_t i = 0; i < vertices.size(); i += 4) -+ { -+ triangleVertices.push_back(vertices[i]); -+ triangleVertices.push_back(vertices[i+1]); -+ triangleVertices.push_back(vertices[i+2]); -+ triangleVertices.push_back(vertices[i+1]); -+ triangleVertices.push_back(vertices[i+3]); -+ triangleVertices.push_back(vertices[i+2]); -+ } -+ -+ // Generate a unique buffer object name and put it in bufferHandle -+ GLuint bufferHandle; -+ glGenBuffers(1, &bufferHandle); -+ // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point -+ glBindBuffer(GL_ARRAY_BUFFER, bufferHandle); -+ // 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, triangleVertices.size() * sizeof (SVertex), &triangleVertices[0], GL_STATIC_DRAW); -+ // Unbind GL_ARRAY_BUFFER -+ glBindBuffer(GL_ARRAY_BUFFER, 0); -+ -+ return CVertexBuffer((void *) bufferHandle, vertices.size() / 4, this); -+} -+ -+void CGUIFontTTFGL::DestroyVertexBuffer(CVertexBuffer &buffer) const -+{ -+ if (buffer.bufferHandle != 0) -+ { -+ // Release the buffer name for reuse -+ glDeleteBuffers(1, (GLuint *) &buffer.bufferHandle); -+ buffer.bufferHandle = 0; -+ } -+} -+#endif -+ - CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight) - { - newHeight = CBaseTexture::PadPow2(newHeight); -diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h -index 735fb3a..6102c90 100644 ---- a/xbmc/guilib/GUIFontTTFGL.h -+++ b/xbmc/guilib/GUIFontTTFGL.h -@@ -29,6 +29,7 @@ - - - #include "GUIFontTTF.h" -+#include "system.h" - - - /*! -@@ -43,6 +44,10 @@ class CGUIFontTTFGL : public CGUIFontTTFBase - - virtual bool FirstBegin(); - virtual void LastEnd(); -+#if HAS_GLES -+ virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const; -+ virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const; -+#endif - - protected: - virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); - -From 2c1526c28ea480fdf884904a4e21db9ad514855b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 1 Nov 2014 22:15:13 +0000 -Subject: [PATCH 17/75] Switch from glDrawArrays() to glDrawElements(). - -This involves setting up a static VBO containing the indexes necessary to -convert from quads to triangles on the fly in the GPU. ---- - xbmc/guilib/GUIFontTTFGL.cpp | 72 +++++++++++++++++++++++++------------ - xbmc/guilib/GUIFontTTFGL.h | 11 +++++- - xbmc/windowing/egl/WinSystemEGL.cpp | 17 +++++++++ - 3 files changed, 77 insertions(+), 23 deletions(-) - -diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp -index aabb9a6..812662c 100644 ---- a/xbmc/guilib/GUIFontTTFGL.cpp -+++ b/xbmc/guilib/GUIFontTTFGL.cpp -@@ -207,6 +207,10 @@ void CGUIFontTTFGL::LastEnd() - if (m_vertexTrans.size() > 0) - { - // Deal with the vertices that can be hardware clipped and therefore translated -+ -+ // Bind our pre-calculated array to GL_ELEMENT_ARRAY_BUFFER -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementArrayHandle); -+ - for (size_t i = 0; i < m_vertexTrans.size(); i++) - { - // Apply the clip rectangle -@@ -222,14 +226,21 @@ void CGUIFontTTFGL::LastEnd() - // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point - glBindBuffer(GL_ARRAY_BUFFER, (GLuint) m_vertexTrans[i].vertexBuffer->bufferHandle); - -- // 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, split into groups of characters no -+ // larger than the pre-determined size of the element array -+ for (size_t character = 0; m_vertexTrans[i].vertexBuffer->size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) -+ { -+ size_t count = m_vertexTrans[i].vertexBuffer->size - character; -+ count = std::min(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); -+ -+ // 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 *) (character*sizeof(SVertex)*4 + offsetof(SVertex, x))); -+ glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, r))); -+ glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, u))); - -- // Do the actual drawing operation, using the full set of vertices in the buffer -- glDrawArrays(GL_TRIANGLES, 0, 6 * m_vertexTrans[i].vertexBuffer->size); -+ glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0); -+ } - - g_matrices.PopMatrix(); - } -@@ -237,8 +248,9 @@ void CGUIFontTTFGL::LastEnd() - g_Windowing.ResetScissors(); - // Restore the original model view matrix - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, g_matrices.GetMatrix(MM_MODELVIEW)); -- // Unbind GL_ARRAY_BUFFER -+ // Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER - glBindBuffer(GL_ARRAY_BUFFER, 0); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - // Disable the attributes used by this shader -@@ -253,19 +265,6 @@ void CGUIFontTTFGL::LastEnd() - #if HAS_GLES - CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vertices) const - { -- // Rearrange the vertices to describe triangles -- std::vector triangleVertices; -- triangleVertices.reserve(vertices.size() * 6 / 4); -- for (size_t i = 0; i < vertices.size(); i += 4) -- { -- triangleVertices.push_back(vertices[i]); -- triangleVertices.push_back(vertices[i+1]); -- triangleVertices.push_back(vertices[i+2]); -- triangleVertices.push_back(vertices[i+1]); -- triangleVertices.push_back(vertices[i+3]); -- triangleVertices.push_back(vertices[i+2]); -- } -- - // Generate a unique buffer object name and put it in bufferHandle - GLuint bufferHandle; - glGenBuffers(1, &bufferHandle); -@@ -274,7 +273,7 @@ CVertexBuffer CGUIFontTTFGL::CreateVertexBuffer(const std::vector &vert - // 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, triangleVertices.size() * sizeof (SVertex), &triangleVertices[0], GL_STATIC_DRAW); -+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof (SVertex), &vertices[0], GL_STATIC_DRAW); - // Unbind GL_ARRAY_BUFFER - glBindBuffer(GL_ARRAY_BUFFER, 0); - -@@ -393,4 +392,33 @@ void CGUIFontTTFGL::DeleteHardwareTexture() - } - } - -+#if HAS_GLES -+void CGUIFontTTFGL::CreateStaticVertexBuffers(void) -+{ -+ // Bind a new buffer to the OpenGL context's GL_ELEMENT_ARRAY_BUFFER binding point -+ glGenBuffers(1, &m_elementArrayHandle); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementArrayHandle); -+ // Create an array holding the mesh indices to convert quads to triangles -+ GLushort index[ELEMENT_ARRAY_MAX_CHAR_INDEX][6]; -+ for (size_t i = 0; i < ELEMENT_ARRAY_MAX_CHAR_INDEX; i++) -+ { -+ index[i][0] = 4*i; -+ index[i][1] = 4*i+1; -+ index[i][2] = 4*i+2; -+ index[i][3] = 4*i+1; -+ index[i][4] = 4*i+3; -+ index[i][5] = 4*i+2; -+ } -+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof index, index, GL_STATIC_DRAW); -+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -+} -+ -+void CGUIFontTTFGL::DestroyStaticVertexBuffers(void) -+{ -+ glDeleteBuffers(1, &m_elementArrayHandle); -+} -+ -+GLuint CGUIFontTTFGL::m_elementArrayHandle; -+#endif -+ - #endif -diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h -index 6102c90..dcf9ca1 100644 ---- a/xbmc/guilib/GUIFontTTFGL.h -+++ b/xbmc/guilib/GUIFontTTFGL.h -@@ -30,6 +30,7 @@ - - #include "GUIFontTTF.h" - #include "system.h" -+#include "system_gl.h" - - - /*! -@@ -47,13 +48,21 @@ class CGUIFontTTFGL : public CGUIFontTTFBase - #if HAS_GLES - virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const; - virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const; -+ static void CreateStaticVertexBuffers(void); -+ static void DestroyStaticVertexBuffers(void); - #endif - - protected: - virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); - virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); - virtual void DeleteHardwareTexture(); -- -+ -+#if HAS_GLES -+#define ELEMENT_ARRAY_MAX_CHAR_INDEX (1000) -+ -+ static GLuint m_elementArrayHandle; -+#endif -+ - private: - unsigned int m_updateY1; - unsigned int m_updateY2; -diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp -index 2bdd4fa..68f0117 100644 ---- a/xbmc/windowing/egl/WinSystemEGL.cpp -+++ b/xbmc/windowing/egl/WinSystemEGL.cpp -@@ -29,6 +29,7 @@ - #include "settings/AdvancedSettings.h" - #include "settings/Settings.h" - #include "settings/DisplaySettings.h" -+#include "guilib/GUIFontTTFGL.h" - #include "guilib/DispResource.h" - #include "threads/SingleLock.h" - #include "utils/log.h" -@@ -207,6 +208,9 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - return false; - } - -+#if HAS_GLES -+ bool newContext = false; -+#endif - if (m_context == EGL_NO_CONTEXT) - { - if (!m_egl->CreateContext(m_display, m_config, contextAttrs, &m_context)) -@@ -214,6 +218,9 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - CLog::Log(LOGERROR, "%s: Could not create context",__FUNCTION__); - return false; - } -+#if HAS_GLES -+ newContext = true; -+#endif - } - - if (!m_egl->BindContext(m_display, m_surface, m_context)) -@@ -222,6 +229,11 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res) - return false; - } - -+#if HAS_GLES -+ if (newContext) -+ CGUIFontTTFGL::CreateStaticVertexBuffers(); -+#endif -+ - // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates - if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION || - g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION) -@@ -243,7 +255,12 @@ bool CWinSystemEGL::DestroyWindowSystem() - DestroyWindow(); - - if (m_context != EGL_NO_CONTEXT) -+ { -+#if HAS_GLES -+ CGUIFontTTFGL::DestroyStaticVertexBuffers(); -+#endif - m_egl->DestroyContext(m_display, m_context); -+ } - m_context = EGL_NO_CONTEXT; - - if (m_display != EGL_NO_DISPLAY) - -From 0581bdecd8c045559dcf682ea7e4bbd5a7849653 Mon Sep 17 00:00:00 2001 -From: Ben Avison -Date: Thu, 1 May 2014 16:28:39 +0100 -Subject: [PATCH 18/75] Improved file buffering in CArchive - -Even though memcpy is typically inlined by the compiler into byte/word loads -and stores (at least for release builds), the frequency with which 1, 2 and 4 -byte loads/stores are encountered in cases where the size is *not* -determinable at compile time is still high enough that it's worth handling -these specially. On the ARM1176JZF-S in the Raspberry Pi, this improves the -total time to open a library (in the case where it's fetched from a CArchive) -by around 4%. - -It should be noted that this code uses 16-bit and 32-bit word loads and -stores that are not necessarily aligned to their respective widths. It is -possible that there are some architectures out there which do not support -this, although all ARMs since ARMv6 have supported it (and ARMs earlier than -that are probably not powerful enough to be good targets for XBMC). ---- - xbmc/utils/Archive.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/xbmc/utils/Archive.h b/xbmc/utils/Archive.h -index 6ed0f8f..8506d95 100644 ---- a/xbmc/utils/Archive.h -+++ b/xbmc/utils/Archive.h -@@ -154,9 +154,17 @@ class CArchive - * than waiting until we attempt to put more data into an already full buffer */ - if (m_BufferRemain > size) - { -+ switch (size) -+ { -+ case 1: *m_BufferPos++ = *ptr; m_BufferRemain--; break; -+ case 2: *(uint16_t *) m_BufferPos = *(const uint16_t *) ptr; m_BufferPos += 2; m_BufferRemain -= 2; break; -+ case 4: *(uint32_t *) m_BufferPos = *(const uint32_t *) ptr; m_BufferPos += 4; m_BufferRemain -= 4; break; -+ default: - memcpy(m_BufferPos, ptr, size); - m_BufferPos += size; - m_BufferRemain -= size; -+ break; -+ } - return *this; - } - else -@@ -171,9 +179,17 @@ class CArchive - /* Note, refilling the buffer is deferred until we know we need to read more from it */ - if (m_BufferRemain >= size) - { -+ switch (size) -+ { -+ case 1: *ptr = *m_BufferPos++; m_BufferRemain--; break; -+ case 2: *(uint16_t *) ptr = *(const uint16_t *) m_BufferPos; m_BufferPos += 2; m_BufferRemain -= 2; break; -+ case 4: *(uint32_t *) ptr = *(const uint32_t *) m_BufferPos; m_BufferPos += 4; m_BufferRemain -= 4; break; -+ default: - memcpy(ptr, m_BufferPos, size); - m_BufferPos += size; - m_BufferRemain -= size; -+ break; -+ } - return *this; - } - else - -From 0dc98aba1e8c9bf8d63bcd12bbc18a5a6021231f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 10 Sep 2014 22:07:21 +0100 -Subject: [PATCH 19/75] [mmal] Allow mmal codec for dvd stills - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index 10648c5..bea5e4f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -194,6 +194,10 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - #endif - CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); - -+#if defined(HAS_MMAL) -+ // mmal can handle dvd playback including stills -+ if (!CSettings::Get().GetBool("videoplayer.usemmal")) -+#endif - if (hint.stills && (hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_MPEG1VIDEO)) - { - // If dvd is an mpeg2 and hint.stills - -From d46182be867dae3e4405be4558275250f87ea3c5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 12 Aug 2014 00:31:36 +0100 -Subject: [PATCH 20/75] [omxcodec] Don't force software codec with dvds - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index aae59dc..12a3ed6 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -3225,7 +3225,9 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) - hint.aspect = aspect; - hint.forced_aspect = true; - } -+#ifndef TARGET_RASPBERRY_PI - hint.software = true; -+#endif - } - - CDVDInputStream::IMenus* pMenus = dynamic_cast(m_pInputStream); - -From 7026b367733a3529f98c3ccb56b16adb6324d320 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 16 Apr 2014 21:18:06 +0100 -Subject: [PATCH 21/75] [omxplayer] Don't propagate 3d flags based on supported - 3d modes - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 29 ++++------------------------- - 1 file changed, 4 insertions(+), 25 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index ac838ce..605318c9 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -759,36 +759,15 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height, f - unsigned flags = 0; - ERenderFormat format = RENDER_FMT_BYPASS; - -+ /* figure out steremode expected based on user settings and hints */ -+ unsigned int stereo_flags = GetStereoModeFlags(GetStereoMode()); -+ - if(m_bAllowFullscreen) - { - flags |= CONF_FLAGS_FULLSCREEN; - m_bAllowFullscreen = false; // only allow on first configure - } -- -- flags |= GetStereoModeFlags(GetStereoMode()); -- -- if(flags & CONF_FLAGS_STEREO_MODE_SBS) -- { -- if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DSBS)) -- CLog::Log(LOGNOTICE, "3DSBS movie found"); -- else -- { -- flags &= ~CONF_FLAGS_STEREO_MODE_MASK(~0); -- CLog::Log(LOGNOTICE, "3DSBS movie found but not supported"); -- } -- } -- else if(flags & CONF_FLAGS_STEREO_MODE_TAB) -- { -- if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DTB)) -- CLog::Log(LOGNOTICE, "3DTB movie found"); -- else -- { -- flags &= ~CONF_FLAGS_STEREO_MODE_MASK(~0); -- CLog::Log(LOGNOTICE, "3DTB movie found but not supported"); -- } -- } -- else -- CLog::Log(LOGNOTICE, "not a 3D movie"); -+ flags |= stereo_flags; - - unsigned int iDisplayWidth = width; - unsigned int iDisplayHeight = height; - -From 9b5da40db6647d40a2c17ab957a3058622472898 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:00:52 +0100 -Subject: [PATCH 22/75] [graphics] Don't set stereo mode based on resolution - -The resolution change should follow stereo mode ---- - xbmc/guilib/GraphicContext.cpp | 35 +++++++++++++++++++---------------- - 1 file changed, 19 insertions(+), 16 deletions(-) - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index 3cb5587..fe6ebf4 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -436,26 +436,29 @@ void CGraphicContext::SetVideoResolutionInternal(RESOLUTION res, bool forceUpdat - RESOLUTION_INFO info_org = CDisplaySettings::Get().GetResolutionInfo(res); - RESOLUTION_INFO info_last = CDisplaySettings::Get().GetResolutionInfo(lastRes); - -- RENDER_STEREO_MODE stereo_mode = m_stereoMode; -- - // if the new mode is an actual stereo mode, switch to that - // if the old mode was an actual stereo mode, switch to no 3d mode -- if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DTB) -- stereo_mode = RENDER_STEREO_MODE_SPLIT_HORIZONTAL; -- else if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -- stereo_mode = RENDER_STEREO_MODE_SPLIT_VERTICAL; -- else if ((info_last.dwFlags & D3DPRESENTFLAG_MODE3DSBS) != 0 -- || (info_last.dwFlags & D3DPRESENTFLAG_MODE3DTB) != 0) -- stereo_mode = RENDER_STEREO_MODE_OFF; -- -- if(stereo_mode != m_stereoMode) -+ // only do this if 3D flags have changed -+ if ((info_org.dwFlags ^ info_last.dwFlags) & (D3DPRESENTFLAG_MODE3DTB | D3DPRESENTFLAG_MODE3DSBS)) - { -- m_stereoView = RENDER_STEREO_VIEW_OFF; -- m_stereoMode = stereo_mode; -- m_nextStereoMode = stereo_mode; -- CSettings::Get().SetInt("videoscreen.stereoscopicmode", (int)m_stereoMode); -- } -+ RENDER_STEREO_MODE stereo_mode = m_stereoMode; -+ -+ if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DTB) -+ stereo_mode = RENDER_STEREO_MODE_SPLIT_HORIZONTAL; -+ else if (info_org.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -+ stereo_mode = RENDER_STEREO_MODE_SPLIT_VERTICAL; -+ else if ((info_last.dwFlags & D3DPRESENTFLAG_MODE3DSBS) != 0 -+ || (info_last.dwFlags & D3DPRESENTFLAG_MODE3DTB) != 0) -+ stereo_mode = RENDER_STEREO_MODE_OFF; - -+ if(stereo_mode != m_stereoMode) -+ { -+ m_stereoView = RENDER_STEREO_VIEW_OFF; -+ m_stereoMode = stereo_mode; -+ m_nextStereoMode = stereo_mode; -+ CSettings::Get().SetInt("videoscreen.stereoscopicmode", (int)m_stereoMode); -+ } -+ } - RESOLUTION_INFO info_mod = GetResInfo(res); - - m_iScreenWidth = info_mod.iWidth; - -From 47fab3f66ff687e42456d0ae5f94dd5df359285e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:01:51 +0100 -Subject: [PATCH 23/75] [graphics] Allow switching to a more suitable 3D - resolution - ---- - xbmc/guilib/GraphicContext.cpp | 40 +++++++++++++++++++++++++++++++++++++++- - xbmc/guilib/GraphicContext.h | 1 + - 2 files changed, 40 insertions(+), 1 deletion(-) - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index fe6ebf4..04d0756 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -35,6 +35,7 @@ - #include "utils/JobManager.h" - #include "video/VideoReferenceClock.h" - #include "cores/IPlayer.h" -+#include - - using namespace std; - -@@ -500,6 +501,43 @@ RESOLUTION CGraphicContext::GetVideoResolution() const - return m_Resolution; - } - -+RESOLUTION CGraphicContext::Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const -+{ -+ RESOLUTION best = resolution; -+ RESOLUTION_INFO curr = CDisplaySettings::Get().GetResolutionInfo(best); -+ // Find closest refresh rate -+ for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) -+ { -+ const RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo((RESOLUTION)i); -+ -+ //discard resolutions that are not the same width and height (and interlaced/3D flags) -+ //or have a too low refreshrate -+ if (info.iScreenWidth != curr.iScreenWidth -+ || info.iScreenHeight != curr.iScreenHeight -+ || info.iScreen != curr.iScreen -+ || (info.dwFlags & D3DPRESENTFLAG_INTERLACED) != (curr.dwFlags & D3DPRESENTFLAG_INTERLACED) -+ || fabs(info.fRefreshRate - curr.fRefreshRate) >= FLT_EPSILON) -+ continue; -+ -+ if (mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ else if (mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && info.dwFlags & D3DPRESENTFLAG_MODE3DTB) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ else if ((mode == RENDER_STEREO_MODE_OFF || mode == RENDER_STEREO_MODE_MONO) && !(info.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB))) -+ { -+ best = (RESOLUTION)i; -+ break; -+ } -+ } -+ return best; -+} -+ - void CGraphicContext::ResetOverscan(RESOLUTION_INFO &res) - { - res.Overscan.left = 0; -@@ -1037,7 +1075,7 @@ void CGraphicContext::Flip(const CDirtyRegionList& dirty) - if(m_stereoMode != m_nextStereoMode) - { - m_stereoMode = m_nextStereoMode; -- SetVideoResolution(GetVideoResolution(), true); -+ SetVideoResolution(Get3DVideoResolution(m_Resolution, m_stereoMode), true); - g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_RENDERER_RESET); - } - } -diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h -index 2904c1b..8d3774f 100644 ---- a/xbmc/guilib/GraphicContext.h -+++ b/xbmc/guilib/GraphicContext.h -@@ -108,6 +108,7 @@ class CGraphicContext : public CCriticalSection, - bool IsValidResolution(RESOLUTION res); - void SetVideoResolution(RESOLUTION res, bool forceUpdate = false); - RESOLUTION GetVideoResolution() const; -+ RESOLUTION Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const; - void ResetOverscan(RESOLUTION res, OVERSCAN &overscan); - void ResetOverscan(RESOLUTION_INFO &resinfo); - void ResetScreenParameters(RESOLUTION res); - -From d5838e37d76f6a0e7054d7e9cbb7beab41b2f63b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 17 Apr 2014 13:38:55 +0100 -Subject: [PATCH 24/75] [3D] Support switching to 3D resolutions - -Include matching 3D flags (SBS/TAB) in the score of a resolution to switch to, to enable switching to 3d modes. -Also remove the old code that treated 3D modes differently when assigning a score. ---- - xbmc/cores/VideoRenderers/BaseRenderer.cpp | 47 +++++++++++------------------- - 1 file changed, 17 insertions(+), 30 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -index 83c3adb..8076e76 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -@@ -222,10 +222,14 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight) - { - RESOLUTION_INFO curr = g_graphicsContext.GetResInfo(current); -+ RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode(); - - float fRefreshRate = fps; - -- float last_diff = fRefreshRate; -+ int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -+ if (!(stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) != !(curr.dwFlags & D3DPRESENTFLAG_MODE3DSBS) || -+ !(stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) != !(curr.dwFlags & D3DPRESENTFLAG_MODE3DTB)) -+ c_weight += 1000; - - // Find closest refresh rate - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) -@@ -241,40 +245,23 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES - || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; - -- // For 3D choose the closest refresh rate -- if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) -- { -- float diff = (info.fRefreshRate - fRefreshRate); -- if(diff < 0) -- diff *= -1.0f; -+ int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); - -- if(diff < last_diff) -- { -- last_diff = diff; -- current = (RESOLUTION)i; -- curr = info; -- } -- } -- else -- { -- int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -- int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); -+ if (!(stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL) != !(info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) || -+ !(stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) != !(info.dwFlags & D3DPRESENTFLAG_MODE3DTB)) -+ i_weight += 1000; - -- // Closer the better, prefer higher refresh rate if the same -- if ((i_weight < c_weight) -- || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) -- { -- current = (RESOLUTION)i; -- curr = info; -- } -+ // Closer the better, prefer higher refresh rate if the same -+ if ((i_weight < c_weight) -+ || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) -+ { -+ current = (RESOLUTION)i; -+ curr = info; -+ c_weight = i_weight; - } - } - -- // For 3D overwrite weight -- if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) -- weight = 0; -- else -- weight = RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier); -+ weight = RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier); - - return current; - } - -From e397abe59fbddcaf141d261855278cb6048e136f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 23 Apr 2014 00:05:07 +0100 -Subject: [PATCH 25/75] [graphics] Make pixel ratio for 3d modes consistent - -Note: Use the stored stereo flags from lists of resolutions. -Use current stereo mode for current resolution. ---- - xbmc/cores/VideoRenderers/BaseRenderer.cpp | 10 +++---- - xbmc/guilib/GraphicContext.cpp | 37 ++++++++++++------------- - xbmc/guilib/GraphicContext.h | 12 ++++++-- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 8 ------ - 4 files changed, 32 insertions(+), 35 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -index 8076e76..9118cb0 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp -@@ -119,7 +119,7 @@ bool CBaseRenderer::FindResolutionFromOverride(float fps, float& weight, bool fa - - for (size_t j = (int)RES_DESKTOP; j < CDisplaySettings::Get().ResolutionInfoSize(); j++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)j); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)j, g_graphicsContext.GetStereoMode((RESOLUTION)j)); - - if (info.iScreenWidth == curr.iScreenWidth - && info.iScreenHeight == curr.iScreenHeight -@@ -179,7 +179,7 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - //get the resolution with the refreshrate closest to 60 hertz - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - if (MathUtils::round_int(info.fRefreshRate) == 60 - && info.iScreenWidth == curr.iScreenWidth -@@ -200,7 +200,7 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) - CLog::Log(LOGDEBUG, "60 hertz refreshrate not available, choosing highest"); - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - if (info.fRefreshRate > curr.fRefreshRate - && info.iScreenWidth == curr.iScreenWidth -@@ -234,14 +234,14 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES - // Find closest refresh rate - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) - { -- const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); -+ const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i, g_graphicsContext.GetStereoMode((RESOLUTION)i)); - - //discard resolutions that are not the same width and height (and interlaced/3D flags) - //or have a too low refreshrate - if (info.iScreenWidth != curr.iScreenWidth - || info.iScreenHeight != curr.iScreenHeight - || info.iScreen != curr.iScreen -- || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) -+ || (info.dwFlags & D3DPRESENTFLAG_INTERLACED) != (curr.dwFlags & D3DPRESENTFLAG_INTERLACED) - || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; - -diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp -index 04d0756..93bd207 100644 ---- a/xbmc/guilib/GraphicContext.cpp -+++ b/xbmc/guilib/GraphicContext.cpp -@@ -747,32 +747,33 @@ void CGraphicContext::ApplyStateBlock() - g_Windowing.ApplyStateBlock(); - } - --const RESOLUTION_INFO CGraphicContext::GetResInfo(RESOLUTION res) const -+RENDER_STEREO_MODE CGraphicContext::GetStereoMode(RESOLUTION res) const - { - RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res); -+ return (info.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? RENDER_STEREO_MODE_SPLIT_HORIZONTAL : -+ (info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? RENDER_STEREO_MODE_SPLIT_VERTICAL : RENDER_STEREO_MODE_OFF; -+} - -- if(m_stereoMode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) -+const RESOLUTION_INFO CGraphicContext::GetResInfo(RESOLUTION res, RENDER_STEREO_MODE stereoMode) const -+{ -+ RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res); -+ -+ if(stereoMode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL) - { -- if((info.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0) -- { -- info.fPixelRatio /= 2; -- info.iBlanking = 0; -- info.dwFlags |= D3DPRESENTFLAG_MODE3DTB; -- } -+ info.fPixelRatio /= 2; -+ info.iBlanking = 0; -+ info.dwFlags |= D3DPRESENTFLAG_MODE3DTB; - info.iHeight = (info.iHeight - info.iBlanking) / 2; - info.Overscan.top /= 2; - info.Overscan.bottom = (info.Overscan.bottom - info.iBlanking) / 2; - info.iSubtitles = (info.iSubtitles - info.iBlanking) / 2; - } - -- if(m_stereoMode == RENDER_STEREO_MODE_SPLIT_VERTICAL) -+ if(stereoMode == RENDER_STEREO_MODE_SPLIT_VERTICAL) - { -- if((info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) == 0) -- { -- info.fPixelRatio *= 2; -- info.iBlanking = 0; -- info.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -- } -+ info.fPixelRatio *= 2; -+ info.iBlanking = 0; -+ info.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - info.iWidth = (info.iWidth - info.iBlanking) / 2; - info.Overscan.left /= 2; - info.Overscan.right = (info.Overscan.right - info.iBlanking) / 2; -@@ -790,16 +791,14 @@ void CGraphicContext::SetResInfo(RESOLUTION res, const RESOLUTION_INFO& info) - if(info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) - { - curr.Overscan.right = info.Overscan.right * 2 + info.iBlanking; -- if((curr.dwFlags & D3DPRESENTFLAG_MODE3DSBS) == 0) -- curr.fPixelRatio /= 2.0; -+ curr.fPixelRatio /= 2.0; - } - - if(info.dwFlags & D3DPRESENTFLAG_MODE3DTB) - { - curr.Overscan.bottom = info.Overscan.bottom * 2 + info.iBlanking; - curr.iSubtitles = info.iSubtitles * 2 + info.iBlanking; -- if((curr.dwFlags & D3DPRESENTFLAG_MODE3DTB) == 0) -- curr.fPixelRatio *= 2.0; -+ curr.fPixelRatio *= 2.0; - } - } - -diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h -index 8d3774f..f2e122d 100644 ---- a/xbmc/guilib/GraphicContext.h -+++ b/xbmc/guilib/GraphicContext.h -@@ -120,11 +120,15 @@ class CGraphicContext : public CCriticalSection, - void GetAllowedResolutions(std::vector &res); - - // output scaling -+ const RESOLUTION_INFO GetResInfo(RESOLUTION res) const -+ { -+ return GetResInfo(res, GetStereoMode()); -+ } - const RESOLUTION_INFO GetResInfo() const - { - return GetResInfo(m_Resolution); - } -- const RESOLUTION_INFO GetResInfo(RESOLUTION res) const; -+ const RESOLUTION_INFO GetResInfo(RESOLUTION res, RENDER_STEREO_MODE stereo_mode) const; - void SetResInfo(RESOLUTION res, const RESOLUTION_INFO& info); - - /* \brief Get UI scaling information from a given resolution to the screen resolution. -@@ -161,9 +165,11 @@ class CGraphicContext : public CCriticalSection, - void RestoreOrigin(); - void SetCameraPosition(const CPoint &camera); - void SetStereoView(RENDER_STEREO_VIEW view); -- RENDER_STEREO_VIEW GetStereoView() { return m_stereoView; } -+ RENDER_STEREO_VIEW GetStereoView() const { return m_stereoView; } - void SetStereoMode(RENDER_STEREO_MODE mode) { m_nextStereoMode = mode; } -- RENDER_STEREO_MODE GetStereoMode() { return m_stereoMode; } -+ RENDER_STEREO_MODE GetStereoMode() const { return m_stereoMode; } -+ RENDER_STEREO_MODE GetStereoMode(RESOLUTION res) const; -+ - void RestoreCameraPosition(); - /*! \brief Set a region in which to clip all rendering - Anything that is rendered after setting a clip region will be clipped so that no part renders -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index c58c28a..bf1e589 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -449,15 +449,9 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - // Also add 3D flags - if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) -- { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -- m_desktopRes.fPixelRatio *= 2.0; -- } - else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF) -- { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DTB; -- m_desktopRes.fPixelRatio *= 0.5; -- } - HDMI_PROPERTY_PARAM_T property; - property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; - vc_tv_hdmi_get_property(&property); -@@ -600,7 +594,6 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v - RESOLUTION_INFO res2 = res; - res2.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - res2.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight); -- res2.fPixelRatio *= 2.0f; - res2.iSubtitles = (int)(0.965 * res2.iHeight); - - AddUniqueResolution(res2, resolutions); -@@ -616,7 +609,6 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v - RESOLUTION_INFO res2 = res; - res2.dwFlags |= D3DPRESENTFLAG_MODE3DTB; - res2.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight); -- res2.fPixelRatio *= 0.5f; - res2.iSubtitles = (int)(0.965 * res2.iHeight); - - AddUniqueResolution(res2, resolutions); - -From 00d11452657c179a50e9754838753b4dd1e3742e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 10 Aug 2014 16:45:16 +0100 -Subject: [PATCH 26/75] filesystem: Make support of browsing into archives - optional - -The ability to browse, scan and play content in archives can cause problems on low powered/low memory devices. -It's quite common to see reports of a large rar file that causes xbmc to crash with an out-of-memory error when browsing or scanning. -It also can be slow as any archive in the directory is opened and extracted. - -Add a settings option to enable this feature and default to disabled on Pi ---- - language/English/strings.po | 9 +++++++++ - system/settings/rbp.xml | 10 ++++++++++ - system/settings/settings.xml | 5 +++++ - xbmc/filesystem/FileDirectoryFactory.cpp | 4 ++++ - 4 files changed, 28 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 15090fc..8e67be0 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16115,4 +16115,13 @@ msgstr "" - #: system/settings/rbp.xml - msgctxt "#38010" - msgid "GPU accelerated" -+ -+#: system/settings/settings.xml -+msgctxt "#38020" -+msgid "Support browsing into archives" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38021" -+msgid "Allow viewing and playing files in archives (e.g. zip, rar)" - msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index f572eed..f3c8a01 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -1,5 +1,15 @@ - - -+
-+ -+ -+ -+ false -+ -+ -+ -+
-+ -
- - -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 367542d..0db66a2 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -226,6 +226,11 @@ - false - - -+ -+ 1 -+ true -+ -+ - - - -diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp -index 2fd8777..3b294cd 100644 ---- a/xbmc/filesystem/FileDirectoryFactory.cpp -+++ b/xbmc/filesystem/FileDirectoryFactory.cpp -@@ -46,6 +46,7 @@ - #include "Directory.h" - #include "File.h" - #include "ZipManager.h" -+#include "settings/Settings.h" - #include "settings/AdvancedSettings.h" - #include "FileItem.h" - #include "utils/StringUtils.h" -@@ -142,6 +143,8 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem, - return NULL; - } - #endif -+ if (CSettings::Get().GetBool("filelists.browsearchives")) -+ { - if (url.IsFileType("zip")) - { - CURL zipURL = URIUtils::CreateArchivePath("zip", url); -@@ -215,6 +218,7 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem, - } - return NULL; - } -+ } - if (url.IsFileType("xsp")) - { // XBMC Smart playlist - just XML renamed to XSP - // read the name of the playlist in - -From 7d1f22e56a754a0723d7245baf7505665e0bebeb Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 27 Oct 2014 13:06:57 +0000 -Subject: [PATCH 28/75] [rbp] Make cachemembuffersize default depend on memory - size - ---- - xbmc/linux/RBP.cpp | 5 +++++ - xbmc/settings/AdvancedSettings.cpp | 5 +++++ - 2 files changed, 10 insertions(+) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index ba1a3d0..5119949 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -22,6 +22,7 @@ - #if defined(TARGET_RASPBERRY_PI) - - #include "settings/Settings.h" -+#include "settings/AdvancedSettings.h" - #include "utils/log.h" - - #include "cores/omxplayer/OMXImage.h" -@@ -84,6 +85,9 @@ bool CRBP::Initialize() - if (!m_gui_resolution_limit) - m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080; - -+ if (g_advancedSettings.m_cacheMemBufferSize == ~0U) -+ g_advancedSettings.m_cacheMemBufferSize = m_arm_mem < 256 ? 1024 * 1024 * 2 : 1024 * 1024 * 20; -+ - g_OMXImage.Initialize(); - m_omx_image_init = true; - return true; -@@ -96,6 +100,7 @@ void CRBP::LogFirmwareVerison() - response[sizeof(response) - 1] = '\0'; - CLog::Log(LOGNOTICE, "Raspberry PI firmware version: %s", response); - CLog::Log(LOGNOTICE, "ARM mem: %dMB GPU mem: %dMB MPG2:%d WVC1:%d", m_arm_mem, m_gpu_mem, m_codec_mpg2_enabled, m_codec_wvc1_enabled); -+ CLog::Log(LOGNOTICE, "cacheMemBufferSize: %dMB", g_advancedSettings.m_cacheMemBufferSize >> 20); - m_DllBcmHost->vc_gencmd(response, sizeof response, "get_config int"); - response[sizeof(response) - 1] = '\0'; - CLog::Log(LOGNOTICE, "Config:\n%s", response); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index a1b68b5..e9cd63a 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -366,7 +366,12 @@ void CAdvancedSettings::Initialize() - m_bPVRAutoScanIconsUserSet = false; - m_iPVRNumericChannelSwitchTimeout = 1000; - -+#ifdef TARGET_RASPBERRY_PI -+ // want default to be memory dependent, but interface to gpu not available yet, so set in RBP.cpp -+ m_cacheMemBufferSize = ~0; -+#else - m_cacheMemBufferSize = 1024 * 1024 * 20; -+#endif - m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems) - // the following setting determines the readRate of a player data - // as multiply of the default data read rate - - -From 62ecc2e30e189aedac46f4be65186803bfa82f18 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 16 Jun 2014 19:06:00 +0100 -Subject: [PATCH 30/75] [experimental] Disable quiet-noise generation - ---- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -index b391ff3..463a89c 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp -@@ -873,6 +873,7 @@ void CActiveAESink::SwapInit(CSampleBuffer* samples) - - void CActiveAESink::GenerateNoise() - { -+#ifndef TARGET_RASPBERRY_PI - int nb_floats = m_sampleOfSilence.pkt->max_nb_samples; - nb_floats *= m_sampleOfSilence.pkt->config.channels; - -@@ -913,6 +914,7 @@ void CActiveAESink::GenerateNoise() - - _aligned_free(noise); - delete resampler; -+#endif - } - - void CActiveAESink::SetSilenceTimer() - -From 009d4c64318bcdc5e032fa0b7cee597b5a681d54 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 30 May 2014 14:58:43 +0100 -Subject: [PATCH 31/75] [settings] Experiment: Report DESKTOP resolution in - video settings - ---- - xbmc/settings/DisplaySettings.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp -index 6902f83..50c5f97 100644 ---- a/xbmc/settings/DisplaySettings.cpp -+++ b/xbmc/settings/DisplaySettings.cpp -@@ -674,6 +674,9 @@ void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting, - vector resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate); - for (vector::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); ++resolution) - { -+if (resolution->ResInfo_Index == RES_DESKTOP) -+ list.push_back(make_pair(StringUtils::Format("DESKTOP"), resolution->ResInfo_Index)); -+else - list.push_back(make_pair( - StringUtils::Format("%dx%d%s", resolution->width, resolution->height, - ModeFlagsToString(resolution->flags, false).c_str()), - -From 725c75575238ea8e0de9eba52323dd9a391ac355 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 16 Aug 2014 21:01:42 +0100 -Subject: [PATCH 32/75] omxrender: Hacks to reduce GUI rendering rate when - playing video - ---- - language/English/strings.po | 27 +++++++++++++++++++++++++++ - system/settings/rbp.xml | 16 ++++++++++++++++ - xbmc/Application.cpp | 17 +++++++++++++++++ - 3 files changed, 60 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 8e67be0..8acc0e9 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16125,3 +16125,30 @@ msgstr "" - msgctxt "#38021" - msgid "Allow viewing and playing files in archives (e.g. zip, rar)" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38000" -+msgid "Limit GUI updates when playing video" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38001" -+msgid "This can reduce CPU when playing video by updating the overlays less often" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38002" -+msgid "Off" -+msgstr "" -+ -+msgctxt "#38003" -+msgid "5 fps" -+msgstr "" -+ -+msgctxt "#38004" -+msgid "10 fps" -+msgstr "" -+ -+msgctxt "#38005" -+msgid "24 fps" -+msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index f3c8a01..2996c29 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -25,6 +25,22 @@ - - - -+ -+ -+ 2 -+ 10 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -
- -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 5425322..1df2418 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2212,6 +2212,23 @@ void CApplication::Render() - if (m_bStop) - return; - -+#ifdef TARGET_RASPBERRY_PI -+ if (g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback()) -+ { -+ int fps = CSettings::Get().GetInt("videoplayer.limitguiupdate"); -+ unsigned int now = XbmcThreads::SystemClockMillis(); -+ unsigned int frameTime = now - m_lastFrameTime; -+ if (fps > 0 && frameTime * fps < 1000) -+ { -+ g_renderManager.FrameWait(100); -+ g_infoManager.UpdateFPS(); -+ g_renderManager.FrameMove(); -+ g_renderManager.FrameFinish(); -+ return; -+ } -+ } -+#endif -+ - MEASURE_FUNCTION; - - int vsync_mode = CSettings::Get().GetInt("videoscreen.vsync"); - -From a284f50bd2047bc50af73aa75a44020dfa3cde42 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 9 Sep 2014 12:04:26 +0100 -Subject: [PATCH 33/75] egl: Treat unknown display aspect ratio as square pixel - ---- - xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -index bf1e589..a25eb86 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp -@@ -446,7 +446,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.iScreenWidth = tv_state.display.hdmi.width; - m_desktopRes.iScreenHeight= tv_state.display.hdmi.height; - m_desktopRes.dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); -- m_desktopRes.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); -+ m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - // Also add 3D flags - if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -@@ -467,7 +467,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r - m_desktopRes.iScreenHeight= tv_state.display.sdtv.height; - m_desktopRes.dwFlags = D3DPRESENTFLAG_INTERLACED; - m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate; -- m_desktopRes.fPixelRatio = get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); -+ m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - } - - SetResolutionString(m_desktopRes); - -From 212072cd72b7b11e45fe2582a2f442edf889f55c Mon Sep 17 00:00:00 2001 -From: anaconda -Date: Thu, 11 Sep 2014 21:30:43 +0200 -Subject: [PATCH 34/75] Disable textbox autoscrolling while on screensaver. - -SQUASH: only if dim or black ---- - xbmc/Application.cpp | 7 +++++++ - xbmc/Application.h | 2 ++ - xbmc/guilib/GUITextBox.cpp | 5 ++++- - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 1df2418..80350c4 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -5894,3 +5894,10 @@ void CApplication::CloseNetworkShares() - CSFTPSessionManager::DisconnectAllSessions(); - #endif - } -+ -+std::string CApplication::GetScreenSaverId() -+{ -+ if (m_screenSaver) -+ return m_screenSaver->ID(); -+ return ""; -+} -diff --git a/xbmc/Application.h b/xbmc/Application.h -index 0a332ff..15efc90 100644 ---- a/xbmc/Application.h -+++ b/xbmc/Application.h -@@ -380,6 +380,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs - - void SetLoggingIn(bool loggingIn) { m_loggingIn = loggingIn; } - -+ std::string GetScreenSaverId(); -+ - protected: - virtual bool OnSettingsSaving() const; - -diff --git a/xbmc/guilib/GUITextBox.cpp b/xbmc/guilib/GUITextBox.cpp -index c0e2fa5..0eca360 100644 ---- a/xbmc/guilib/GUITextBox.cpp -+++ b/xbmc/guilib/GUITextBox.cpp -@@ -23,6 +23,7 @@ - #include "utils/XBMCTinyXML.h" - #include "utils/MathUtils.h" - #include "utils/StringUtils.h" -+#include "Application.h" - - using namespace std; - -@@ -132,7 +133,9 @@ void CGUITextBox::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio - // update our auto-scrolling as necessary - if (m_autoScrollTime && m_lines.size() > m_itemsPerPage) - { -- if (!m_autoScrollCondition || m_autoScrollCondition->Get()) -+ if ((!m_autoScrollCondition || m_autoScrollCondition->Get()) && !(g_application.IsInScreenSaver() && -+ (g_application.GetScreenSaverId() == "screensaver.xbmc.builtin.black" || -+ g_application.GetScreenSaverId() == "screensaver.xbmc.builtin.dim"))) - { - if (m_lastRenderTime) - m_autoScrollDelayTime += currentTime - m_lastRenderTime; - -From 3220e1f7f63c9d9d4b50088a6f8627770658a582 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 18 Sep 2014 14:24:56 +0100 -Subject: [PATCH 35/75] [omxplayer] Only enable audio clock master when A/V - sync method is set to audio clock - ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 5475570..7c07b57 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -246,7 +246,8 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") -+ if((CSettings::Get().GetBool("videoplayer.usedisplayasclock") && CSettings::Get().GetInt("videoplayer.synctype") == SYNC_DISCON) || -+ CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both") - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); -@@ -272,7 +273,7 @@ bool COMXAudio::PortSettingsChanged() - { - // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock. - // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync -- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock")) -+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && CSettings::Get().GetInt("videoplayer.synctype") == SYNC_DISCON) - { - OMX_CONFIG_BOOLEANTYPE configBool; - OMX_INIT_STRUCTURE(configBool); - -From 222992a4992f1eee0e343b072b59b7680d46162b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 19 Sep 2014 11:54:49 +0100 -Subject: [PATCH 36/75] [dvdplayer/rbp] Add pi specific option to maintain - vsync with pll adjustment - -New A/V sync option in settings/video/playback to do "Adjust PLL". -This uses video clock (so perfect video syncing) but avoids having to resample -or drop/dupe audio packets which is normally required. - -Needed updated firmware ---- - language/English/strings.po | 5 +++++ - system/settings/rbp.xml | 20 ++++++++++++++++++ - xbmc/cores/AudioEngine/Utils/AEUtil.h | 3 ++- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 36 +++++++++++++++++++++++++++++++-- - xbmc/cores/dvdplayer/DVDPlayerAudio.h | 1 + - xbmc/linux/RBP.cpp | 14 +++++++++++++ - xbmc/linux/RBP.h | 1 + - 7 files changed, 77 insertions(+), 3 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 8acc0e9..a3b71e8 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16152,3 +16152,8 @@ msgstr "" - msgctxt "#38005" - msgid "24 fps" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38006" -+msgid "Adjust PLL" -+msgstr "" -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 2996c29..79853a8 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -11,6 +11,26 @@ -
- -
-+ -+ -+ -+ 2 -+ 2 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ true -+ -+ -+ -+ -+ - - - false -diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.h b/xbmc/cores/AudioEngine/Utils/AEUtil.h -index 782a9ba..3e0390c 100644 ---- a/xbmc/cores/AudioEngine/Utils/AEUtil.h -+++ b/xbmc/cores/AudioEngine/Utils/AEUtil.h -@@ -57,7 +57,8 @@ enum AVSync - { - SYNC_DISCON = 0, - SYNC_SKIPDUP, -- SYNC_RESAMPLE -+ SYNC_RESAMPLE, -+ SYNC_PLLADJUST - }; - - struct AEDelayStatus -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index c1a5b8d..fe76917 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -113,6 +113,7 @@ CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent) - m_started = false; - m_silence = false; - m_resampleratio = 1.0; -+ m_plladjust = 1.0f; - m_synctype = SYNC_DISCON; - m_setsynctype = SYNC_DISCON; - m_prevsynctype = -1; -@@ -475,6 +476,8 @@ void CDVDPlayerAudio::UpdatePlayerInfo() - //if the resample ratio is 0.5, then we're playing twice as fast - if (m_synctype == SYNC_RESAMPLE) - s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio; -+ if (m_synctype == SYNC_PLLADJUST) -+ s << ", pll:" << fixed << setprecision(5) << 1.0 / m_plladjust; - - s << ", att:" << fixed << setprecision(1) << log(GetCurrentAttenuation()) * 20.0f << " dB"; - -@@ -627,8 +630,8 @@ void CDVDPlayerAudio::SetSyncType(bool passthrough) - - if (m_synctype != m_prevsynctype) - { -- const char *synctypes[] = {"clock feedback", "skip/duplicate", "resample", "invalid"}; -- int synctype = (m_synctype >= 0 && m_synctype <= 2) ? m_synctype : 3; -+ const char *synctypes[] = {"clock feedback", "skip/duplicate", "resample", "pll adjust", "invalid"}; -+ int synctype = (m_synctype >= 0 && m_synctype <= 3) ? m_synctype : 4; - CLog::Log(LOGDEBUG, "CDVDPlayerAudio:: synctype set to %i: %s", m_synctype, synctypes[synctype]); - m_prevsynctype = m_synctype; - } -@@ -702,6 +705,31 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - } - m_resampleratio = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; - } -+ else if (m_synctype == SYNC_PLLADJUST) -+ { -+#if defined(TARGET_RASPBERRY_PI) -+ //reset the integral on big errors, failsafe -+ if (fabs(m_error) > DVD_TIME_BASE) -+ m_integral = 0; -+ else if (fabs(m_error) > DVD_MSEC_TO_TIME(5)) -+ m_integral += m_error / DVD_TIME_BASE / INTEGRAL; -+ -+ double proportional = 0.0; -+ -+ //on big errors use more proportional -+ if (fabs(m_error / DVD_TIME_BASE) > 0.0) -+ { -+ double proportionaldiv = PROPORTIONAL * (PROPREF / fabs(m_error / DVD_TIME_BASE)); -+ if (proportionaldiv < PROPDIVMIN) proportionaldiv = PROPDIVMIN; -+ else if (proportionaldiv > PROPDIVMAX) proportionaldiv = PROPDIVMAX; -+ -+ proportional = m_error / DVD_TIME_BASE / proportionaldiv; -+ } -+ m_plladjust = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -+ double new_adjust = g_RBP.AdjustHDMIClock(m_plladjust); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.4f (%.4f) proportional:%.4f integral:%.4f", __FUNCTION__, m_plladjust, new_adjust, proportional, m_integral); -+#endif -+ } - } - } - -@@ -740,6 +768,10 @@ bool CDVDPlayerAudio::OutputPacket(DVDAudioFrame &audioframe) - m_dvdAudio.SetResampleRatio(m_resampleratio); - m_dvdAudio.AddPackets(audioframe); - } -+ else if (m_synctype == SYNC_PLLADJUST) -+ { -+ m_dvdAudio.AddPackets(audioframe); -+ } - - return true; - } -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -index e8b2ab6..02c64a0 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -@@ -232,6 +232,7 @@ class CDVDPlayerAudio : public CThread, public IDVDStreamPlayerAudio - bool m_prevskipped; - double m_maxspeedadjust; - double m_resampleratio; //resample ratio when using SYNC_RESAMPLE, used for the codec info -+ double m_plladjust; // for display using SYNC_PLLADJUST - - struct SInfo - { -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 5119949..ce09fce 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -212,4 +212,18 @@ void CRBP::Deinitialize() - m_initialized = false; - m_omx_initialized = false; - } -+ -+double CRBP::AdjustHDMIClock(double adjust) -+{ -+ char response[80]; -+ vc_gencmd(response, sizeof response, "hdmi_adjust_clock %f", adjust); -+ float new_adjust = 1.0f; -+ char *p = strchr(response, '='); -+ if (p) -+ new_adjust = atof(p+1); -+ CLog::Log(LOGDEBUG, "CRBP::%s(%.4f) = %.4f", __func__, adjust, new_adjust); -+ return new_adjust; -+} -+ -+ - #endif -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index 4fd18f3..6456657 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -58,6 +58,7 @@ class CRBP - unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); - DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } - void WaitVsync(); -+ double AdjustHDMIClock(double adjust); - - private: - DllBcmHost *m_DllBcmHost; - -From 29a77a2507e861a52bec8c00547c566803610109 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 27 Sep 2014 15:32:37 +0100 -Subject: [PATCH 37/75] [dvdplayer] exerimental: don't raise priority of audio - thread - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 12a3ed6..cb512ed 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -3210,7 +3210,11 @@ bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset) - m_dvdPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1); - - /* audio normally won't consume full cpu, so let it have prio */ -+#ifdef TARGET_RASPBERRY_PI -+ m_dvdPlayerAudio->SetPriority(GetPriority()); -+#else - m_dvdPlayerAudio->SetPriority(GetPriority()+1); -+#endif - return true; - } - - -From eedd135d8bb82fdd8bdc965513beb2dc3e62c66e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 28 Sep 2014 19:28:17 +0100 -Subject: [PATCH 38/75] [mmalcodec] Introduce a preroll period to buffer up - frames on startup - ---- - .../DVDCodecs/Video/DVDVideoCodecMMAL.cpp | 5 ++++ - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h | 1 + - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 30 +++++++++++++++++----- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h | 3 +++ - 4 files changed, 33 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -index 55b9969..262283d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.cpp -@@ -96,4 +96,9 @@ bool CDVDVideoCodecMMAL::GetCodecStats(double &pts, int &droppedPics) - return m_decoder->GetCodecStats(pts, droppedPics); - } - -+void CDVDVideoCodecMMAL::SetSpeed(int iSpeed) -+{ -+ m_decoder->SetSpeed(iSpeed); -+} -+ - #endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -index 67aa505..a768e70 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecMMAL.h -@@ -42,6 +42,7 @@ class CDVDVideoCodecMMAL : public CDVDVideoCodec - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void); - virtual bool GetCodecStats(double &pts, int &droppedPics); -+ virtual void SetSpeed(int iSpeed); - - protected: - MMALVideoPtr m_decoder; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index 098910e..6742e0e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -128,6 +128,8 @@ CMMALVideo::CMMALVideo() - m_output_busy = 0; - m_demux_queue_length = 0; - m_es_format = mmal_format_alloc(); -+ m_preroll = true; -+ m_speed = DVD_PLAYSPEED_NORMAL; - } - - CMMALVideo::~CMMALVideo() -@@ -696,6 +698,8 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - - m_drop_state = false; - m_startframe = false; -+ m_preroll = !m_hints.stills; -+ m_speed = DVD_PLAYSPEED_NORMAL; - - return true; - } -@@ -904,23 +908,29 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) - break; - } - int ret = 0; -- if (!m_output_ready.empty()) -+ if (mmal_queue_length(m_dec_input_pool->queue) > 0 && !m_demux_queue_length) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s - got space for output: demux_queue(%d) space(%d)", CLASSNAME, __func__, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size); -- ret |= VC_PICTURE; -+ ret |= VC_BUFFER; - } -- if (mmal_queue_length(m_dec_input_pool->queue) > 0 && !m_demux_queue_length) -+ else -+ m_preroll = false; -+ -+ if (m_preroll && m_output_ready.size() >= GetAllowedReferences()) -+ m_preroll = false; -+ -+ if (!m_output_ready.empty() && !m_preroll) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s - got output picture:%d", CLASSNAME, __func__, m_output_ready.size()); -- ret |= VC_BUFFER; -+ ret |= VC_PICTURE; - } - if (!ret) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) -- CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d)", -- CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size); -+ CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d) preroll(%d)", -+ CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size, m_preroll); - Sleep(10); // otherwise we busy spin - } - return ret; -@@ -963,8 +973,16 @@ void CMMALVideo::Reset(void) - m_decoderPts = DVD_NOPTS_VALUE; - m_droppedPics = 0; - m_decode_frame_number = 1; -+ m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE); - } - -+void CMMALVideo::SetSpeed(int iSpeed) -+{ -+ if (g_advancedSettings.CanLogComponent(LOGVIDEO)) -+ CLog::Log(LOGDEBUG, "%s::%s %d->%d", CLASSNAME, __func__, m_speed, iSpeed); -+ -+ m_speed = iSpeed; -+} - - void CMMALVideo::ReturnBuffer(CMMALVideoBuffer *buffer) - { -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -index b4aa571..4f81bbd 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -@@ -90,6 +90,7 @@ class CMMALVideo - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void) { return (const char*)m_pFormatName; } - virtual bool GetCodecStats(double &pts, int &droppedPics); -+ virtual void SetSpeed(int iSpeed); - - // MMAL decoder callback routines. - void ReleaseBuffer(CMMALVideoBuffer *buffer); -@@ -140,6 +141,8 @@ class CMMALVideo - unsigned int m_decode_frame_number; - double m_decoderPts; - unsigned int m_droppedPics; -+ int m_speed; -+ bool m_preroll; - - MMAL_COMPONENT_T *m_dec; - MMAL_PORT_T *m_dec_input; - -From 84916f93b7d3c7a740a4669c3d36f3314a773b54 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 24 Sep 2014 23:13:52 +0100 -Subject: [PATCH 39/75] [audio] Add settings option to boost centre channel - when downmixing - -This allows a dB volume increase to be added to centre channel. -This can help improve dialgue in the presence of background music/effects. -It can go up to 30dB for testing purposes, but value of 6 is probably more reasonable. -It is recommended to ensure "Normalise levels on downmix" is enabled when boosting by large values to avoid clipping. - -Should work with Pi Sink (dvdplayer/paplayer) and omxplayer ---- - language/English/strings.po | 15 +++++++++++++++ - system/settings/settings.xml | 12 ++++++++++++ - .../Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp | 7 +++++++ - .../AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 6 ++++++ - xbmc/cores/omxplayer/OMXAudio.cpp | 6 ++++++ - 5 files changed, 46 insertions(+) - -diff --git a/language/English/strings.po b/language/English/strings.po -index a3b71e8..24f9636 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -16157,3 +16157,18 @@ msgstr "" - msgctxt "#38006" - msgid "Adjust PLL" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38007" -+msgid "Boost centre channel when downmixing" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38008" -+msgid "Increase this value to make the dialogue louder compared to background sounds when downmixing multichannel audio" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38009" -+msgid "%i dB" -+msgstr "" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 0db66a2..dbddcb6 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -2451,6 +2451,18 @@ - true - - -+ -+ 2 -+ 0 -+ -+ 0 -+ 1 -+ 30 -+ -+ -+ 38009 -+ -+ - - HAS_AE_QUALITY_LEVELS - 2 -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -index de188e7..449a500 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp -@@ -20,6 +20,7 @@ - - #include "cores/AudioEngine/Utils/AEUtil.h" - #include "ActiveAEResampleFFMPEG.h" -+#include "settings/Settings.h" - #include "utils/log.h" - - extern "C" { -@@ -105,6 +106,12 @@ bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, i - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - if (remapLayout) - { -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index 96f79b7..84505bf 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -162,6 +162,12 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - if (remapLayout) - { -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 7c07b57..ef4c3d4 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -633,6 +633,12 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } -+ int boost_center = CSettings::Get().GetInt("audiooutput.boostcenter"); -+ if (boost_center) -+ { -+ float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f); -+ av_opt_set_double(m_pContext, "center_mix_level", gain, 0); -+ } - - // stereo upmix - if (upmix && m_src_channels == 2 && m_dst_channels > 2) - -From 138475ea18c50ffb151d83b4498065f6fd177a4c Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 3 Oct 2014 18:38:07 +0100 -Subject: [PATCH 40/75] [omxcore] Skip out of flush on error - ---- - xbmc/linux/OMXCore.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp -index 4ae29ba..4caa304 100644 ---- a/xbmc/linux/OMXCore.cpp -+++ b/xbmc/linux/OMXCore.cpp -@@ -419,7 +419,7 @@ void COMXCoreComponent::FlushAll() - - void COMXCoreComponent::FlushInput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; -@@ -436,7 +436,7 @@ void COMXCoreComponent::FlushInput() - - void COMXCoreComponent::FlushOutput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; - -From 02de40bac468886dcb16dbbfc6175a1d7167ffb3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 3 Oct 2014 18:40:06 +0100 -Subject: [PATCH 41/75] [SinkPi] Handle multichannel layout more like OMXAudio - ---- - xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -index 89684e4..fd9a03d 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -@@ -92,9 +92,9 @@ static void SetAudioProps(bool stream_channels, uint32_t channel_map) - CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map); - } - --static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) -+static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough) - { -- unsigned int channels = format.m_channelLayout.Count(); -+ unsigned int channels = channelLayout.Count(); - uint32_t channel_map = 0; - if (passthrough) - return 0; -@@ -133,12 +133,12 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels - // but no BR BL channels, we use the wide map in order to open only the num of channels really - // needed. -- if (format.m_channelLayout.HasChannel(AE_CH_BL) && !format.m_channelLayout.HasChannel(AE_CH_SL)) -+ if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL)) - map = map_back; - - for (unsigned int i = 0; i < channels; ++i) - { -- AEChannel c = format.m_channelLayout[i]; -+ AEChannel c = channelLayout[i]; - unsigned int chan = 0; - if ((unsigned int)c < sizeof map_normal / sizeof *map_normal) - chan = map[(unsigned int)c]; -@@ -169,9 +169,9 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - 0xff, // 7 - 0x13, // 7.1 - }; -- uint8_t cea = format.m_channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; -+ uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; - if (cea == 0xff) -- CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, format.m_channelLayout.HasChannel(AE_CH_LFE), channels); -+ CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels); - - channel_map |= cea << 24; - -@@ -208,7 +208,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER / NUM_OMX_BUFFERS; - format.m_frameSamples = format.m_frames * channels; - -- SetAudioProps(m_passthrough, GetChannelMap(format, m_passthrough)); -+ SetAudioProps(m_passthrough, GetChannelMap(format.m_channelLayout, m_passthrough)); - - m_format = format; - m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); - -From 960a504f649cd7b044244c57baad37ed51e0254a Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 27 Oct 2014 15:23:51 +0000 -Subject: [PATCH 42/75] [rbp] Default extract thumbnails to false - -It can take 80 seconds for a single file on a Pi. It can cause crashes with out-of-memory errors. -It genereates a lot of support issues. Best to default to disabled and let users enable it if they must ---- - system/settings/rbp.xml | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 79853a8..4c2ef41 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -62,6 +62,16 @@ - - - -+ -+ -+ -+ false -+ -+ -+ false -+ -+ -+ -
- -
- -From 23830676efe433f73e747f68bebbea710bbeb88e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 11 Nov 2014 18:14:23 +0000 -Subject: [PATCH 43/75] [resamplepi] Try to report the same numbers as ffmpeg - ---- - .../cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index 84505bf..2b5bef2 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -544,9 +544,10 @@ int CActiveAEResamplePi::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t - - int64_t CActiveAEResamplePi::GetDelay(int64_t base) - { -- int ret = m_dst_rate ? 1000 * GetBufferedSamples() / m_dst_rate : 0; -+ int64_t ret = av_rescale_rnd(GetBufferedSamples(), m_dst_rate, base, AV_ROUND_UP); -+ - #ifdef DEBUG_VERBOSE -- CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, (int)ret); - #endif - return ret; - } -@@ -567,7 +568,7 @@ int CActiveAEResamplePi::GetBufferedSamples() - - int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) - { -- int ret = ((long long)src_samples * dst_rate + src_rate-1) / src_rate; -+ int ret = av_rescale_rnd(src_samples, dst_rate, src_rate, AV_ROUND_UP); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif -@@ -576,7 +577,7 @@ int CActiveAEResamplePi::CalcDstSampleCount(int src_samples, int dst_rate, int s - - int CActiveAEResamplePi::GetSrcBufferSize(int samples) - { -- int ret = 0; -+ int ret = av_samples_get_buffer_size(NULL, m_src_channels, samples, m_src_fmt, 1); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif -@@ -585,7 +586,7 @@ int CActiveAEResamplePi::GetSrcBufferSize(int samples) - - int CActiveAEResamplePi::GetDstBufferSize(int samples) - { -- int ret = CalcDstSampleCount(samples, m_dst_rate, m_src_rate); -+ int ret = av_samples_get_buffer_size(NULL, m_dst_channels, samples, m_dst_fmt, 1); - #ifdef DEBUG_VERBOSE - CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); - #endif - -From dff457e218d695b32a4ad362e9cd96595e677fd4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 11 Nov 2014 20:49:30 +0000 -Subject: [PATCH 44/75] [dvdplayer] New scheme for PLL adjustment for video - clock - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 40 +++++++++++++-------------------- - xbmc/cores/dvdplayer/DVDPlayerAudio.h | 2 ++ - 2 files changed, 18 insertions(+), 24 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index fe76917..4f25feb 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -113,7 +113,9 @@ CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent) - m_started = false; - m_silence = false; - m_resampleratio = 1.0; -- m_plladjust = 1.0f; -+ m_plladjust = 1.0; -+ m_last_plladjust = 1.0; -+ m_last_error = 0.0; - m_synctype = SYNC_DISCON; - m_setsynctype = SYNC_DISCON; - m_prevsynctype = -1; -@@ -192,6 +194,8 @@ void CDVDPlayerAudio::OpenStream( CDVDStreamInfo &hints, CDVDAudioCodec* codec ) - - m_error = 0; - m_errors.Flush(); -+ m_plladjust = 1.0; -+ m_last_plladjust = 1.0; - m_integral = 0; - m_prevskipped = false; - m_syncclock = true; -@@ -234,7 +238,6 @@ void CDVDPlayerAudio::CloseStream(bool bWaitForBuffers) - - // uninit queue - m_messageQueue.End(); -- - CLog::Log(LOGNOTICE, "Deleting audio codec"); - if (m_pAudioCodec) - { -@@ -475,9 +478,11 @@ void CDVDPlayerAudio::UpdatePlayerInfo() - //print the inverse of the resample ratio, since that makes more sense - //if the resample ratio is 0.5, then we're playing twice as fast - if (m_synctype == SYNC_RESAMPLE) -- s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio; -+ s << ", rr:" << fixed << setprecision(5) << 1.0 / m_resampleratio << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; -+ if (m_synctype == SYNC_SKIPDUP) -+ s << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; - if (m_synctype == SYNC_PLLADJUST) -- s << ", pll:" << fixed << setprecision(5) << 1.0 / m_plladjust; -+ s << ", pll:" << fixed << setprecision(5) << m_last_plladjust << ", err:" << fixed << setprecision(1) << m_last_error * 1e-3 << "ms"; - - s << ", att:" << fixed << setprecision(1) << log(GetCurrentAttenuation()) * 20.0f << " dB"; - -@@ -651,6 +656,7 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - m_pClock->Update(clock+error, absolute, 0.0, "CDVDPlayerAudio::HandleSyncError1"); - m_errors.Flush(); - m_error = 0; -+ m_plladjust = 1.0; - m_syncclock = false; - - return; -@@ -704,32 +710,18 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - proportional = m_error / DVD_TIME_BASE / proportionaldiv; - } - m_resampleratio = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s rr:%.5f error:%.3fms", __FUNCTION__, m_resampleratio, m_error * 1e-3); - } - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- //reset the integral on big errors, failsafe -- if (fabs(m_error) > DVD_TIME_BASE) -- m_integral = 0; -- else if (fabs(m_error) > DVD_MSEC_TO_TIME(5)) -- m_integral += m_error / DVD_TIME_BASE / INTEGRAL; -- -- double proportional = 0.0; -- -- //on big errors use more proportional -- if (fabs(m_error / DVD_TIME_BASE) > 0.0) -- { -- double proportionaldiv = PROPORTIONAL * (PROPREF / fabs(m_error / DVD_TIME_BASE)); -- if (proportionaldiv < PROPDIVMIN) proportionaldiv = PROPDIVMIN; -- else if (proportionaldiv > PROPDIVMAX) proportionaldiv = PROPDIVMAX; -- -- proportional = m_error / DVD_TIME_BASE / proportionaldiv; -- } -- m_plladjust = 1.0 / m_pClock->GetClockSpeed() + proportional + m_integral; -- double new_adjust = g_RBP.AdjustHDMIClock(m_plladjust); -- CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.4f (%.4f) proportional:%.4f integral:%.4f", __FUNCTION__, m_plladjust, new_adjust, proportional, m_integral); -+ double e = std::max(std::min(m_error, DVD_MSEC_TO_TIME(10)), -DVD_MSEC_TO_TIME(10)); -+ m_plladjust = 1.0 + e * 1.5e-8; -+ m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * 1.5e-8 ); - #endif - } -+ m_last_error = m_error; - } - } - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -index 02c64a0..37bf4bd 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h -@@ -233,6 +233,8 @@ class CDVDPlayerAudio : public CThread, public IDVDStreamPlayerAudio - double m_maxspeedadjust; - double m_resampleratio; //resample ratio when using SYNC_RESAMPLE, used for the codec info - double m_plladjust; // for display using SYNC_PLLADJUST -+ double m_last_error; // for display using SYNC_PLLADJUST -+ double m_last_plladjust; // for display using SYNC_PLLADJUST - - struct SInfo - { - -From 063facdddb659360288c377eb4a11aa25427ac74 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 15 Nov 2014 12:03:34 +0000 -Subject: [PATCH 45/75] [dvdplayer] Add lock for player creation - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 3 +++ - xbmc/cores/dvdplayer/DVDPlayer.h | 1 + - 2 files changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index cb512ed..a27291b 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -494,6 +494,7 @@ void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer, std:: - - void CDVDPlayer::CreatePlayers() - { -+ CSingleLock lock(m_players_lock); - #ifdef HAS_OMXPLAYER - if (m_omxplayer_mode && OMXPlayerUnsuitable(m_HasVideo, m_HasAudio, m_pDemuxer, m_pInputStream, m_SelectionStreams)) - { -@@ -523,6 +524,7 @@ void CDVDPlayer::CreatePlayers() - - void CDVDPlayer::DestroyPlayers() - { -+ CSingleLock lock(m_players_lock); - if (!m_players_created) - return; - delete m_dvdPlayerVideo; -@@ -4015,6 +4017,7 @@ double CDVDPlayer::GetQueueTime() - - void CDVDPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info) - { -+ CSingleLock lock(m_players_lock); - info.bitrate = m_dvdPlayerVideo->GetVideoBitrate(); - - std::string retVal; -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index ef64076..7ea6ea6 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -554,4 +554,5 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer - // omxplayer variables - struct SOmxPlayerState m_OmxPlayerState; - bool m_omxplayer_mode; // using omxplayer acceleration -+ CCriticalSection m_players_lock; - }; - -From ec8eebaab2cbc09a09f6435d51cfdf946368a2a3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 19 Nov 2014 13:29:43 +0000 -Subject: [PATCH 46/75] [dvdplayeraudio] Add advancedsetting for configuring - max pll adjustment - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 8 +++++--- - xbmc/settings/AdvancedSettings.cpp | 2 ++ - xbmc/settings/AdvancedSettings.h | 1 + - 3 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index 4f25feb..3cfe8ad 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -25,6 +25,7 @@ - #include "DVDCodecs/DVDCodecs.h" - #include "DVDCodecs/DVDFactoryCodec.h" - #include "settings/Settings.h" -+#include "settings/AdvancedSettings.h" - #include "video/VideoReferenceClock.h" - #include "utils/log.h" - #include "utils/TimeUtils.h" -@@ -715,10 +716,11 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- double e = std::max(std::min(m_error, DVD_MSEC_TO_TIME(10)), -DVD_MSEC_TO_TIME(10)); -- m_plladjust = 1.0 + e * 1.5e-8; -+ double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(10), 1.0), -1.0); -+ double adjust = g_advancedSettings.m_maxPllAdjust * 1e-6; -+ m_plladjust = 1.0 + e * adjust; - m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -- CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * 1.5e-8 ); -+ CLog::Log(LOGDEBUG, "CDVDPlayerAudio::%s pll:%.5f (%.5f) error:%.6f e:%.6f a:%f", __FUNCTION__, m_plladjust, m_last_plladjust, m_error, e * adjust, adjust ); - #endif - } - m_last_error = m_error; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index e9cd63a..3a266f8 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -108,6 +108,7 @@ void CAdvancedSettings::Initialize() - - m_audioHeadRoom = 0; - m_ac3Gain = 12.0f; -+ m_maxPllAdjust = 300; - m_audioApplyDrc = true; - m_dvdplayerIgnoreDTSinWAV = false; - -@@ -482,6 +483,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - if (pElement) - { - XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f); -+ XMLUtils::GetInt(pElement, "maxplladjust", m_maxPllAdjust, 0, 1000000); - XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12); - XMLUtils::GetString(pElement, "defaultplayer", m_audioDefaultPlayer); - // 101 on purpose - can be used to never automark as watched -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index ed91aba..eccc62f 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -137,6 +137,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - - int m_audioHeadRoom; - float m_ac3Gain; -+ int m_maxPllAdjust; - CStdString m_audioDefaultPlayer; - float m_audioPlayCountMinimumPercent; - bool m_dvdplayerIgnoreDTSinWAV; - -From 7f6ceceb2f69718018c768a6bdad004b8d8cbb88 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 19 Nov 2014 17:35:44 +0000 -Subject: [PATCH 47/75] [mmalrender] Skip some log message in bypass mode - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 03a05de..c0ff30d 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -298,6 +298,9 @@ int CMMALRenderer::GetImage(YV12Image *image, int source, bool readonly) - - void CMMALRenderer::ReleaseBuffer(int idx) - { -+ if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -+ return; -+ - #if defined(MMAL_DEBUG_VERBOSE) - CLog::Log(LOGDEBUG, "%s::%s - %d", CLASSNAME, __func__, idx); - #endif -@@ -366,13 +369,13 @@ void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - - void CMMALRenderer::FlipPage(int source) - { -+ if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -+ return; -+ - #if defined(MMAL_DEBUG_VERBOSE) - CLog::Log(LOGDEBUG, "%s::%s - %d", CLASSNAME, __func__, source); - #endif - -- if (!m_bConfigured || m_format == RENDER_FMT_BYPASS) -- return; -- - YUVBUFFER *buffer = &m_buffers[source]; - // we only want to upload frames once - if (buffer->flipindex++) - -From e1b8916187049e731b79ea1550b1d2bd393f4014 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 24 Nov 2014 21:24:25 +0000 -Subject: [PATCH 48/75] [mmalcodec] Avoid deinterlace for dvd menus for now - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index 6742e0e..a1f11e9 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -883,7 +883,7 @@ int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) - - bool deinterlace = m_interlace_mode != MMAL_InterlaceProgressive; - -- if (deinterlace_request == VS_DEINTERLACEMODE_OFF) -+ if (m_hints.stills || deinterlace_request == VS_DEINTERLACEMODE_OFF) - deinterlace = false; - else if (deinterlace_request == VS_DEINTERLACEMODE_FORCE) - deinterlace = true; - -From be0e902ee3257fb5a3ffc27cdeecad337b506c30 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 24 Nov 2014 22:07:25 +0000 -Subject: [PATCH 49/75] [dvdplayervideo] Prod decoder when in stills mode - -An asynchronous hardware decoder doesn't only produce output pictures when new packets arrive. -In dvd stills mode give it a chance to return pictures that weren't ready when frame was decoded. ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 46 ++++++++++++++++++++------------- - 1 file changed, 28 insertions(+), 18 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index f030e37..7a8fc10 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -324,7 +324,8 @@ void CDVDPlayerVideo::Process() - - while (!m_bStop) - { -- int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000; -+ bool bPictureWaiting = m_hints.stills && (m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE) & VC_PICTURE); -+ int iQueueTimeOut = (int)(bPictureWaiting ? 0 : (m_hints.stills || m_stalled) ? frametime / 4 : frametime * 10) / 1000; - int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0; - - CDVDMsg* pMsg; -@@ -341,27 +342,36 @@ void CDVDPlayerVideo::Process() - if( iPriority ) - continue; - -- //Okey, start rendering at stream fps now instead, we are likely in a stillframe -- if( !m_stalled ) -+ // check for picture waiting -+ if (bPictureWaiting) - { -- if(m_started) -- CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate); -- m_stalled = true; -- pts+= frametime*4; -+ // create a dummy demuxer packet to prod the decode logic -+ pMsg = new CDVDMsgDemuxerPacket(CDVDDemuxUtils::AllocateDemuxPacket(0), false); - } -- -- //Waiting timed out, output last picture -- if( picture.iFlags & DVP_FLAG_ALLOCATED ) -+ else - { -- //Remove interlaced flag before outputting -- //no need to output this as if it was interlaced -- picture.iFlags &= ~DVP_FLAG_INTERLACED; -- picture.iFlags |= DVP_FLAG_NOSKIP; -- OutputPicture(&picture, pts); -- pts+= frametime; -- } -+ //Okey, start rendering at stream fps now instead, we are likely in a stillframe -+ if( !m_stalled ) -+ { -+ if(m_started) -+ CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate); -+ m_stalled = true; -+ pts+= frametime*4; -+ } - -- continue; -+ //Waiting timed out, output last picture -+ if( picture.iFlags & DVP_FLAG_ALLOCATED ) -+ { -+ //Remove interlaced flag before outputting -+ //no need to output this as if it was interlaced -+ picture.iFlags &= ~DVP_FLAG_INTERLACED; -+ picture.iFlags |= DVP_FLAG_NOSKIP; -+ OutputPicture(&picture, pts); -+ pts+= frametime; -+ } -+ -+ continue; -+ } - } - - if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) - -From bb7e171804ee58a781715cce47c51fd53614c667 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 16:20:56 +0000 -Subject: [PATCH 50/75] [mmalcodec] Skip some setup that is not required when - closing - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 27 ++++++++++++---------- - 1 file changed, 15 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index a1f11e9..a11fa65 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -708,11 +708,11 @@ void CMMALVideo::Dispose() - { - // we are happy to exit, but let last shared pointer being deleted trigger the destructor - bool done = false; -+ m_finished = true; - Reset(); - pthread_mutex_lock(&m_output_mutex); - if (!m_output_busy) - done = true; -- m_finished = true; - pthread_mutex_unlock(&m_output_mutex); - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s dts_queue(%d) ready_queue(%d) busy_queue(%d) done:%d", CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, done); -@@ -941,19 +941,21 @@ void CMMALVideo::Reset(void) - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - -- if (m_dec_input) -+ if (m_dec_input && m_dec_input->is_enabled) - mmal_port_disable(m_dec_input); -- if (m_deint_connection) -+ if (m_deint_connection && m_deint_connection->is_enabled) - mmal_connection_disable(m_deint_connection); -- if (m_dec_output) -+ if (m_dec_output && m_dec_output->is_enabled) - mmal_port_disable(m_dec_output); -- if (m_dec_input) -- mmal_port_enable(m_dec_input, dec_input_port_cb); -- if (m_deint_connection) -- mmal_connection_enable(m_deint_connection); -- if (m_dec_output) -- mmal_port_enable(m_dec_output, dec_output_port_cb_static); -- -+ if (!m_finished) -+ { -+ if (m_dec_input) -+ mmal_port_enable(m_dec_input, dec_input_port_cb); -+ if (m_deint_connection) -+ mmal_connection_enable(m_deint_connection); -+ if (m_dec_output) -+ mmal_port_enable(m_dec_output, dec_output_port_cb_static); -+ } - // blow all ready video frames - bool old_drop_state = m_drop_state; - SetDropState(true); -@@ -967,7 +969,8 @@ void CMMALVideo::Reset(void) - if (!old_drop_state) - SetDropState(false); - -- SendCodecConfigData(); -+ if (!m_finished) -+ SendCodecConfigData(); - - m_startframe = false; - m_decoderPts = DVD_NOPTS_VALUE; - -From 5930f4130c9d65fd93e58e2e4982948d2040f52f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 16:31:56 +0000 -Subject: [PATCH 51/75] [languageinvoker] Reduce priority of python threads - ---- - xbmc/interfaces/generic/LanguageInvokerThread.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/xbmc/interfaces/generic/LanguageInvokerThread.cpp b/xbmc/interfaces/generic/LanguageInvokerThread.cpp -index 7b0d903..f92aa3e 100644 ---- a/xbmc/interfaces/generic/LanguageInvokerThread.cpp -+++ b/xbmc/interfaces/generic/LanguageInvokerThread.cpp -@@ -51,6 +51,11 @@ bool CLanguageInvokerThread::execute(const std::string &script, const std::vecto - m_args = arguments; - - Create(); -+ #ifdef TARGET_RASPBERRY_PI -+ /* low prio */ -+ SetPriority(GetPriority()-1); -+ #endif -+ - return true; - } - - -From cf8ad14e8e9035e4d29ca3e1b34c87a736418de0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Nov 2014 17:53:46 +0000 -Subject: [PATCH 52/75] [mmalcodec] Try reducing number of video frames - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index a11fa65..dd08c95 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -628,7 +628,7 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); - -- status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, NUM_BUFFERS); -+ status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, GetAllowedReferences()); - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -index 4f81bbd..79a4bfd 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.h -@@ -86,7 +86,7 @@ class CMMALVideo - virtual void Reset(void); - virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); - virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture); -- virtual unsigned GetAllowedReferences() { return NUM_BUFFERS; } -+ virtual unsigned GetAllowedReferences() { return 3; } - virtual void SetDropState(bool bDrop); - virtual const char* GetName(void) { return (const char*)m_pFormatName; } - virtual bool GetCodecStats(double &pts, int &droppedPics); - -From 8674e33d70b70cbdddb884150f9367913281c822 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 1 Dec 2014 17:31:00 +0000 -Subject: [PATCH 53/75] [mmalcodec] Ensure we have requested number of buffers - in non-accelerated case - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index c0ff30d..6d461bd 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -100,7 +100,7 @@ bool CMMALRenderer::init_vout(MMAL_ES_FORMAT_T *format) - return false; - } - -- m_vout_input->buffer_num = m_vout_input->buffer_num_recommended; -+ m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers); - m_vout_input->buffer_size = m_vout_input->buffer_size_recommended; - - status = mmal_port_enable(m_vout_input, vout_input_port_cb_static); - -From 9f8efa4d26372a517b28da10b46e761efb08fd82 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 3 Dec 2014 21:17:53 +0000 -Subject: [PATCH 54/75] [omxplayer] Add some info about hdmi sync to codec - overlay - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 8 +++++++- - xbmc/cores/omxplayer/OMXVideo.cpp | 24 ++++++++++++++++++++++++ - xbmc/cores/omxplayer/OMXVideo.h | 1 + - 3 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 605318c9..77b9461 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -618,12 +618,18 @@ void OMXPlayerVideo::SetSpeed(int speed) - - std::string OMXPlayerVideo::GetPlayerInfo() - { -+ double match = 0.0f, phase = 0.0f, pll = 0.0f; - std::ostringstream s; - s << "fr:" << fixed << setprecision(3) << m_fFrameRate; - s << ", vq:" << setw(2) << min(99,GetLevel()) << "%"; - s << ", dc:" << m_codecname; - s << ", Mb/s:" << fixed << setprecision(2) << (double)GetVideoBitrate() / (1024.0*1024.0); -- -+ if (m_omxVideo.GetPlayerInfo(match, phase, pll)) -+ { -+ s << ", match:" << fixed << setprecision(2) << match; -+ s << ", phase:" << fixed << setprecision(2) << phase; -+ s << ", pll:" << fixed << setprecision(5) << pll; -+ } - return s.str(); - } - -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index 99bb7eb..dea0e11 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -759,6 +759,30 @@ unsigned int COMXVideo::GetSize() - return m_omx_decoder.GetInputBufferSize(); - } - -+bool COMXVideo::GetPlayerInfo(double &match, double &phase, double &pll) -+{ -+ CSingleLock lock (m_critSection); -+ OMX_ERRORTYPE omx_err; -+ OMX_CONFIG_BRCMRENDERSTATSTYPE renderstats; -+ -+ if (!m_hdmi_clock_sync || !m_omx_render.IsInitialized()) -+ return false; -+ OMX_INIT_STRUCTURE(renderstats); -+ renderstats.nPortIndex = m_omx_render.GetInputPort(); -+ -+ omx_err = m_omx_render.GetParameter(OMX_IndexConfigBrcmRenderStats, &renderstats); -+ if(omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "COMXVideo::GetPlayerInfo error GetParameter OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); -+ return false; -+ } -+ match = renderstats.nMatch * 1e-6; -+ phase = (double)renderstats.nPhase / (double)renderstats.nPeriod; -+ pll = (double)renderstats.nPixelClock / (double)renderstats.nPixelClockNominal; -+ return true; -+} -+ -+ - int COMXVideo::Decode(uint8_t *pData, int iSize, double pts) - { - CSingleLock lock (m_critSection); -diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h -index c8fd5fb..9f26427 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.h -+++ b/xbmc/cores/omxplayer/OMXVideo.h -@@ -61,6 +61,7 @@ class COMXVideo - std::string GetDecoderName() { return m_video_codec_name; }; - void SetVideoRect(const CRect& SrcRect, const CRect& DestRect, RENDER_STEREO_MODE video_mode, RENDER_STEREO_MODE display_mode); - int GetInputBufferSize(); -+ bool GetPlayerInfo(double &match, double &phase, double &pll); - void SubmitEOS(); - bool IsEOS(); - bool SubmittedEOS() const { return m_submitted_eos; } - -From c3220a3ed4bf509aa691979a3e341574eb2b940b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 7 Dec 2014 15:21:18 +0000 -Subject: [PATCH 55/75] [omxplayer] Remove test of removed setting, avoids a - log message - ---- - xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -index 66014d4..c2da2d2 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -@@ -525,17 +525,17 @@ AEDataFormat OMXPlayerAudio::GetDataFormat(CDVDStreamInfo hints) - /* check our audio capabilties */ - - /* pathrought is overriding hw decode*/ -- if(hints.codec == AV_CODEC_ID_AC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_AC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate)) - { - dataFormat = AE_FMT_AC3; - m_passthrough = true; - } -- if(hints.codec == AV_CODEC_ID_EAC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate * 4) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_EAC3 && CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate * 4)) - { - dataFormat = AE_FMT_EAC3; - m_passthrough = true; - } -- if(hints.codec == AV_CODEC_ID_DTS && CAEFactory::SupportsRaw(AE_FMT_DTS, hints.samplerate) && !CSettings::Get().GetBool("audiooutput.dualaudio")) -+ if(hints.codec == AV_CODEC_ID_DTS && CAEFactory::SupportsRaw(AE_FMT_DTS, hints.samplerate)) - { - dataFormat = AE_FMT_DTS; - m_passthrough = true; - -From 38648532ae2482c5923009a8085665d721630b6d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 28 Dec 2014 19:13:51 +0000 -Subject: [PATCH 56/75] [omxplayer] Skip packet concatenation for WMAV2 files - -See: http://forum.kodi.tv/showthread.php?tid=212552 ---- - xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -index 94b673e..1a920f7 100644 ---- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -+++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -@@ -97,8 +97,8 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) - if (m_pCodecContext->request_channel_layout) - CLog::Log(LOGNOTICE,"COMXAudioCodecOMX::Open() Requesting channel layout of %x", (unsigned)m_pCodecContext->request_channel_layout); - -- // vorbis has variable sized planar output, so skip concatenation -- if (hints.codec == AV_CODEC_ID_VORBIS) -+ // vorbis and wma2v2 have variable sized planar output, so skip concatenation -+ if (hints.codec == AV_CODEC_ID_VORBIS || hints.codec == AV_CODEC_ID_WMAV2) - m_bNoConcatenate = true; - - if(m_pCodecContext->bits_per_coded_sample == 0) - -From a10151bb193d6c832c1700be0bbabedae32f8b80 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 31 Dec 2014 17:08:52 +0000 -Subject: [PATCH 57/75] filesystem: Make browsing into archives enbabled by - default on Pi - -This causes issues for people who scan library with archives disabled, then subsequently enable it. -The library has the .rar files in which don't play without removing and re-adding. - -We'll let people who don't use archives disable it manually ---- - system/settings/rbp.xml | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml -index 4c2ef41..3260465 100644 ---- a/system/settings/rbp.xml -+++ b/system/settings/rbp.xml -@@ -1,15 +1,5 @@ - - --
-- -- -- -- false -- -- -- --
-- -
- - - -From 1b25d3a54d15b90d76dcbcdceebb719ea18c24a3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 31 Dec 2014 16:03:32 +0000 -Subject: [PATCH 58/75] [PVR] Fix for slow metadata updates of recordings - -See: http://forum.kodi.tv/showthread.php?tid=210774 - -metaron identified that entering the recordings screen wih 850 recordings on a Pi -was taking about 40 seconds. The database is opened and closed for every recording, -and this dominates the time taken. With the database open/close pulled out of the loop -it now takes 1.4 seconds. - -squash: Changes suggested by Jalle19 ---- - xbmc/pvr/recordings/PVRRecording.cpp | 20 +++++++------------- - xbmc/pvr/recordings/PVRRecording.h | 4 +++- - xbmc/pvr/recordings/PVRRecordings.cpp | 27 +++++++++++++++++---------- - xbmc/pvr/recordings/PVRRecordings.h | 4 +++- - 4 files changed, 30 insertions(+), 25 deletions(-) - -diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp -index ccf2693..905f42c 100644 ---- a/xbmc/pvr/recordings/PVRRecording.cpp -+++ b/xbmc/pvr/recordings/PVRRecording.cpp -@@ -221,7 +221,7 @@ bool CPVRRecording::SetPlayCount(int count) - return true; - } - --void CPVRRecording::UpdateMetadata(void) -+void CPVRRecording::UpdateMetadata(CVideoDatabase &db) - { - if (m_bGotMetaData) - return; -@@ -231,20 +231,14 @@ void CPVRRecording::UpdateMetadata(void) - - if (!supportsPlayCount || !supportsLastPlayed) - { -- CVideoDatabase db; -- if (db.Open()) -+ if (!supportsPlayCount) - { -- if (!supportsPlayCount) -- { -- CFileItem pFileItem(*this); -- m_playCount = db.GetPlayCount(pFileItem); -- } -- -- if (!supportsLastPlayed) -- db.GetResumeBookMark(m_strFileNameAndPath, m_resumePoint); -- -- db.Close(); -+ CFileItem pFileItem(*this); -+ m_playCount = db.GetPlayCount(pFileItem); - } -+ -+ if (!supportsLastPlayed) -+ db.GetResumeBookMark(m_strFileNameAndPath, m_resumePoint); - } - - m_bGotMetaData = true; -diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h -index 91af28a..c9d9359 100644 ---- a/xbmc/pvr/recordings/PVRRecording.h -+++ b/xbmc/pvr/recordings/PVRRecording.h -@@ -39,6 +39,8 @@ - #include "video/VideoInfoTag.h" - #include "XBDateTime.h" - -+class CVideoDatabase; -+ - namespace PVR - { - class CPVRRecording; -@@ -149,7 +151,7 @@ namespace PVR - * @brief Get the resume point and play count from the database if the - * client doesn't handle it itself. - */ -- void UpdateMetadata(void); -+ void UpdateMetadata(CVideoDatabase &db); - - /*! - * @brief Update this tag with the contents of the given tag. -diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp -index 34ef40f..7741efc 100644 ---- a/xbmc/pvr/recordings/PVRRecordings.cpp -+++ b/xbmc/pvr/recordings/PVRRecordings.cpp -@@ -43,7 +43,14 @@ CPVRRecordings::CPVRRecordings(void) : - m_iLastId(0), - m_bGroupItems(true) - { -+ m_database.Open(); -+} - -+CPVRRecordings::~CPVRRecordings() -+{ -+ Clear(); -+ if (m_database.IsOpen()) -+ m_database.Close(); - } - - void CPVRRecordings::UpdateFromClients(void) -@@ -119,8 +126,9 @@ void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList - strFilePath = StringUtils::Format("pvr://recordings/%s/%s/", strUseBase.c_str(), strCurrent.c_str()); - - CFileItemPtr pFileItem; -- current->UpdateMetadata(); -- -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); -+ - if (!results->Contains(strFilePath)) - { - pFileItem.reset(new CFileItem(strCurrent, true)); -@@ -250,8 +258,7 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) - { - bool bResult = false; - -- CVideoDatabase database; -- if (database.Open()) -+ if (m_database.IsOpen()) - { - bResult = true; - -@@ -291,15 +298,13 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) - // Clear resume bookmark - if (count > 0) - { -- database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); -+ m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); - recording->SetLastPlayedPosition(0); - } - -- database.SetPlayCount(*pItem, count); -+ m_database.SetPlayCount(*pItem, count); - } - } -- -- database.Close(); - } - - return bResult; -@@ -330,7 +335,8 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite - if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory)) - continue; - -- current->UpdateMetadata(); -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); - CFileItemPtr pFileItem(new CFileItem(*current)); - pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); - pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); -@@ -369,7 +375,8 @@ void CPVRRecordings::GetAll(CFileItemList &items) - for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) - { - CPVRRecordingPtr current = it->second; -- current->UpdateMetadata(); -+ if (m_database.IsOpen()) -+ current->UpdateMetadata(m_database); - - CFileItemPtr pFileItem(new CFileItem(*current)); - pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); -diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h -index 6b8cb14..2bcc834 100644 ---- a/xbmc/pvr/recordings/PVRRecordings.h -+++ b/xbmc/pvr/recordings/PVRRecordings.h -@@ -24,6 +24,7 @@ - #include "threads/Thread.h" - #include "utils/Observer.h" - #include "video/VideoThumbLoader.h" -+#include "video/VideoDatabase.h" - - #define PVR_ALL_RECORDINGS_PATH_EXTENSION "-1" - -@@ -40,6 +41,7 @@ namespace PVR - PVR_RECORDINGMAP m_recordings; - unsigned int m_iLastId; - bool m_bGroupItems; -+ CVideoDatabase m_database; - - virtual void UpdateFromClients(void); - virtual std::string TrimSlashes(const std::string &strOrig) const; -@@ -58,7 +60,7 @@ namespace PVR - - public: - CPVRRecordings(void); -- virtual ~CPVRRecordings(void) { Clear(); }; -+ virtual ~CPVRRecordings(void); - - int Load(); - void Unload(); - -From 1da99439c1b3502111974ddce6f033b9d59675a0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Dec 2014 17:20:00 +0000 -Subject: [PATCH 59/75] [dvdplayer] Allow pll adjustment to go higher, but tail - off more gradually - ---- - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 2 +- - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -index 3cfe8ad..5db48a8 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp -@@ -716,7 +716,7 @@ void CDVDPlayerAudio::HandleSyncError(double duration) - else if (m_synctype == SYNC_PLLADJUST) - { - #if defined(TARGET_RASPBERRY_PI) -- double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(10), 1.0), -1.0); -+ double e = std::max(std::min(m_error / DVD_MSEC_TO_TIME(50), 1.0), -1.0); - double adjust = g_advancedSettings.m_maxPllAdjust * 1e-6; - m_plladjust = 1.0 + e * adjust; - m_last_plladjust = g_RBP.AdjustHDMIClock(m_plladjust); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 3a266f8..f007f42 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -108,7 +108,7 @@ void CAdvancedSettings::Initialize() - - m_audioHeadRoom = 0; - m_ac3Gain = 12.0f; -- m_maxPllAdjust = 300; -+ m_maxPllAdjust = 1000; - m_audioApplyDrc = true; - m_dvdplayerIgnoreDTSinWAV = false; - - -From 884b78280878f6ab25f51f3e0b3ab49376320219 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 11 Dec 2014 17:00:57 +0000 -Subject: [PATCH 60/75] Fix for UI not showing both extractflags and - extractthumb - ---- - language/English/strings.po | 11 ++++++++--- - system/settings/settings.xml | 10 +++++----- - 2 files changed, 13 insertions(+), 8 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 24f9636..c54cb25 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -10790,7 +10790,7 @@ msgstr "" - - #: system/settings/settings.xml - msgctxt "#20433" --msgid "Extract thumbnails and video information" -+msgid "Extract video information from files" - msgstr "" - - #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp -@@ -14164,7 +14164,7 @@ msgstr "" - #. Description of setting "Videos -> File lists -> Extract thumbnails and video information" with label #20433 - #: system/settings/settings.xml - msgctxt "#36178" --msgid "Extract thumbnails and metadata information such as codec and aspect ratio from videos." -+msgid "Extract metadata information such as codec and aspect ratio from videos." - msgstr "" - - #. Description of setting "Videos -> File lists -> Replace file names with library titles" with label #20419 -@@ -14176,7 +14176,7 @@ msgstr "" - #. Description of setting "Videos -> File lists -> Extract thumbnails and video information" with label #20433 - #: system/settings/settings.xml - msgctxt "#36180" --msgid "Extract thumbnails and information, such as codecs and aspect ratio, to display in Library Mode." -+msgid "Extract thumbnails, to display in Library Mode." - msgstr "" - - #: system/settings/settings.xml -@@ -16172,3 +16172,8 @@ msgstr "" - msgctxt "#38009" - msgid "%i dB" - msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#38015" -+msgid "Extract thumbnails from video files" -+msgstr "" -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index dbddcb6..756475f 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -802,17 +802,17 @@ - - - -- 1 -+ 3 - true - - -- -- 1 -+ -+ 3 - true - - -- -- 4 -+ -+ 1 - true - - - -From be43189486ef1b1886d116e8d875d7e1548c6dee Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 26 Jan 2015 19:24:17 +0000 -Subject: [PATCH 61/75] Fix for occasinal heap corruption with font cache - -See: PR 4143 issuecomment-71114810 ---- - xbmc/guilib/GUIFontCache.h | 10 +++++++++- - xbmc/guilib/GUIFontTTF.cpp | 43 ++++++++++++++++++++++++++++++++----------- - 2 files changed, 41 insertions(+), 12 deletions(-) - -diff --git a/xbmc/guilib/GUIFontCache.h b/xbmc/guilib/GUIFontCache.h -index ff766bf..575ee7d 100644 ---- a/xbmc/guilib/GUIFontCache.h -+++ b/xbmc/guilib/GUIFontCache.h -@@ -38,6 +38,7 @@ - #include "boost/multi_index/sequenced_index.hpp" - #include "boost/multi_index/hashed_index.hpp" - #include "boost/multi_index/member.hpp" -+#include "boost/shared_ptr.hpp" - - #include "TransformMatrix.h" - -@@ -201,7 +202,14 @@ struct CGUIFontCacheStaticPosition - void UpdateWithOffsets(const CGUIFontCacheStaticPosition &cached, bool scrolling) {} - }; - --typedef std::vector CGUIFontCacheStaticValue; -+struct CGUIFontCacheStaticValue : public boost::shared_ptr > -+{ -+ void clear() -+ { -+ if (*this) -+ (*this)->clear(); -+ } -+}; - - inline bool Match(const CGUIFontCacheStaticPosition &a, const TransformMatrix &a_m, - const CGUIFontCacheStaticPosition &b, const TransformMatrix &b_m, -diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp -index 7d4fc88..4110546 100644 ---- a/xbmc/guilib/GUIFontTTF.cpp -+++ b/xbmc/guilib/GUIFontTTF.cpp -@@ -30,6 +30,7 @@ - #include "URL.h" - #include "filesystem/File.h" - #include "threads/SystemClock.h" -+#include "boost/make_shared.hpp" - - #include - -@@ -357,6 +358,7 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - { - Begin(); - -+ uint32_t rawAlignment = alignment; - bool dirtyCache; - bool hardwareClipping = g_Windowing.ScissorsCanEffectClipping(); - CGUIFontCacheStaticPosition staticPos(x, y); -@@ -376,8 +378,8 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - XbmcThreads::SystemClockMillis(), - dirtyCache) : - unusedVertexBuffer; -- std::vector tempVertices; -- std::vector &vertices = hardwareClipping ? -+ boost::shared_ptr > tempVertices = boost::make_shared >(); -+ boost::shared_ptr > &vertices = hardwareClipping ? - tempVertices : - m_staticCache.Lookup(staticPos, - colors, text, -@@ -467,7 +469,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, vertices); -+ RenderCharacter(startX + cursorX, startY, period, color, !scrolling, *tempVertices); - cursorX += period->advance; - } - break; -@@ -476,7 +478,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, vertices); -+ RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, *tempVertices); - if ( alignment & XBFONT_JUSTIFIED ) - { - if ((*pos & 0xffff) == L' ') -@@ -489,17 +491,36 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors - } - if (hardwareClipping) - { -- CVertexBuffer newVertexBuffer = CreateVertexBuffer(tempVertices); -+ CVertexBuffer &vertexBuffer = m_dynamicCache.Lookup(dynamicPos, -+ colors, text, -+ rawAlignment, maxPixelWidth, -+ scrolling, -+ XbmcThreads::SystemClockMillis(), -+ dirtyCache); -+ CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices); - vertexBuffer = newVertexBuffer; - m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertexBuffer, g_graphicsContext.GetClipRegion())); - } -+ else -+ { -+ m_staticCache.Lookup(staticPos, -+ colors, text, -+ rawAlignment, maxPixelWidth, -+ scrolling, -+ XbmcThreads::SystemClockMillis(), -+ dirtyCache) = *static_cast(&tempVertices); -+ /* Append the new vertices to the set collected since the first Begin() call */ -+ m_vertex.insert(m_vertex.end(), tempVertices->begin(), tempVertices->end()); -+ } -+ } -+ else -+ { -+ if (hardwareClipping) -+ m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, g_graphicsContext.GetClipRegion())); -+ else -+ /* Append the vertices from the cache to the set collected since the first Begin() call */ -+ m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end()); - } -- else if (hardwareClipping) -- m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, g_graphicsContext.GetClipRegion())); -- 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(); - } - -From 232c2dc0a1a51436a44678437ce55080ff124914 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 4 Feb 2015 22:02:33 +0000 -Subject: [PATCH 62/75] [omxplayer] Avoid extra frame allocation when - deinterlace might be enabled - -Requires updated firmware ---- - xbmc/cores/omxplayer/OMXVideo.cpp | 16 ---------------- - 1 file changed, 16 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index dea0e11..55e16c4 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -610,22 +610,6 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, EDEINTERLACEMODE de - return false; - } - -- if (m_deinterlace_request != VS_DEINTERLACEMODE_OFF) -- { -- // the deinterlace component requires 3 additional video buffers in addition to the DPB (this is normally 2). -- OMX_PARAM_U32TYPE extra_buffers; -- OMX_INIT_STRUCTURE(extra_buffers); -- extra_buffers.nU32 = 3; -- -- omx_err = m_omx_decoder.SetParameter(OMX_IndexParamBrcmExtraBuffers, &extra_buffers); -- if(omx_err != OMX_ErrorNone) -- { -- CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamBrcmExtraBuffers omx_err(0x%08x)\n", omx_err); -- return false; -- } -- } -- -- - // broadcom omx entension: - // When enabled, the timestamp fifo mode will change the way incoming timestamps are associated with output images. - // In this mode the incoming timestamps get used without re-ordering on output images. - -From 7e18dad8c601498c8d15b2d916b0524716b49f11 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 18 Jan 2015 16:45:51 +0000 -Subject: [PATCH 63/75] [rbp] Enable error concealment by default - -Firmware now supports parsing SEI recovery points meaning streams without -IDR frames don't get discarded completely when error concealment is enabled. - -This should avoid the garbled frames that appear when seeking non-indexed (e.g. mpegts) files. -Requires updated firmware ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp | 2 +- - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -index dd08c95..1bfec44 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/MMALCodec.cpp -@@ -623,7 +623,7 @@ bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVide - - error_concealment.hdr.id = MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT; - error_concealment.hdr.size = sizeof(MMAL_PARAMETER_BOOLEAN_T); -- error_concealment.enable = MMAL_FALSE; -+ error_concealment.enable = g_advancedSettings.m_omxDecodeStartWithValidFrame; - status = mmal_port_parameter_set(m_dec_input, &error_concealment.hdr); - if (status != MMAL_SUCCESS) - CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index f007f42..9f00cf4 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -117,7 +117,7 @@ void CAdvancedSettings::Initialize() - m_limiterRelease = 0.1f; - - m_omxHWAudioDecode = false; -- m_omxDecodeStartWithValidFrame = false; -+ m_omxDecodeStartWithValidFrame = true; - - m_karaokeSyncDelayCDG = 0.0f; - m_karaokeSyncDelayLRC = 0.0f; - -From feca09cb89fda6814030d0a0a62d92400625bfe0 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 26 Jan 2015 17:54:07 +0000 -Subject: [PATCH 64/75] [mmalrenderer] Avoid grabbing the g_graphicsContext - lock - it can deadlock - ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 6d461bd..11a6f10 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -404,7 +404,6 @@ void CMMALRenderer::FlipPage(int source) - - unsigned int CMMALRenderer::PreInit() - { -- CSingleLock lock(g_graphicsContext); - m_bConfigured = false; - UnInit(); - -@@ -434,7 +433,6 @@ void CMMALRenderer::ReleaseBuffers() - - void CMMALRenderer::UnInit() - { -- CSingleLock lock(g_graphicsContext); - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - if (m_vout) - { - -From 348995898891377b83f550f25fc657d167eecdde Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 15 Feb 2015 14:06:12 +0000 -Subject: [PATCH 65/75] [mmal] Use libmpeg2 when mpeg2 codec licence is not - available - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index bea5e4f..e4f59d7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -49,6 +49,9 @@ - #include "Video/DVDVideoCodecAndroidMediaCodec.h" - #include "android/activity/AndroidFeatures.h" - #endif -+#if defined(HAS_MMAL) -+#include "linux/RBP.h" -+#endif - #include "Audio/DVDAudioCodecFFmpeg.h" - #include "Audio/DVDAudioCodecPassthrough.h" - #include "Overlay/DVDOverlayCodecSSA.h" -@@ -196,7 +199,7 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - - #if defined(HAS_MMAL) - // mmal can handle dvd playback including stills -- if (!CSettings::Get().GetBool("videoplayer.usemmal")) -+ if (!CSettings::Get().GetBool("videoplayer.usemmal") || !g_RBP.GetCodecMpg2()) - #endif - if (hint.stills && (hint.codec == AV_CODEC_ID_MPEG2VIDEO || hint.codec == AV_CODEC_ID_MPEG1VIDEO)) - { - -From 232f0dafea51c319364b314b2e2277429c5bcdd7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 28 Feb 2015 22:34:52 +0000 -Subject: [PATCH 66/75] [mmalrender] Fix for hang on shutdown - -mmal_queue_push doesn't allow null pointers, so use a unique packet for signalling quit ---- - xbmc/cores/VideoRenderers/MMALRenderer.cpp | 5 +++-- - xbmc/cores/VideoRenderers/MMALRenderer.h | 2 ++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -index 11a6f10..a70eeb0 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp -@@ -132,7 +132,7 @@ bool CMMALRenderer::init_vout(MMAL_ES_FORMAT_T *format) - void CMMALRenderer::Process() - { - MMAL_BUFFER_HEADER_T *buffer; -- while (buffer = mmal_queue_wait(m_release_queue), buffer) -+ while (buffer = mmal_queue_wait(m_release_queue), buffer && buffer != &m_quit_packet) - { - CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data; - omvb->Release(); -@@ -148,6 +148,7 @@ CMMALRenderer::CMMALRenderer() - m_vout_input = NULL; - m_vout_input_pool = NULL; - memset(m_buffers, 0, sizeof m_buffers); -+ mmal_buffer_header_reset(&m_quit_packet); - m_release_queue = mmal_queue_create(); - Create(); - } -@@ -156,7 +157,7 @@ CMMALRenderer::~CMMALRenderer() - { - CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); - // shutdown thread -- mmal_queue_put(m_release_queue, NULL); -+ mmal_queue_put(m_release_queue, &m_quit_packet); - m_sync.Wait(); - mmal_queue_destroy(m_release_queue); - UnInit(); -diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.h b/xbmc/cores/VideoRenderers/MMALRenderer.h -index 8ca0b94..a5c248c 100644 ---- a/xbmc/cores/VideoRenderers/MMALRenderer.h -+++ b/xbmc/cores/VideoRenderers/MMALRenderer.h -@@ -116,6 +116,8 @@ class CMMALRenderer : public CBaseRenderer, public CThread - - MMAL_QUEUE_T *m_release_queue; - CEvent m_sync; -+ MMAL_BUFFER_HEADER_T m_quit_packet; -+ - bool init_vout(MMAL_ES_FORMAT_T *m_format); - void ReleaseBuffers(); - }; - -From 69fa623c46a38f94b8a4e3eabc5cd108bc55b925 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 27 Feb 2015 19:07:17 +0000 -Subject: [PATCH 67/75] [omxplayer] Attempt to fix missing subtitles after seek - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 77b9461..2a3619f 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -295,7 +295,7 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - const double preroll = DVD_MSEC_TO_TIME(100); - double media_pts = m_av_clock->OMXMediaTime(); - -- if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts + preroll <= m_nextOverlay) -+ if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts != 0.0 && media_pts + preroll <= m_nextOverlay) - return; - - int buffer = g_renderManager.WaitForBuffer(CThread::m_bStop); - -From f12f1a04a761c73ed1bb1fd49caef5246743f5b4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 1 Mar 2015 14:49:12 +0000 -Subject: [PATCH 69/75] [omxplayer] Fix for volume being treated as a linear - scale - -The volume in kodi is actually 0.0=-60dB to 1.0=0dB. omxplayer was treating this as a linear scale. -That's correct for 0.0 and 1.0, but too loud for 0.5. - -The fix has been tested with white noise sample and decibel meter smartphone app, and now omxplayer and -dvdplayer produce the same output ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index ef4c3d4..c16ae2e 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -1056,6 +1056,8 @@ bool COMXAudio::ApplyVolume(void) - return false; - - float fVolume = m_Mute ? VOLUME_MINIMUM : m_CurrentVolume; -+ // need to convert a log scale of 0.0=-60dB, 1.0=0dB to a linear scale (0.0=silence, 1.0=full) -+ fVolume = CAEUtil::GainToScale(CAEUtil::PercentToGain(fVolume)); - - // the analogue volume is too quiet for some. Allow use of an advancedsetting to boost this (at risk of distortion) (deprecated) - double gain = pow(10, (g_advancedSettings.m_ac3Gain - 12.0f) / 20.0); - -From 6da1be424f1c9c115352e2812a96f038bef188c5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 24 Feb 2015 00:09:19 +0000 -Subject: [PATCH 70/75] [omxplayer] Limit subtitle updates to 10fps to avoid - stuttering with closed captions - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 2a3619f..6ae404df 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -221,7 +221,7 @@ double OMXPlayerVideo::NextOverlay(double pts) - else if (delta_stop > 0.0 && (min_delta == DVD_NOPTS_VALUE || delta_stop < min_delta)) - min_delta = delta_stop; - } -- return min_delta == DVD_NOPTS_VALUE ? pts+DVD_MSEC_TO_TIME(500) : pts+min_delta; -+ return min_delta == DVD_NOPTS_VALUE ? pts+DVD_MSEC_TO_TIME(500) : pts+std::max(min_delta, DVD_MSEC_TO_TIME(100)); - } - - -@@ -305,9 +305,9 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - double subtitle_pts = m_nextOverlay; - double time = subtitle_pts != DVD_NOPTS_VALUE ? subtitle_pts - media_pts : 0.0; - -- m_nextOverlay = NextOverlay(media_pts); -+ m_nextOverlay = NextOverlay(media_pts + preroll); - -- ProcessOverlays(media_pts); -+ ProcessOverlays(media_pts + preroll); - - time += m_av_clock->GetAbsoluteClock(); - g_renderManager.FlipPage(CThread::m_bStop, time/DVD_TIME_BASE); - -From 2563cbc8489b33d5a1067d439683e41c2d090496 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 17 Mar 2015 20:52:28 +0000 -Subject: [PATCH 71/75] [omxplayer] Allow HDMI output to work when unsupported - ALSA card is selected - -See: http://forum.kodi.tv/showthread.php?tid=221118&pid=1958062#pid1958062 - -Basically omxplayer doesn't support ALSA and can only drive HDMI or the analogue output. -In the past users have made use of this fact to effictively get HDMI output for videos, and ALSA output for music. - -In some of the code restructuring using omxplayer with ALSA enabled no longer works - you just get errors in the log. -A trivial change allows this to work again ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index c16ae2e..95db68c 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -128,7 +128,7 @@ bool COMXAudio::PortSettingsChanged() - if(!m_omx_render_analog.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; - } -- if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:HDMI") -+ if (CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Both" || CSettings::Get().GetString("audiooutput.audiodevice") != "PI:Analogue") - { - if(!m_omx_render_hdmi.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit)) - return false; - -From a960108065b8effd7673c89542392e8ff600c548 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 27 Mar 2015 22:20:39 +0000 -Subject: [PATCH 75/75] Revert "[omxplayer] Attempt to fix missing subtitles - after seek" - -This reverts commit cb2e41c82fd58fd87ddfd632b847fef5e287b97e. ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 6ae404df..028b8cd 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -295,7 +295,7 @@ void OMXPlayerVideo::Output(double pts, bool bDropPacket) - const double preroll = DVD_MSEC_TO_TIME(100); - double media_pts = m_av_clock->OMXMediaTime(); - -- if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts != 0.0 && media_pts + preroll <= m_nextOverlay) -+ if (m_nextOverlay != DVD_NOPTS_VALUE && media_pts + preroll <= m_nextOverlay) - return; - - int buffer = g_renderManager.WaitForBuffer(CThread::m_bStop); diff --git a/projects/WeTek_Play/patches/kodi/0003-Enable-true-1920x1080-output-without-upscaling-on-Am.patch b/projects/WeTek_Play/patches/kodi/0003-Enable-true-1920x1080-output-without-upscaling-on-Am.patch index 4a060920cf..c0fef5357b 100644 --- a/projects/WeTek_Play/patches/kodi/0003-Enable-true-1920x1080-output-without-upscaling-on-Am.patch +++ b/projects/WeTek_Play/patches/kodi/0003-Enable-true-1920x1080-output-without-upscaling-on-Am.patch @@ -1,19 +1,19 @@ -From 15445c00a63921fde8c22a9229186d7cb8117778 Mon Sep 17 00:00:00 2001 +From 001de52ae30377edcd03ba050c454255da99cb07 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Wed, 16 Apr 2014 23:08:58 +0300 Subject: [PATCH 03/17] Enable true 1920x1080 output without upscaling on Amlogic-based devices. --- - xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp | 44 +++++++++++++++++++++++++-- - xbmc/windowing/egl/EGLNativeTypeAmlogic.h | 3 ++ + xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp | 44 +++++++++++++++++++++++++++-- + xbmc/windowing/egl/EGLNativeTypeAmlogic.h | 3 ++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -index 7064836..362db6d 100644 +index f2073cb..3c7a8e6 100644 --- a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -@@ -87,9 +87,12 @@ bool CEGLNativeTypeAmlogic::CreateNativeWindow() +@@ -88,9 +88,12 @@ bool CEGLNativeTypeAmlogic::CreateNativeWindow() if (!nativeWindow) return false; @@ -28,7 +28,7 @@ index 7064836..362db6d 100644 return true; #else return false; -@@ -134,6 +137,12 @@ bool CEGLNativeTypeAmlogic::GetNativeResolution(RESOLUTION_INFO *res) const +@@ -135,6 +138,12 @@ bool CEGLNativeTypeAmlogic::GetNativeResolution(RESOLUTION_INFO *res) const bool CEGLNativeTypeAmlogic::SetNativeResolution(const RESOLUTION_INFO &res) { @@ -41,19 +41,19 @@ index 7064836..362db6d 100644 switch((int)(0.5 + res.fRefreshRate)) { default: -@@ -219,7 +228,10 @@ bool CEGLNativeTypeAmlogic::SetDisplayResolution(const char *resolution) - CStdString mode = resolution; +@@ -220,7 +229,10 @@ bool CEGLNativeTypeAmlogic::SetDisplayResolution(const char *resolution) + std::string mode = resolution; // switch display resolution - aml_set_sysfs_str("/sys/class/display/mode", mode.c_str()); + SysfsUtils::SetString("/sys/class/display/mode", mode.c_str()); - SetupVideoScaling(mode.c_str()); + + RESOLUTION_INFO res; -+ aml_mode_to_resolution(mode, &res); ++ aml_mode_to_resolution(mode.c_str(), &res); + SetFramebufferResolution(res); return true; } -@@ -304,3 +316,29 @@ void CEGLNativeTypeAmlogic::DisableFreeScale() +@@ -305,3 +317,29 @@ void CEGLNativeTypeAmlogic::DisableFreeScale() close(fd0); } } @@ -97,5 +97,5 @@ index cc34ff7..781a153 100644 std::string m_framebuffer_name; }; -- -1.7.10.4 +2.1.4 diff --git a/projects/WeTek_Play/patches/kodi/0004-Add-support-for-retrieval-of-CPU-temperature-on-Amlo.patch b/projects/WeTek_Play/patches/kodi/0004-Add-support-for-retrieval-of-CPU-temperature-on-Amlo.patch index 031261430e..b88fdf523e 100644 --- a/projects/WeTek_Play/patches/kodi/0004-Add-support-for-retrieval-of-CPU-temperature-on-Amlo.patch +++ b/projects/WeTek_Play/patches/kodi/0004-Add-support-for-retrieval-of-CPU-temperature-on-Amlo.patch @@ -1,26 +1,17 @@ -From 904bd346a5b7ca168a1137768dae5c9c731d8127 Mon Sep 17 00:00:00 2001 +From 41fa8f5e4ad5498417a8de12031003dc1c13ea19 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Tue, 22 Jul 2014 12:18:29 +0300 -Subject: [PATCH 04/17] Add support for retrieval of CPU temperature on - Amlogic +Subject: [PATCH 04/17] Add support for retrieval of CPU temperature on Amlogic --- - xbmc/utils/CPUInfo.cpp | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) + xbmc/utils/CPUInfo.cpp | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/xbmc/utils/CPUInfo.cpp b/xbmc/utils/CPUInfo.cpp -index 71aa745..f80e7ba 100644 +index 5f5bf80..c840ab6 100644 --- a/xbmc/utils/CPUInfo.cpp +++ b/xbmc/utils/CPUInfo.cpp -@@ -18,6 +18,7 @@ - * - */ - -+#include "system.h" - #include "CPUInfo.h" - #include "Temperature.h" - #include -@@ -95,6 +96,10 @@ +@@ -97,6 +97,10 @@ #include "settings/AdvancedSettings.h" #include "utils/StringUtils.h" @@ -31,7 +22,7 @@ index 71aa745..f80e7ba 100644 using namespace std; // In milliseconds -@@ -265,6 +270,10 @@ CCPUInfo::CCPUInfo(void) +@@ -267,6 +271,10 @@ CCPUInfo::CCPUInfo(void) m_fProcTemperature = fopen("/sys/class/hwmon/hwmon0/temp1_input", "r"); if (m_fProcTemperature == NULL) m_fProcTemperature = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); // On Raspberry PIs @@ -42,7 +33,7 @@ index 71aa745..f80e7ba 100644 m_fCPUFreq = fopen ("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r"); if (!m_fCPUFreq) -@@ -607,7 +616,10 @@ bool CCPUInfo::getTemperature(CTemperature& temperature) +@@ -609,7 +617,10 @@ bool CCPUInfo::getTemperature(CTemperature& temperature) if (!ret) { ret = fscanf(m_fProcTemperature, "%d", &value); @@ -55,5 +46,5 @@ index 71aa745..f80e7ba 100644 ret++; } -- -1.7.10.4 +2.1.4 diff --git a/projects/WeTek_Play/patches/kodi/0006-Fix-the-issue-when-the-video-display-is-disabled-aft.patch b/projects/WeTek_Play/patches/kodi/0006-Fix-the-issue-when-the-video-display-is-disabled-aft.patch index a55ac3c36a..8c46e90bbc 100644 --- a/projects/WeTek_Play/patches/kodi/0006-Fix-the-issue-when-the-video-display-is-disabled-aft.patch +++ b/projects/WeTek_Play/patches/kodi/0006-Fix-the-issue-when-the-video-display-is-disabled-aft.patch @@ -1,19 +1,19 @@ -From 56d4e85af28b0d65859fb84bb6b6582bf3c71a7b Mon Sep 17 00:00:00 2001 +From 0fdd487aa04abdbf65402b720e363e4890d98ad1 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Tue, 29 Jul 2014 10:31:07 +0300 Subject: [PATCH 06/17] Fix the issue when the video display is disabled after a resolution change --- - xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp | 55 +-------------------------- - xbmc/windowing/egl/EGLNativeTypeAmlogic.h | 1 - + xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp | 55 +---------------------------- + xbmc/windowing/egl/EGLNativeTypeAmlogic.h | 1 - 2 files changed, 1 insertion(+), 55 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -index 8e4bf37..2d5c4a1 100644 +index c9a3bd8..6b38889 100644 --- a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -@@ -65,7 +65,7 @@ void CEGLNativeTypeAmlogic::Initialize() +@@ -66,7 +66,7 @@ void CEGLNativeTypeAmlogic::Initialize() aml_permissions(); aml_cpufreq_min(true); aml_cpufreq_max(true); @@ -22,52 +22,52 @@ index 8e4bf37..2d5c4a1 100644 } void CEGLNativeTypeAmlogic::Destroy() { -@@ -277,64 +277,11 @@ void CEGLNativeTypeAmlogic::SetupVideoScaling(const char *mode) - aml_set_sysfs_int("/sys/class/graphics/fb0/blank", 0); +@@ -278,64 +278,11 @@ void CEGLNativeTypeAmlogic::SetupVideoScaling(const char *mode) + SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", 0); } -void CEGLNativeTypeAmlogic::EnableFreeScale() -{ - // enable OSD free scale using frame buffer size of 720p -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_height", 720); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_height", 720); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 0); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 0); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_width", 1280); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_height", 720); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_width", 1280); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_height", 720); - - // enable video free scale (scaling to 1920x1080 with frame buffer size 1280x720) -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 0); -- aml_set_sysfs_int("/sys/class/video/disable_video", 1); -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 1); -- aml_set_sysfs_str("/sys/class/ppmgr/ppscaler_rect", "0 0 1919 1079 0"); -- aml_set_sysfs_str("/sys/class/ppmgr/disp", "1280 720"); +- SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 0); +- SysfsUtils::SetInt("/sys/class/video/disable_video", 1); +- SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 1); +- SysfsUtils::SetString("/sys/class/ppmgr/ppscaler_rect", "0 0 1919 1079 0"); +- SysfsUtils::SetString("/sys/class/ppmgr/disp", "1280 720"); - // -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_height", 720); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_height", 720); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_width", 1280); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_height", 720); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_width", 1280); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_height", 720); - // -- aml_set_sysfs_int("/sys/class/video/disable_video", 2); -- aml_set_sysfs_str("/sys/class/display/axis", "0 0 1279 719 0 0 0 0"); -- aml_set_sysfs_str("/sys/class/ppmgr/ppscaler_rect", "0 0 1279 719 1"); +- SysfsUtils::SetInt("/sys/class/video/disable_video", 2); +- SysfsUtils::SetString("/sys/class/display/axis", "0 0 1279 719 0 0 0 0"); +- SysfsUtils::SetString("/sys/class/ppmgr/ppscaler_rect", "0 0 1279 719 1"); - // -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 1); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 1); -- aml_set_sysfs_str("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); +- SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 1); +- SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 1); +- SysfsUtils::SetString("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); -} - void CEGLNativeTypeAmlogic::DisableFreeScale() { // turn off frame buffer freescale - aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 0); - aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 0); -- aml_set_sysfs_str("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); + SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 0); + SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 0); +- SysfsUtils::SetString("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); - -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 0); -- aml_set_sysfs_int("/sys/class/video/disable_video", 0); +- SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 0); +- SysfsUtils::SetInt("/sys/class/video/disable_video", 0); - // now default video display to off -- aml_set_sysfs_int("/sys/class/video/disable_video", 1); +- SysfsUtils::SetInt("/sys/class/video/disable_video", 1); - - // revert display axis - int fd0; @@ -78,9 +78,9 @@ index 8e4bf37..2d5c4a1 100644 - struct fb_var_screeninfo vinfo; - if (ioctl(fd0, FBIOGET_VSCREENINFO, &vinfo) == 0) - { -- char daxis_str[255] = {0}; +- char daxis_str[256] = {0}; - sprintf(daxis_str, "%d %d %d %d 0 0 0 0", 0, 0, vinfo.xres-1, vinfo.yres-1); -- aml_set_sysfs_str("/sys/class/display/axis", daxis_str); +- SysfsUtils::SetString("/sys/class/display/axis", daxis_str); - } - close(fd0); - } @@ -100,5 +100,5 @@ index 8042f36..2e52b7e 100644 private: -- -1.7.10.4 +2.1.4 diff --git a/projects/WeTek_Play/patches/kodi/0008-Reorder-libraries-in-configure-script-to-prevent-lin.patch b/projects/WeTek_Play/patches/kodi/0008-Reorder-libraries-in-configure-script-to-prevent-lin.patch index 098ad65b6c..99d12214ae 100644 --- a/projects/WeTek_Play/patches/kodi/0008-Reorder-libraries-in-configure-script-to-prevent-lin.patch +++ b/projects/WeTek_Play/patches/kodi/0008-Reorder-libraries-in-configure-script-to-prevent-lin.patch @@ -9,13 +9,13 @@ with libsmbclient if the libc that is currently used doesn't contain some functi such as dn_expand (which are often included in libc), but are actually included in libresolv. --- - configure.in | 2 +- + configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/configure.in b/configure.in +diff --git a/configure.ac b/configure.ac index ff4022f..079fa27 100644 ---- a/configure.in -+++ b/configure.in +--- a/configure.ac ++++ b/configure.ac @@ -1475,7 +1475,7 @@ fi # samba if test "x$use_samba" != "xno"; then diff --git a/projects/WeTek_Play/patches/kodi/0012-Fix-incorrect-frame-rate-detection-of-some-videos-wi.patch b/projects/WeTek_Play/patches/kodi/0012-Fix-incorrect-frame-rate-detection-of-some-videos-wi.patch index ce88543f6b..9f70d0fa69 100644 --- a/projects/WeTek_Play/patches/kodi/0012-Fix-incorrect-frame-rate-detection-of-some-videos-wi.patch +++ b/projects/WeTek_Play/patches/kodi/0012-Fix-incorrect-frame-rate-detection-of-some-videos-wi.patch @@ -1,4 +1,4 @@ -From c1992302a958e8b98ce5b0181434b800bf61e78e Mon Sep 17 00:00:00 2001 +From a9ff99a36f9e6cea70f7274312a127563af15dc5 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Sun, 21 Sep 2014 17:20:25 +0300 Subject: [PATCH 12/17] Fix incorrect frame rate detection of some videos with @@ -8,17 +8,17 @@ Use FFMPEG's r_frame_rate, if it as valid, as a video stream frame rate, otherwi Also remove CDVDStreamInfo.rfpsscale, CDVDStreamInfo.rfpsrate, CDemuxStreamVideo.irFpsScale and CDemuxStreamVideo.irFpsRate, they are not needed anymore. --- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 4 --- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 29 +++++++------------- - xbmc/cores/dvdplayer/DVDStreamInfo.cpp | 8 ------ - xbmc/cores/dvdplayer/DVDStreamInfo.h | 2 -- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 4 --- + .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 29 ++++++++-------------- + xbmc/cores/dvdplayer/DVDStreamInfo.cpp | 8 ------ + xbmc/cores/dvdplayer/DVDStreamInfo.h | 2 -- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h -index 40c16c0..98c3513 100644 +index d69991e..faf3c9b 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h -@@ -148,8 +148,6 @@ public: +@@ -151,8 +151,6 @@ public: { iFpsScale = 0; iFpsRate = 0; @@ -27,7 +27,7 @@ index 40c16c0..98c3513 100644 iHeight = 0; iWidth = 0; fAspect = 0.0; -@@ -164,8 +162,6 @@ public: +@@ -167,8 +165,6 @@ public: virtual ~CDemuxStreamVideo() {} int iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps int iFpsRate; @@ -37,10 +37,10 @@ index 40c16c0..98c3513 100644 int iWidth; // width of the stream reported by the demuxer float fAspect; // display aspect of stream diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index ac4bfdb..0025f3a6 100644 +index 1315117..5367b28 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -1123,34 +1123,25 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) +@@ -1125,34 +1125,25 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) #else AVRational r_frame_rate = pStream->r_frame_rate; #endif @@ -126,12 +126,12 @@ index c1dbd85..03facbe 100644 width = stream->iWidth; aspect = stream->fAspect; diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.h b/xbmc/cores/dvdplayer/DVDStreamInfo.h -index de66625..d775d78 100644 +index c0e22a2..8953ff3 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.h +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.h @@ -58,8 +58,6 @@ public: // VIDEO - int fpsscale; // scale of 1000 and a rate of 29970 will result in 29.97 fps + int fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps int fpsrate; - int rfpsscale; - int rfpsrate; @@ -139,5 +139,5 @@ index de66625..d775d78 100644 int width; // width of the stream reported by the demuxer float aspect; // display aspect as reported by demuxer -- -1.7.10.4 +2.1.4 diff --git a/projects/WeTek_Play/patches/kodi/0016-aml-Disable-deinterlacing-for-HD-content-while-video.patch b/projects/WeTek_Play/patches/kodi/0016-aml-Disable-deinterlacing-for-HD-content-while-video.patch index 9e4b881e17..ac06dd2ec9 100644 --- a/projects/WeTek_Play/patches/kodi/0016-aml-Disable-deinterlacing-for-HD-content-while-video.patch +++ b/projects/WeTek_Play/patches/kodi/0016-aml-Disable-deinterlacing-for-HD-content-while-video.patch @@ -1,30 +1,30 @@ -From fbc3b79cb960d559aad3e0c125b1094cfee3142c Mon Sep 17 00:00:00 2001 +From 6aa16d7fe7e6dbe95bdca8069a16d2aa415adf37 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Tue, 3 Feb 2015 17:58:19 +0100 -Subject: [PATCH 16/17] [aml] Disable deinterlacing for HD content while video - is being played in a window to prevent screen - blinking in 1080p50/60hz display modes +Subject: [PATCH 16/17] Disable deinterlacing for HD content while video is + being played in a window to prevent screen blinking in 1080p50/60hz display + modes --- - xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp | 5 +++++ + xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -index f3c67ea..0410bfa 100644 +index 2fad224..74804de 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -@@ -2226,6 +2226,11 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect) +@@ -2261,6 +2261,11 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect) CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_view(%d)", m_stereo_view); #endif + if (dst_rect.Width() < display.Width() || dst_rect.Height() < display.Height()) -+ aml_set_sysfs_int("/sys/module/di/parameters/bypass_hd", 1); ++ SysfsUtils::SetInt("/sys/module/di/parameters/bypass_hd", 1); + else -+ aml_set_sysfs_int("/sys/module/di/parameters/bypass_hd", 0); ++ SysfsUtils::SetInt("/sys/module/di/parameters/bypass_hd", 0); + // goofy 0/1 based difference in aml axis coordinates. // fix them. dst_rect.x2--; -- -1.7.10.4 +2.1.4 diff --git a/projects/WeTek_Play/patches/kodi/0017-pivos-amcodec-hack-pvr-can-reopen-too-fast-slow-us-d.patch b/projects/WeTek_Play/patches/kodi/0017-pivos-amcodec-hack-pvr-can-reopen-too-fast-slow-us-d.patch deleted file mode 100644 index 27d3c62975..0000000000 --- a/projects/WeTek_Play/patches/kodi/0017-pivos-amcodec-hack-pvr-can-reopen-too-fast-slow-us-d.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5ea60323c4d6648943e774946010251e0f560a8d Mon Sep 17 00:00:00 2001 -From: davilla -Date: Wed, 3 Sep 2014 22:14:01 -0400 -Subject: [PATCH 17/17] pivos: [amcodec-hack] pvr can reopen too fast, slow us - down a little - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -index 0410bfa..66ec4f7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -@@ -1632,6 +1632,10 @@ void CAMLCodec::CloseDecoder() - aml_set_sysfs_int("/sys/class/tsync/enable", 1); - - ShowMainVideo(false); -+ -+ // add a little delay after closing in case -+ // we are reopened too fast. -+ usleep(500 * 1000); - } - - void CAMLCodec::Reset() --- -1.7.10.4 - diff --git a/projects/imx6/patches/kodi/kodi-07-Add-aml_support_hevc-function-and-recognize-S812-chi.patch b/projects/imx6/patches/kodi/kodi-07-Add-aml_support_hevc-function-and-recognize-S812-chi.patch deleted file mode 100644 index 1637df70f0..0000000000 --- a/projects/imx6/patches/kodi/kodi-07-Add-aml_support_hevc-function-and-recognize-S812-chi.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 264be7a32fdb566ecf69933189553128c589c800 Mon Sep 17 00:00:00 2001 -From: Stanislav Vlasic -Date: Mon, 13 Oct 2014 13:20:11 +0200 -Subject: [PATCH 07/16] Add aml_support_hevc function and recognize S812 chip - ---- - xbmc/utils/AMLUtils.cpp | 26 ++++++++++++++++++++++++-- - xbmc/utils/AMLUtils.h | 5 ++++- - 2 files changed, 28 insertions(+), 3 deletions(-) - -diff --git a/xbmc/utils/AMLUtils.cpp b/xbmc/utils/AMLUtils.cpp -index 9553745..ac921db 100644 ---- a/xbmc/utils/AMLUtils.cpp -+++ b/xbmc/utils/AMLUtils.cpp -@@ -159,6 +159,22 @@ void aml_permissions() - } - } - -+bool aml_support_hevc() -+{ -+ char valstr[1024]; -+ if(aml_get_sysfs_str("/sys/class/amstream/vcodec_profile", valstr, 1024) != 0) -+ { -+ return false; -+ } -+ char* p = strstr(valstr, "hevc:"); -+ if(p == NULL) -+ { -+ return false; -+ } -+ -+ return true; -+} -+ - enum AML_DEVICE_TYPE aml_get_device_type() - { - static enum AML_DEVICE_TYPE aml_device_type = AML_DEVICE_TYPE_UNINIT; -@@ -173,8 +189,14 @@ enum AML_DEVICE_TYPE aml_get_device_type() - aml_device_type = AML_DEVICE_TYPE_M3; - else if (cpu_hardware.find("Meson6") != std::string::npos) - aml_device_type = AML_DEVICE_TYPE_M6; -- else if (cpu_hardware.find("Meson8") != std::string::npos) -- aml_device_type = AML_DEVICE_TYPE_M8; -+ else if ((cpu_hardware.find("Meson8") != std::string::npos) && (cpu_hardware.find("Meson8B") == std::string::npos)) -+ { -+ if (aml_support_hevc()) -+ aml_device_type = AML_DEVICE_TYPE_M8M2; -+ else -+ aml_device_type = AML_DEVICE_TYPE_M8; -+ } else if (cpu_hardware.find("Meson8B") != std::string::npos) -+ aml_device_type = AML_DEVICE_TYPE_M8B; - else - aml_device_type = AML_DEVICE_TYPE_UNKNOWN; - } -diff --git a/xbmc/utils/AMLUtils.h b/xbmc/utils/AMLUtils.h -index 9778e9b..208f9d3 100644 ---- a/xbmc/utils/AMLUtils.h -+++ b/xbmc/utils/AMLUtils.h -@@ -28,7 +28,9 @@ enum AML_DEVICE_TYPE - AML_DEVICE_TYPE_M1, - AML_DEVICE_TYPE_M3, - AML_DEVICE_TYPE_M6, -- AML_DEVICE_TYPE_M8 -+ AML_DEVICE_TYPE_M8, // S802 -+ AML_DEVICE_TYPE_M8B, // S805 -+ AML_DEVICE_TYPE_M8M2 // S812 - }; - - enum AML_DISPLAY_AXIS_PARAM -@@ -48,6 +50,7 @@ bool aml_present(); - void aml_permissions(); - bool aml_hw3d_present(); - bool aml_wired_present(); -+bool aml_support_hevc(); - enum AML_DEVICE_TYPE aml_get_device_type(); - void aml_cpufreq_min(bool limit); - void aml_cpufreq_max(bool limit); --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-08-CHG-Extract-SysfsUtils-from-the-AML-utils.patch b/projects/imx6/patches/kodi/kodi-08-CHG-Extract-SysfsUtils-from-the-AML-utils.patch deleted file mode 100644 index ba5f41cf3d..0000000000 --- a/projects/imx6/patches/kodi/kodi-08-CHG-Extract-SysfsUtils-from-the-AML-utils.patch +++ /dev/null @@ -1,814 +0,0 @@ -From 22a9bc18b49eb5858b5c7511c9573a861fa81232 Mon Sep 17 00:00:00 2001 -From: "Chris \"Koying\" Browet" -Date: Wed, 31 Dec 2014 15:08:12 +0100 -Subject: [PATCH 08/16] CHG: Extract SysfsUtils from the AML utils - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp | 46 +++++----- - xbmc/utils/AMLUtils.cpp | 95 ++++---------------- - xbmc/utils/AMLUtils.h | 5 -- - xbmc/utils/Makefile.in | 1 + - xbmc/utils/SysfsUtils.cpp | 104 ++++++++++++++++++++++ - xbmc/utils/SysfsUtils.h | 32 +++++++ - xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp | 100 ++++++++++----------- - xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 44 ++------- - xbmc/windowing/egl/EGLNativeTypeIMX.h | 2 - - 9 files changed, 234 insertions(+), 195 deletions(-) - create mode 100644 xbmc/utils/SysfsUtils.cpp - create mode 100644 xbmc/utils/SysfsUtils.h - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -index 26db4a1..b74d361 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp -@@ -33,6 +33,7 @@ - #include "utils/AMLUtils.h" - #include "utils/log.h" - #include "utils/StringUtils.h" -+#include "utils/SysfsUtils.h" - #include "utils/TimeUtils.h" - - #if defined(TARGET_ANDROID) -@@ -1643,7 +1644,7 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) - m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH); - m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0); - // disable tsync, we are playing video disconnected from audio. -- aml_set_sysfs_int("/sys/class/tsync/enable", 0); -+ SysfsUtils::SetInt("/sys/class/tsync/enable", 0); - - am_private->am_pkt.codec = &am_private->vcodec; - pre_header_feeding(am_private, &am_private->am_pkt); -@@ -1655,15 +1656,15 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) - - m_display_rect = CRect(0, 0, CDisplaySettings::Get().GetCurrentResolutionInfo().iWidth, CDisplaySettings::Get().GetCurrentResolutionInfo().iHeight); - -- char buffer[256] = {0}; -- aml_get_sysfs_str("/sys/class/ppmgr/ppscaler", buffer, 255); -- if (!strstr(buffer, "enabled")) // Scaler not enabled, use screen size -+ std::string strScaler; -+ SysfsUtils::GetString("/sys/class/ppmgr/ppscaler", strScaler); -+ if (strScaler.find("enabled") != std::string::npos) // Scaler not enabled, use screen size - { - CLog::Log(LOGDEBUG, "ppscaler not enabled"); -- memset(buffer, 0, 256); -- aml_get_sysfs_str("/sys/class/display/mode", buffer, 255); -+ std::string mode; -+ SysfsUtils::GetString("/sys/class/display/mode", mode); - RESOLUTION_INFO res; -- if (aml_mode_to_resolution(buffer, &res)) -+ if (aml_mode_to_resolution(mode.c_str(), &res)) - m_display_rect = CRect(0, 0, res.iScreenWidth, res.iScreenHeight); - } - -@@ -1671,11 +1672,11 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) - // if display is set to 1080xxx, then disable deinterlacer for HD content - // else bandwidth usage is too heavy and it will slow down video decoder. - char display_mode[256] = {0}; -- aml_get_sysfs_str("/sys/class/display/mode", display_mode, 255); -+ SysfsUtils::GetString("/sys/class/display/mode", display_mode, 255); - if (strstr(display_mode,"1080")) -- aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 1); -+ SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 1); - else -- aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0); -+ SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 0); - */ - - m_opened = true; -@@ -1708,7 +1709,7 @@ void CAMLCodec::CloseDecoder() - free(am_private->extradata); - am_private->extradata = NULL; - // return tsync to default so external apps work -- aml_set_sysfs_int("/sys/class/tsync/enable", 1); -+ SysfsUtils::SetInt("/sys/class/tsync/enable", 1); - - ShowMainVideo(false); - } -@@ -1721,8 +1722,9 @@ void CAMLCodec::Reset() - return; - - // set the system blackout_policy to leave the last frame showing -- int blackout_policy = aml_get_sysfs_int("/sys/class/video/blackout_policy"); -- aml_set_sysfs_int("/sys/class/video/blackout_policy", 0); -+ int blackout_policy; -+ SysfsUtils::GetInt("/sys/class/video/blackout_policy", blackout_policy); -+ SysfsUtils::SetInt("/sys/class/video/blackout_policy", 0); - - // restore the speed (some amcodec versions require this) - if (m_speed != DVD_PLAYSPEED_NORMAL) -@@ -1742,7 +1744,7 @@ void CAMLCodec::Reset() - pre_header_feeding(am_private, &am_private->am_pkt); - - // restore the saved system blackout_policy value -- aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy); -+ SysfsUtils::SetInt("/sys/class/video/blackout_policy", blackout_policy); - - // reset some interal vars - m_1st_pts = 0; -@@ -2065,7 +2067,7 @@ void CAMLCodec::ShowMainVideo(const bool show) - if (saved_disable_video == disable_video) - return; - -- aml_set_sysfs_int("/sys/class/video/disable_video", disable_video); -+ SysfsUtils::SetInt("/sys/class/video/disable_video", disable_video); - saved_disable_video = disable_video; - } - -@@ -2074,7 +2076,7 @@ void CAMLCodec::SetVideoZoom(const float zoom) - // input zoom range is 0.5 to 2.0 with a default of 1.0. - // output zoom range is 2 to 300 with default of 100. - // we limit that to a range of 50 to 200 with default of 100. -- aml_set_sysfs_int("/sys/class/video/zoom", (int)(100 * zoom)); -+ SysfsUtils::SetInt("/sys/class/video/zoom", (int)(100 * zoom)); - } - - void CAMLCodec::SetVideoContrast(const int contrast) -@@ -2082,19 +2084,19 @@ void CAMLCodec::SetVideoContrast(const int contrast) - // input contrast range is 0 to 100 with default of 50. - // output contrast range is -255 to 255 with default of 0. - int aml_contrast = (255 * (contrast - 50)) / 50; -- aml_set_sysfs_int("/sys/class/video/contrast", aml_contrast); -+ SysfsUtils::SetInt("/sys/class/video/contrast", aml_contrast); - } - void CAMLCodec::SetVideoBrightness(const int brightness) - { - // input brightness range is 0 to 100 with default of 50. - // output brightness range is -127 to 127 with default of 0. - int aml_brightness = (127 * (brightness - 50)) / 50; -- aml_set_sysfs_int("/sys/class/video/brightness", aml_brightness); -+ SysfsUtils::SetInt("/sys/class/video/brightness", aml_brightness); - } - void CAMLCodec::SetVideoSaturation(const int saturation) - { - // output saturation range is -127 to 127 with default of 127. -- aml_set_sysfs_int("/sys/class/video/saturation", saturation); -+ SysfsUtils::SetInt("/sys/class/video/saturation", saturation); - } - - void CAMLCodec::GetRenderFeatures(Features &renderFeatures) -@@ -2110,7 +2112,7 @@ void CAMLCodec::GetRenderFeatures(Features &renderFeatures) - void CAMLCodec::SetVideo3dMode(const int mode3d) - { - CLog::Log(LOGDEBUG, "CAMLCodec::SetVideo3dMode:mode3d(0x%x)", mode3d); -- aml_set_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode", mode3d); -+ SysfsUtils::SetInt("/sys/class/ppmgr/ppmgr_3d_mode", mode3d); - } - - std::string CAMLCodec::GetStereoMode() -@@ -2313,9 +2315,9 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect) - char video_axis[256] = {}; - sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2); - -- aml_set_sysfs_str("/sys/class/video/axis", video_axis); -+ SysfsUtils::SetString("/sys/class/video/axis", video_axis); - // make sure we are in 'full stretch' so we can stretch -- aml_set_sysfs_int("/sys/class/video/screen_mode", 1); -+ SysfsUtils::SetInt("/sys/class/video/screen_mode", 1); - - // we only get called once gui has changed to something - // that would show video playback, so show it. -diff --git a/xbmc/utils/AMLUtils.cpp b/xbmc/utils/AMLUtils.cpp -index ac921db..c127c84 100644 ---- a/xbmc/utils/AMLUtils.cpp -+++ b/xbmc/utils/AMLUtils.cpp -@@ -28,77 +28,22 @@ - #include "AMLUtils.h" - #include "utils/CPUInfo.h" - #include "utils/log.h" -+#include "utils/SysfsUtils.h" - #include "utils/StringUtils.h" - #include "utils/AMLUtils.h" - #include "guilib/gui3d.h" - --int aml_set_sysfs_str(const char *path, const char *val) --{ -- int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); -- if (fd >= 0) -- { -- write(fd, val, strlen(val)); -- close(fd); -- return 0; -- } -- return -1; --} -- --int aml_get_sysfs_str(const char *path, char *valstr, const int size) --{ -- int fd = open(path, O_RDONLY); -- if (fd >= 0) -- { -- read(fd, valstr, size - 1); -- valstr[strlen(valstr)] = '\0'; -- close(fd); -- return 0; -- } -- -- sprintf(valstr, "%s", "fail"); -- return -1; --} -- --int aml_set_sysfs_int(const char *path, const int val) --{ -- int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); -- if (fd >= 0) -- { -- char bcmd[16]; -- sprintf(bcmd, "%d", val); -- write(fd, bcmd, strlen(bcmd)); -- close(fd); -- return 0; -- } -- return -1; --} -- --int aml_get_sysfs_int(const char *path) --{ -- int val = -1; -- int fd = open(path, O_RDONLY); -- if (fd >= 0) -- { -- char bcmd[16]; -- read(fd, bcmd, sizeof(bcmd)); -- val = strtol(bcmd, NULL, 16); -- close(fd); -- } -- return val; --} -- - bool aml_present() - { - static int has_aml = -1; - if (has_aml == -1) - { -- int rtn = aml_get_sysfs_int("/sys/class/audiodsp/digital_raw"); -- if (rtn != -1) -+ if (SysfsUtils::Has("/sys/class/audiodsp/digital_raw")) - has_aml = 1; - else - has_aml = 0; - if (has_aml) -- CLog::Log(LOGNOTICE, "aml_present, rtn(%d)", rtn); -+ CLog::Log(LOGNOTICE, "AML device detected"); - } - return has_aml == 1; - } -@@ -108,10 +53,12 @@ bool aml_hw3d_present() - static int has_hw3d = -1; - if (has_hw3d == -1) - { -- if (aml_get_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode") != -1) -+ if (SysfsUtils::Has("/sys/class/ppmgr/ppmgr_3d_mode")) - has_hw3d = 1; - else - has_hw3d = 0; -+ if (has_hw3d) -+ CLog::Log(LOGNOTICE, "AML 3D support detected"); - } - return has_hw3d == 1; - } -@@ -121,8 +68,8 @@ bool aml_wired_present() - static int has_wired = -1; - if (has_wired == -1) - { -- char test[64] = {0}; -- if (aml_get_sysfs_str("/sys/class/net/eth0/operstate", test, 63) != -1) -+ std::string test; -+ if (SysfsUtils::GetString("/sys/class/net/eth0/operstate", test) != -1) - has_wired = 1; - else - has_wired = 0; -@@ -161,18 +108,12 @@ void aml_permissions() - - bool aml_support_hevc() - { -- char valstr[1024]; -- if(aml_get_sysfs_str("/sys/class/amstream/vcodec_profile", valstr, 1024) != 0) -+ std::string valstr; -+ if(SysfsUtils::GetString("/sys/class/amstream/vcodec_profile", valstr) != 0) - { - return false; - } -- char* p = strstr(valstr, "hevc:"); -- if(p == NULL) -- { -- return false; -- } -- -- return true; -+ return (valstr.find("hevc:") != std::string::npos); - } - - enum AML_DEVICE_TYPE aml_get_device_type() -@@ -216,7 +157,7 @@ void aml_cpufreq_min(bool limit) - if (limit) - cpufreq = 600000; - -- aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq); -+ SysfsUtils::SetInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", cpufreq); - } - #endif - } -@@ -231,8 +172,8 @@ void aml_cpufreq_max(bool limit) - if (limit) - cpufreq = 800000; - -- aml_set_sysfs_int("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq); -- aml_set_sysfs_str("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand"); -+ SysfsUtils::SetInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", cpufreq); -+ SysfsUtils::SetString("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "ondemand"); - } - } - -@@ -244,7 +185,7 @@ void aml_set_audio_passthrough(bool passthrough) - { - // m1 uses 1, m3 and above uses 2 - int raw = aml_get_device_type() == AML_DEVICE_TYPE_M1 ? 1:2; -- aml_set_sysfs_int("/sys/class/audiodsp/digital_raw", passthrough ? raw:0); -+ SysfsUtils::SetInt("/sys/class/audiodsp/digital_raw", passthrough ? raw:0); - } - } - -@@ -314,11 +255,11 @@ void aml_probe_hdmi_audio() - - int aml_axis_value(AML_DISPLAY_AXIS_PARAM param) - { -- char axis[20] = {0}; -+ std::string axis; - int value[8]; - -- aml_get_sysfs_str("/sys/class/display/axis", axis, 19); -- sscanf(axis, "%d %d %d %d %d %d %d %d", &value[0], &value[1], &value[2], &value[3], &value[4], &value[5], &value[6], &value[7]); -+ SysfsUtils::GetString("/sys/class/display/axis", axis); -+ sscanf(axis.c_str(), "%d %d %d %d %d %d %d %d", &value[0], &value[1], &value[2], &value[3], &value[4], &value[5], &value[6], &value[7]); - - return value[param]; - } -diff --git a/xbmc/utils/AMLUtils.h b/xbmc/utils/AMLUtils.h -index 208f9d3..6b0048a 100644 ---- a/xbmc/utils/AMLUtils.h -+++ b/xbmc/utils/AMLUtils.h -@@ -41,11 +41,6 @@ enum AML_DISPLAY_AXIS_PARAM - AML_DISPLAY_AXIS_PARAM_HEIGHT - }; - --int aml_set_sysfs_str(const char *path, const char *val); --int aml_get_sysfs_str(const char *path, char *valstr, const int size); --int aml_set_sysfs_int(const char *path, const int val); --int aml_get_sysfs_int(const char *path); -- - bool aml_present(); - void aml_permissions(); - bool aml_hw3d_present(); -diff --git a/xbmc/utils/Makefile.in b/xbmc/utils/Makefile.in -index e203447..2d89fcd 100644 ---- a/xbmc/utils/Makefile.in -+++ b/xbmc/utils/Makefile.in -@@ -79,6 +79,7 @@ SRCS += XMLUtils.cpp - SRCS += Utf8Utils.cpp - SRCS += XSLTUtils.cpp - SRCS += ActorProtocol.cpp -+SRCS += SysfsUtils.cpp - - ifeq (@USE_OPENGLES@,1) - SRCS += AMLUtils.cpp -diff --git a/xbmc/utils/SysfsUtils.cpp b/xbmc/utils/SysfsUtils.cpp -new file mode 100644 -index 0000000..ca62986 ---- /dev/null -+++ b/xbmc/utils/SysfsUtils.cpp -@@ -0,0 +1,104 @@ -+/* -+ * Copyright (C) 2011-2014 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 "SysfsUtils.h" -+#include "utils/log.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+int SysfsUtils::SetString(const std::string& path, const std::string& valstr) -+{ -+ int fd = open(path.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); -+ if (fd >= 0) -+ { -+ write(fd, valstr.c_str(), valstr.size()); -+ close(fd); -+ return 0; -+ } -+ CLog::Log(LOGERROR, "%s: error writing %s",__FUNCTION__, path.c_str()); -+ return -1; -+} -+ -+int SysfsUtils::GetString(const std::string& path, std::string& valstr) -+{ -+ int len; -+ char buf[256] = {0}; -+ -+ int fd = open(path.c_str(), O_RDONLY); -+ if (fd >= 0) -+ { -+ valstr.clear(); -+ while ((len = read(fd, buf, 256)) > 0) -+ valstr.append(buf, len); -+ close(fd); -+ return 0; -+ } -+ -+ CLog::Log(LOGERROR, "%s: error reading %s",__FUNCTION__, path.c_str()); -+ valstr = "fail"; -+ return -1; -+} -+ -+int SysfsUtils::SetInt(const std::string& path, const int val) -+{ -+ int fd = open(path.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); -+ if (fd >= 0) -+ { -+ char bcmd[16]; -+ sprintf(bcmd, "%d", val); -+ write(fd, bcmd, strlen(bcmd)); -+ close(fd); -+ return 0; -+ } -+ -+ CLog::Log(LOGERROR, "%s: error writing %s",__FUNCTION__, path.c_str()); -+ return -1; -+} -+ -+int SysfsUtils::GetInt(const std::string& path, int& val) -+{ -+ int fd = open(path.c_str(), O_RDONLY); -+ if (fd >= 0) -+ { -+ char bcmd[16]; -+ read(fd, bcmd, sizeof(bcmd)); -+ val = strtol(bcmd, NULL, 16); -+ close(fd); -+ return 0; -+ } -+ -+ CLog::Log(LOGERROR, "%s: error reading %s",__FUNCTION__, path.c_str()); -+ return -1; -+} -+ -+bool SysfsUtils::Has(const std::string &path) -+{ -+ int fd = open(path.c_str(), O_RDONLY); -+ if (fd >= 0) -+ { -+ close(fd); -+ return true; -+ } -+ return false; -+} -diff --git a/xbmc/utils/SysfsUtils.h b/xbmc/utils/SysfsUtils.h -new file mode 100644 -index 0000000..fe038bf ---- /dev/null -+++ b/xbmc/utils/SysfsUtils.h -@@ -0,0 +1,32 @@ -+#pragma once -+/* -+ * Copyright (C) 2011-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 -+ -+class SysfsUtils -+{ -+public: -+ static int SetString(const std::string& path, const std::string& valstr); -+ static int GetString(const std::string& path, std::string& valstr); -+ static int SetInt(const std::string& path, const int val); -+ static int GetInt(const std::string& path, int& val); -+ static bool Has(const std::string& path); -+}; -diff --git a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -index 7064836..0cce3ea 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeAmlogic.cpp -@@ -22,6 +22,7 @@ - #include "guilib/gui3d.h" - #include "utils/AMLUtils.h" - #include "utils/StringUtils.h" -+#include "utils/SysfsUtils.h" - - #include - #include -@@ -49,13 +50,12 @@ CEGLNativeTypeAmlogic::~CEGLNativeTypeAmlogic() - - bool CEGLNativeTypeAmlogic::CheckCompatibility() - { -- char name[256] = {0}; -+ std::string name; - std::string modalias = "/sys/class/graphics/" + m_framebuffer_name + "/device/modalias"; - -- aml_get_sysfs_str(modalias.c_str(), name, 255); -- CStdString strName = name; -- StringUtils::Trim(strName); -- if (strName == "platform:mesonfb") -+ SysfsUtils::GetString(modalias, name); -+ StringUtils::Trim(name); -+ if (name == "platform:mesonfb") - return true; - return false; - } -@@ -127,9 +127,9 @@ bool CEGLNativeTypeAmlogic::DestroyNativeWindow() - - bool CEGLNativeTypeAmlogic::GetNativeResolution(RESOLUTION_INFO *res) const - { -- char mode[256] = {0}; -- aml_get_sysfs_str("/sys/class/display/mode", mode, 255); -- return aml_mode_to_resolution(mode, res); -+ std::string mode; -+ SysfsUtils::GetString("/sys/class/display/mode", mode); -+ return aml_mode_to_resolution(mode.c_str(), res); - } - - bool CEGLNativeTypeAmlogic::SetNativeResolution(const RESOLUTION_INFO &res) -@@ -180,8 +180,8 @@ bool CEGLNativeTypeAmlogic::SetNativeResolution(const RESOLUTION_INFO &res) - - bool CEGLNativeTypeAmlogic::ProbeResolutions(std::vector &resolutions) - { -- char valstr[256] = {0}; -- aml_get_sysfs_str("/sys/class/amhdmitx/amhdmitx0/disp_cap", valstr, 255); -+ std::string valstr; -+ SysfsUtils::GetString("/sys/class/amhdmitx/amhdmitx0/disp_cap", valstr); - std::vector probe_str = StringUtils::Split(valstr, "\n"); - - resolutions.clear(); -@@ -210,7 +210,7 @@ bool CEGLNativeTypeAmlogic::GetPreferredResolution(RESOLUTION_INFO *res) const - bool CEGLNativeTypeAmlogic::ShowWindow(bool show) - { - std::string blank_framebuffer = "/sys/class/graphics/" + m_framebuffer_name + "/blank"; -- aml_set_sysfs_int(blank_framebuffer.c_str(), show ? 0 : 1); -+ SysfsUtils::SetInt(blank_framebuffer.c_str(), show ? 0 : 1); - return true; - } - -@@ -218,7 +218,7 @@ bool CEGLNativeTypeAmlogic::SetDisplayResolution(const char *resolution) - { - CStdString mode = resolution; - // switch display resolution -- aml_set_sysfs_str("/sys/class/display/mode", mode.c_str()); -+ SysfsUtils::SetString("/sys/class/display/mode", mode.c_str()); - SetupVideoScaling(mode.c_str()); - - return true; -@@ -226,67 +226,67 @@ bool CEGLNativeTypeAmlogic::SetDisplayResolution(const char *resolution) - - void CEGLNativeTypeAmlogic::SetupVideoScaling(const char *mode) - { -- aml_set_sysfs_int("/sys/class/graphics/fb0/blank", 1); -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 0); -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", 1); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 0); -+ SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 0); - - if (strstr(mode, "1080")) - { -- aml_set_sysfs_str("/sys/class/graphics/fb0/request2XScale", "8"); -- aml_set_sysfs_str("/sys/class/graphics/fb1/scale_axis", "1280 720 1920 1080"); -- aml_set_sysfs_str("/sys/class/graphics/fb1/scale", "0x10001"); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/request2XScale", "8"); -+ SysfsUtils::SetString("/sys/class/graphics/fb1/scale_axis", "1280 720 1920 1080"); -+ SysfsUtils::SetString("/sys/class/graphics/fb1/scale", "0x10001"); - } - else - { -- aml_set_sysfs_str("/sys/class/graphics/fb0/request2XScale", "16 1280 720"); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/request2XScale", "16 1280 720"); - } - -- aml_set_sysfs_int("/sys/class/graphics/fb0/blank", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", 0); - } - - void CEGLNativeTypeAmlogic::EnableFreeScale() - { - // enable OSD free scale using frame buffer size of 720p -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_height", 720); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_height", 720); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_width", 1280); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_height", 720); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_width", 1280); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_height", 720); - - // enable video free scale (scaling to 1920x1080 with frame buffer size 1280x720) -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 0); -- aml_set_sysfs_int("/sys/class/video/disable_video", 1); -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 1); -- aml_set_sysfs_str("/sys/class/ppmgr/ppscaler_rect", "0 0 1919 1079 0"); -- aml_set_sysfs_str("/sys/class/ppmgr/disp", "1280 720"); -+ SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 0); -+ SysfsUtils::SetInt("/sys/class/video/disable_video", 1); -+ SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 1); -+ SysfsUtils::SetString("/sys/class/ppmgr/ppscaler_rect", "0 0 1919 1079 0"); -+ SysfsUtils::SetString("/sys/class/ppmgr/disp", "1280 720"); - // -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb0/scale_height", 720); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_width", 1280); -- aml_set_sysfs_int("/sys/class/graphics/fb1/scale_height", 720); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_width", 1280); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/scale_height", 720); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_width", 1280); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/scale_height", 720); - // -- aml_set_sysfs_int("/sys/class/video/disable_video", 2); -- aml_set_sysfs_str("/sys/class/display/axis", "0 0 1279 719 0 0 0 0"); -- aml_set_sysfs_str("/sys/class/ppmgr/ppscaler_rect", "0 0 1279 719 1"); -+ SysfsUtils::SetInt("/sys/class/video/disable_video", 2); -+ SysfsUtils::SetString("/sys/class/display/axis", "0 0 1279 719 0 0 0 0"); -+ SysfsUtils::SetString("/sys/class/ppmgr/ppscaler_rect", "0 0 1279 719 1"); - // -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 1); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 1); -- aml_set_sysfs_str("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 1); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 1); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); - } - - void CEGLNativeTypeAmlogic::DisableFreeScale() - { - // turn off frame buffer freescale -- aml_set_sysfs_int("/sys/class/graphics/fb0/free_scale", 0); -- aml_set_sysfs_int("/sys/class/graphics/fb1/free_scale", 0); -- aml_set_sysfs_str("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); -+ SysfsUtils::SetInt("/sys/class/graphics/fb0/free_scale", 0); -+ SysfsUtils::SetInt("/sys/class/graphics/fb1/free_scale", 0); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/free_scale_axis", "0 0 1279 719"); - -- aml_set_sysfs_int("/sys/class/ppmgr/ppscaler", 0); -- aml_set_sysfs_int("/sys/class/video/disable_video", 0); -+ SysfsUtils::SetInt("/sys/class/ppmgr/ppscaler", 0); -+ SysfsUtils::SetInt("/sys/class/video/disable_video", 0); - // now default video display to off -- aml_set_sysfs_int("/sys/class/video/disable_video", 1); -+ SysfsUtils::SetInt("/sys/class/video/disable_video", 1); - - // revert display axis - int fd0; -@@ -297,9 +297,9 @@ void CEGLNativeTypeAmlogic::DisableFreeScale() - struct fb_var_screeninfo vinfo; - if (ioctl(fd0, FBIOGET_VSCREENINFO, &vinfo) == 0) - { -- char daxis_str[255] = {0}; -+ char daxis_str[256] = {0}; - sprintf(daxis_str, "%d %d %d %d 0 0 0 0", 0, 0, vinfo.xres-1, vinfo.yres-1); -- aml_set_sysfs_str("/sys/class/display/axis", daxis_str); -+ SysfsUtils::SetString("/sys/class/display/axis", daxis_str); - } - close(fd0); - } -diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -index 04cadc8..9893558 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -@@ -28,6 +28,7 @@ - #include "utils/log.h" - #include "utils/RegExp.h" - #include "utils/StringUtils.h" -+#include "utils/SysfsUtils.h" - #include "utils/Environment.h" - #include "guilib/gui3d.h" - #include "windowing/WindowingFactory.h" -@@ -190,7 +191,7 @@ bool CEGLNativeTypeIMX::DestroyNativeWindow() - bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const - { - std::string mode; -- get_sysfs_str("/sys/class/graphics/fb0/mode", mode); -+ SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); - return ModeToResolution(mode, res); - } - -@@ -200,14 +201,14 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) - return false; - - std::string mode; -- get_sysfs_str("/sys/class/graphics/fb0/mode", mode); -+ SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); - if (res.strId == mode) - return false; - - DestroyNativeWindow(); - DestroyNativeDisplay(); - -- set_sysfs_str("/sys/class/graphics/fb0/mode", res.strId); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId); - - CreateNativeDisplay(); - -@@ -225,7 +226,7 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio - return false; - - std::string valstr; -- get_sysfs_str("/sys/class/graphics/fb0/modes", valstr); -+ SysfsUtils::GetString("/sys/class/graphics/fb0/modes", valstr); - std::vector probe_str; - probe_str = StringUtils::Split(valstr, "\n"); - -@@ -257,41 +258,6 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) - return false; - } - --int CEGLNativeTypeIMX::get_sysfs_str(std::string path, std::string& valstr) const --{ -- int len; -- char buf[256] = {0}; -- -- int fd = open(path.c_str(), O_RDONLY); -- if (fd >= 0) -- { -- while ((len = read(fd, buf, 255)) > 0) -- valstr.append(buf, len); -- close(fd); -- } -- else -- { -- CLog::Log(LOGERROR, "%s: error reading %s",__FUNCTION__, path.c_str()); -- valstr = "fail"; -- return -1; -- } -- return 0; --} -- --int CEGLNativeTypeIMX::set_sysfs_str(std::string path, std::string val) const --{ -- int fd = open(path.c_str(), O_WRONLY); -- if (fd >= 0) -- { -- val += '\n'; -- write(fd, val.c_str(), val.size()); -- close(fd); -- return 0; -- } -- CLog::Log(LOGERROR, "%s: error writing %s",__FUNCTION__, path.c_str()); -- return -1; --} -- - bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const - { - if (!res) -diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h -index d5e5739..0298cb5 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeIMX.h -+++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h -@@ -50,8 +50,6 @@ public: - - protected: - bool m_readonly; -- int get_sysfs_str(std::string path, std::string& valstr) const; -- int set_sysfs_str(std::string path, std::string val) const; - bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; - - EGLNativeDisplayType m_display; --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-09-imx-Fixed-mode-change-after-SysfsUtils-port.patch b/projects/imx6/patches/kodi/kodi-09-imx-Fixed-mode-change-after-SysfsUtils-port.patch deleted file mode 100644 index 98894197c8..0000000000 --- a/projects/imx6/patches/kodi/kodi-09-imx-Fixed-mode-change-after-SysfsUtils-port.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 11a9bc199b0ebd9e6cfb9b82547bb3c5379b1104 Mon Sep 17 00:00:00 2001 -From: smallint -Date: Mon, 19 Jan 2015 20:38:42 +0100 -Subject: [PATCH 09/16] [imx] Fixed mode change after SysfsUtils port - ---- - xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -index 9893558..061f6e6 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -@@ -208,7 +208,7 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) - DestroyNativeWindow(); - DestroyNativeDisplay(); - -- SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId); -+ SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId + "\n"); - - CreateNativeDisplay(); - --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-10-imx-Added-de-interlacing-method-enumerations-FAST_MO.patch b/projects/imx6/patches/kodi/kodi-10-imx-Added-de-interlacing-method-enumerations-FAST_MO.patch deleted file mode 100644 index 12274ae0dd..0000000000 --- a/projects/imx6/patches/kodi/kodi-10-imx-Added-de-interlacing-method-enumerations-FAST_MO.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 9c9935180aa9297d35855db674b7eb7f732714e9 Mon Sep 17 00:00:00 2001 -From: smallint -Date: Thu, 5 Feb 2015 19:35:05 +0000 -Subject: [PATCH 10/16] [imx] Added de-interlacing method enumerations - FAST_MOTION and FAST_MOTION_DOUBLE - ---- - language/English/strings.po | 14 +++++++++++++- - xbmc/settings/VideoSettings.h | 3 +++ - xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 2 ++ - 3 files changed, 18 insertions(+), 1 deletion(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 15090fc..d994570 100755 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -7548,7 +7548,19 @@ msgctxt "#16333" - msgid "MMAL - Bob (Half)" - msgstr "" - --#empty strings from id 16334 to 16399 -+#. Description of OSD video settings for deinterlace method with label #16334 -+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+msgctxt "#16334" -+msgid "IMX - Fast motion" -+msgstr "" -+ -+#. Description of OSD video settings for deinterlace method with label #16335 -+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+msgctxt "#16335" -+msgid "IMX - Fast motion (Double)" -+msgstr "" -+ -+#empty strings from id 16336 to 16399 - - #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp - msgctxt "#16400" -diff --git a/xbmc/settings/VideoSettings.h b/xbmc/settings/VideoSettings.h -index 6eaef1d..8644250 100644 ---- a/xbmc/settings/VideoSettings.h -+++ b/xbmc/settings/VideoSettings.h -@@ -72,6 +72,9 @@ enum EINTERLACEMETHOD - VS_INTERLACEMETHOD_MMAL_BOB = 27, - VS_INTERLACEMETHOD_MMAL_BOB_HALF = 28, - -+ VS_INTERLACEMETHOD_IMX_FASTMOTION = 29, -+ VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE = 30, -+ - VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value. - }; - -diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -index ca65fdc..d350a02 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -@@ -266,6 +266,8 @@ void CGUIDialogVideoSettings::InitializeSettings() - entries.push_back(make_pair(16331, VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF)); - entries.push_back(make_pair(16332, VS_INTERLACEMETHOD_MMAL_BOB)); - entries.push_back(make_pair(16333, VS_INTERLACEMETHOD_MMAL_BOB_HALF)); -+ entries.push_back(make_pair(16334, VS_INTERLACEMETHOD_IMX_FASTMOTION)); -+ entries.push_back(make_pair(16335, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE)); - - /* remove unsupported methods */ - for (StaticIntegerSettingOptions::iterator it = entries.begin(); it != entries.end(); ) --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-11-RenderManager-preserve-field-type-for-Renderer-Rende.patch b/projects/imx6/patches/kodi/kodi-11-RenderManager-preserve-field-type-for-Renderer-Rende.patch deleted file mode 100644 index 17793cd645..0000000000 --- a/projects/imx6/patches/kodi/kodi-11-RenderManager-preserve-field-type-for-Renderer-Rende.patch +++ /dev/null @@ -1,52 +0,0 @@ -From ba9b668fcbfd4f6bcfd67b22bcdc850a140ac65c Mon Sep 17 00:00:00 2001 -From: smallint -Date: Thu, 5 Feb 2015 19:37:13 +0000 -Subject: [PATCH 11/16] [RenderManager] preserve field type for - Renderer::RenderUpdate - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 36c2842..85c3565 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -676,7 +676,10 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - deinterlacemode = VS_DEINTERLACEMODE_OFF; - - if (deinterlacemode == VS_DEINTERLACEMODE_OFF) -+ { - presentmethod = PRESENT_METHOD_SINGLE; -+ sync = FS_NONE; -+ } - else - { - if (deinterlacemode == VS_DEINTERLACEMODE_AUTO && sync == FS_NONE) -@@ -691,6 +694,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB_INVERTED) { presentmethod = PRESENT_METHOD_BOB; invert = true; } - else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BOB) presentmethod = PRESENT_METHOD_BOB; - else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BEST) presentmethod = PRESENT_METHOD_BOB; -+ else if (interlacemethod == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE) presentmethod = PRESENT_METHOD_BOB; - else presentmethod = PRESENT_METHOD_SINGLE; - - /* default to odd field if we want to deinterlace and don't know better */ -@@ -837,8 +841,14 @@ bool CXBMCRenderManager::IsVideoLayer() - void CXBMCRenderManager::PresentSingle(bool clear, DWORD flags, DWORD alpha) - { - CSingleLock lock(g_graphicsContext); -+ SPresent& m = m_Queue[m_presentsource]; - -- m_pRenderer->RenderUpdate(clear, flags, alpha); -+ if (m.presentfield == FS_BOT) -+ m_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_BOT, alpha); -+ else if (m.presentfield == FS_TOP) -+ m_pRenderer->RenderUpdate(clear, flags | RENDER_FLAG_TOP, alpha); -+ else -+ m_pRenderer->RenderUpdate(clear, flags, alpha); - } - - /* new simpler method of handling interlaced material, * --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-12-imx-Reworked-video-decoding-and-rendering-see-http-f.patch b/projects/imx6/patches/kodi/kodi-12-imx-Reworked-video-decoding-and-rendering-see-http-f.patch deleted file mode 100644 index fd5ed38378..0000000000 --- a/projects/imx6/patches/kodi/kodi-12-imx-Reworked-video-decoding-and-rendering-see-http-f.patch +++ /dev/null @@ -1,2351 +0,0 @@ -From f868235f00f10e58d682a7786544b495d5113405 Mon Sep 17 00:00:00 2001 -From: smallint -Date: Thu, 5 Feb 2015 19:39:33 +0000 -Subject: [PATCH 12/16] [imx] Reworked video decoding and rendering, see - http://forum.kodi.tv/showthread.php?tid=211289&pid=1892440#pid1892440 - -Conflicts: - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ---- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 219 ++-- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 3 + - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1084 +++++++++++++++++--- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 319 ++++-- - xbmc/guilib/GUIVideoControl.cpp | 4 + - xbmc/utils/Screenshot.cpp | 13 +- - xbmc/video/windows/GUIWindowFullScreen.cpp | 4 + - xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 70 +- - xbmc/windowing/egl/WinSystemEGL.cpp | 9 +- - 9 files changed, 1370 insertions(+), 355 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index a765461..94fb19b 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -88,12 +88,6 @@ static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR; - #ifdef HAS_IMXVPU - #include "windowing/egl/EGLWrapper.h" - #include "DVDCodecs/Video/DVDVideoCodecIMX.h" -- --#define GL_VIV_NV12 0x8FC1 --typedef void (GL_APIENTRYP PFNGLTEXDIRECTVIVMAPPROC) (GLenum Target, GLsizei Width, GLsizei Height, GLenum Format, GLvoid ** Logical, const GLuint * Physical); --typedef void (GL_APIENTRYP PFNGLTEXDIRECTINVALIDATEVIVPROC) (GLenum Target); --static PFNGLTEXDIRECTVIVMAPPROC glTexDirectVIVMap; --static PFNGLTEXDIRECTINVALIDATEVIVPROC glTexDirectInvalidateVIV; - #endif - - #if defined(TARGET_ANDROID) -@@ -185,13 +179,6 @@ CLinuxRendererGLES::CLinuxRendererGLES() - eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC) eglGetProcAddress("eglClientWaitSyncKHR"); - } - #endif -- --#ifdef HAS_IMXVPU -- if (!glTexDirectVIVMap) -- glTexDirectVIVMap = (PFNGLTEXDIRECTVIVMAPPROC) CEGLWrapper::GetProcAddress("glTexDirectVIVMap"); -- if (!glTexDirectInvalidateVIV) -- glTexDirectInvalidateVIV = (PFNGLTEXDIRECTINVALIDATEVIVPROC) CEGLWrapper::GetProcAddress("glTexDirectInvalidateVIV"); --#endif - } - - CLinuxRendererGLES::~CLinuxRendererGLES() -@@ -608,6 +595,64 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) - - return; - } -+#ifdef HAS_IMXVPU -+ else if (m_renderMethod & RENDER_IMXMAP) -+ { -+#if 0 -+ static unsigned long long previous = 0; -+ unsigned long long current = XbmcThreads::SystemClockMillis(); -+ printf("r->r: %d\n", (int)(current-previous)); -+ previous = current; -+#endif -+ CDVDVideoCodecIMXBuffer *buffer = m_buffers[m_iYV12RenderBuffer].IMXBuffer; -+ if (buffer != NULL && buffer->IsValid()) -+ { -+ ManageDisplay(); -+ g_IMXContext.SetBlitRects(m_sourceRect, m_destRect); -+ -+ bool topFieldFirst = true; -+ -+ // Deinterlacing requested -+ if (flags & RENDER_FLAG_FIELDMASK) -+ { -+ if ((buffer->GetFieldType() == VPU_FIELD_BOTTOM) -+ || (buffer->GetFieldType() == VPU_FIELD_BT) ) -+ topFieldFirst = false; -+ -+ if (flags & RENDER_FLAG_FIELD0) -+ { -+ // Double rate first frame -+ g_IMXContext.SetDeInterlacing(true); -+ g_IMXContext.SetDoubleRate(true); -+ g_IMXContext.SetInterpolatedFrame(true); -+ } -+ else if (flags & RENDER_FLAG_FIELD1) -+ { -+ // Double rate second frame -+ g_IMXContext.SetDeInterlacing(true); -+ g_IMXContext.SetDoubleRate(true); -+ g_IMXContext.SetInterpolatedFrame(false); -+ } -+ else -+ { -+ // Fast motion -+ g_IMXContext.SetDeInterlacing(true); -+ g_IMXContext.SetDoubleRate(false); -+ } -+ } -+ // Progressive -+ else -+ g_IMXContext.SetDeInterlacing(false); -+ -+ g_IMXContext.BlitAsync(NULL, buffer, topFieldFirst); -+ } -+ -+#if 0 -+ unsigned long long current2 = XbmcThreads::SystemClockMillis(); -+ printf("r: %d %d\n", m_iYV12RenderBuffer, (int)(current2-current)); -+#endif -+ } -+#endif - } - - void CLinuxRendererGLES::FlipPage(int source) -@@ -963,13 +1008,7 @@ void CLinuxRendererGLES::ReleaseBuffer(int idx) - #endif - #ifdef HAS_IMXVPU - if (m_renderMethod & RENDER_IMXMAP) -- { -- if (buf.IMXBuffer) -- { -- SAFE_RELEASE(buf.IMXBuffer); -- buf.IMXBuffer = NULL; -- } -- } -+ SAFE_RELEASE(buf.IMXBuffer); - #endif - } - -@@ -1241,7 +1280,7 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field) - // imgwidth *= planes[0].pixpertex_x; - // imgheight *= planes[0].pixpertex_y; - // } --// -+// - // glBegin(GL_QUADS); - // - // glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1); -@@ -1679,81 +1718,6 @@ void CLinuxRendererGLES::RenderCoreVideoRef(int index, int field) - - void CLinuxRendererGLES::RenderIMXMAPTexture(int index, int field) - { --#if defined(HAS_IMXVPU) --#ifdef DEBUG_VERBOSE -- unsigned int time = XbmcThreads::SystemClockMillis(); --#endif -- -- YUVPLANE &plane = m_buffers[index].fields[field][0]; -- CDVDVideoCodecIMXBuffer *buffer = m_buffers[index].IMXBuffer; -- -- if(buffer == NULL) return; -- -- CDVDVideoCodecIMX::Enter(); -- -- if(!buffer->IsValid()) -- { -- CDVDVideoCodecIMX::Leave(); -- return; -- } -- -- glDisable(GL_DEPTH_TEST); -- -- glActiveTexture(GL_TEXTURE0); -- glBindTexture(m_textureTarget, plane.id); -- -- g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA); -- -- GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip -- GLfloat ver[4][4]; -- GLfloat tex[4][2]; -- GLfloat col[3] = {1.0f, 1.0f, 1.0f}; -- -- GLint posLoc = g_Windowing.GUIShaderGetPos(); -- GLint texLoc = g_Windowing.GUIShaderGetCoord0(); -- GLint colLoc = g_Windowing.GUIShaderGetCol(); -- -- glVertexAttribPointer(posLoc, 4, GL_FLOAT, 0, 0, ver); -- glVertexAttribPointer(texLoc, 2, GL_FLOAT, 0, 0, tex); -- glVertexAttribPointer(colLoc, 3, GL_FLOAT, 0, 0, col); -- -- glEnableVertexAttribArray(posLoc); -- glEnableVertexAttribArray(texLoc); -- glEnableVertexAttribArray(colLoc); -- -- // Set vertex coordinates -- for(int i = 0; i < 4; i++) -- { -- ver[i][0] = m_rotatedDestCoords[i].x; -- ver[i][1] = m_rotatedDestCoords[i].y; -- ver[i][2] = 0.0f;// set z to 0 -- ver[i][3] = 1.0f; -- } -- -- // Set texture coordinates -- tex[0][0] = tex[3][0] = plane.rect.x1; -- tex[0][1] = tex[1][1] = plane.rect.y1; -- tex[1][0] = tex[2][0] = plane.rect.x2; -- tex[2][1] = tex[3][1] = plane.rect.y2; -- -- glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx); -- -- glDisableVertexAttribArray(posLoc); -- glDisableVertexAttribArray(texLoc); -- glDisableVertexAttribArray(colLoc); -- -- g_Windowing.DisableGUIShader(); -- VerifyGLState(); -- -- glBindTexture(m_textureTarget, 0); -- VerifyGLState(); -- -- CDVDVideoCodecIMX::Leave(); -- --#ifdef DEBUG_VERBOSE -- CLog::Log(LOGDEBUG, "RenderIMXMAPTexture %d: tm:%d\n", index, XbmcThreads::SystemClockMillis() - time); --#endif --#endif - } - - bool CLinuxRendererGLES::RenderCapture(CRenderCapture* capture) -@@ -2717,42 +2681,6 @@ void CLinuxRendererGLES::SetTextureFilter(GLenum method) - //******************************************************************************************************** - void CLinuxRendererGLES::UploadIMXMAPTexture(int index) - { --#ifdef HAS_IMXVPU -- YUVBUFFER& buf = m_buffers[index]; -- CDVDVideoCodecIMXBuffer* IMXBuffer = buf.IMXBuffer; -- -- if(IMXBuffer) -- { -- CDVDVideoCodecIMX::Enter(); -- -- if(!IMXBuffer->IsValid()) -- { -- CDVDVideoCodecIMX::Leave(); -- return; -- } -- -- YUVPLANE &plane = m_buffers[index].fields[0][0]; -- -- glActiveTexture(GL_TEXTURE0); -- glBindTexture(m_textureTarget, plane.id); -- -- GLuint physical = ~0U; -- GLvoid *virt = (GLvoid*)IMXBuffer->m_VirtAddr; -- glTexDirectVIVMap(m_textureTarget, IMXBuffer->m_iWidth, IMXBuffer->m_iHeight, GL_VIV_NV12, -- (GLvoid **)&virt, &physical); -- glTexDirectInvalidateVIV(m_textureTarget); -- -- glBindTexture(m_textureTarget, 0); -- -- plane.flipindex = m_buffers[index].flipindex; -- plane.texwidth = IMXBuffer->m_iWidth; -- plane.texheight = IMXBuffer->m_iHeight; -- -- CalculateTextureSourceRects(index, 1); -- -- CDVDVideoCodecIMX::Leave(); -- } --#endif - } - - void CLinuxRendererGLES::DeleteIMXMAPTexture(int index) -@@ -2868,9 +2796,6 @@ bool CLinuxRendererGLES::Supports(EDEINTERLACEMODE mode) - if(m_renderMethod & RENDER_CVREF) - return false; - -- if(m_renderMethod & RENDER_IMXMAP) -- return false; -- - if(mode == VS_DEINTERLACEMODE_AUTO - || mode == VS_DEINTERLACEMODE_FORCE) - return true; -@@ -2899,13 +2824,19 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method) - if(m_renderMethod & RENDER_CVREF) - return false; - -- if(m_renderMethod & RENDER_IMXMAP) -- return false; -- - if(method == VS_INTERLACEMETHOD_AUTO) - return true; - --#if defined(__i386__) || defined(__x86_64__) -+ if(m_renderMethod & RENDER_IMXMAP) -+ { -+ if(method == VS_INTERLACEMETHOD_IMX_FASTMOTION -+ || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE) -+ return true; -+ else -+ return false; -+ } -+ -+#if !defined(TARGET_ANDROID) && (defined(__i386__) || defined(__x86_64__)) - if(method == VS_INTERLACEMETHOD_DEINTERLACE - || method == VS_INTERLACEMETHOD_DEINTERLACE_HALF - || method == VS_INTERLACEMETHOD_SW_BLEND) -@@ -2926,6 +2857,9 @@ bool CLinuxRendererGLES::Supports(ESCALINGMETHOD method) - return itr != m_scalingMethods.end(); - } - -+ if(m_renderMethod & RENDER_IMXMAP) -+ return false; -+ - if(method == VS_SCALINGMETHOD_NEAREST - || method == VS_SCALINGMETHOD_LINEAR) - return true; -@@ -2954,7 +2888,7 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod() - return VS_INTERLACEMETHOD_NONE; - - if(m_renderMethod & RENDER_IMXMAP) -- return VS_INTERLACEMETHOD_NONE; -+ return VS_INTERLACEMETHOD_IMX_FASTMOTION; - - #if defined(__i386__) || defined(__x86_64__) - return VS_INTERLACEMETHOD_DEINTERLACE_HALF; -@@ -2970,6 +2904,9 @@ unsigned int CLinuxRendererGLES::GetOptimalBufferSize() - m_format == RENDER_FMT_EGLIMG || - m_format == RENDER_FMT_MEDIACODEC) - return 2; -+ else if(m_format == RENDER_FMT_IMXMAP) -+ // Let the codec control the buffer size -+ return GetMaxBufferSize(); - else - return 3; - } -@@ -3061,7 +2998,7 @@ void CLinuxRendererGLES::AddProcessor(CDVDVideoCodecIMXBuffer *buffer, int index - - bool CLinuxRendererGLES::IsGuiLayer() - { -- if (m_format == RENDER_FMT_BYPASS) -+ if (m_format == RENDER_FMT_BYPASS || m_format == RENDER_FMT_IMXMAP) - return false; - else - return true; -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index b865033..ce5356d 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -42,6 +42,9 @@ namespace Shaders { class BaseVideoFilterShader; } - class COpenMaxVideo; - class CDVDVideoCodecStageFright; - class CDVDMediaCodecInfo; -+#ifdef HAS_IMXVPU -+class CDVDVideoCodecIMXBuffer; -+#endif - typedef std::vector Features; - - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -index ca0abcc..65adced 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -@@ -20,25 +20,34 @@ - - #include "DVDVideoCodecIMX.h" - --#include --#include --#include --#include --#include --#include -+#include "settings/AdvancedSettings.h" - #include "threads/SingleLock.h" -+#include "threads/Atomics.h" - #include "utils/log.h" - #include "DVDClock.h" --#include "settings/AdvancedSettings.h" --#include "threads/Atomics.h" - -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IMX_VDI_MAX_WIDTH 968 - #define FRAME_ALIGN 16 - #define MEDIAINFO 1 -+#define RENDER_QUEUE_SIZE 3 - #define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) - #define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) -+#define Align2(ptr,align) (((unsigned int)ptr)/(align)*(align)) -+ -+ -+// Global instance -+CIMXContext g_IMXContext; -+ - - // Experiments show that we need at least one more (+1) VPU buffer than the min value returned by the VPU --const int CDVDVideoCodecIMX::m_extraVpuBuffers = 6; -+const int CDVDVideoCodecIMX::m_extraVpuBuffers = 1+RENDER_QUEUE_SIZE+2; - const int CDVDVideoCodecIMX::m_maxVpuDecodeLoops = 5; - CCriticalSection CDVDVideoCodecIMX::m_codecBufferLock; - -@@ -90,8 +99,8 @@ bool CDVDVideoCodecIMX::VpuAllocBuffers(VpuMemInfo *pMemBlock) - return true; - - AllocFailure: -- VpuFreeBuffers(); -- return false; -+ VpuFreeBuffers(); -+ return false; - } - - int CDVDVideoCodecIMX::VpuFindBuffer(void *frameAddr) -@@ -104,7 +113,7 @@ int CDVDVideoCodecIMX::VpuFindBuffer(void *frameAddr) - return -1; - } - --bool CDVDVideoCodecIMX::VpuFreeBuffers(void) -+bool CDVDVideoCodecIMX::VpuFreeBuffers() - { - VpuMemDesc vpuMem; - VpuDecRetCode vpuRet; -@@ -135,7 +144,7 @@ bool CDVDVideoCodecIMX::VpuFreeBuffers(void) - vpuRet = VPU_DecFreeMem(&vpuMem); - if(vpuRet != VPU_DEC_RET_SUCCESS) - { -- CLog::Log(LOGERROR, "%s - Errror while trying to free physical memory (%d).\n", __FUNCTION__, ret); -+ CLog::Log(LOGERROR, "%s - Error while trying to free physical memory (%d).\n", __FUNCTION__, ret); - ret = false; - } - } -@@ -148,7 +157,7 @@ bool CDVDVideoCodecIMX::VpuFreeBuffers(void) - } - - --bool CDVDVideoCodecIMX::VpuOpen(void) -+bool CDVDVideoCodecIMX::VpuOpen() - { - VpuDecRetCode ret; - VpuVersionInfo vpuVersion; -@@ -185,7 +194,11 @@ bool CDVDVideoCodecIMX::VpuOpen(void) - VpuAllocBuffers(&memInfo); - - m_decOpenParam.nReorderEnable = 1; -+#ifdef IMX_INPUT_FORMAT_I420 -+ m_decOpenParam.nChromaInterleave = 0; -+#else - m_decOpenParam.nChromaInterleave = 1; -+#endif - m_decOpenParam.nMapType = 0; - m_decOpenParam.nTiled2LinearEnable = 0; - m_decOpenParam.nEnableFileMode = 0; -@@ -206,6 +219,24 @@ bool CDVDVideoCodecIMX::VpuOpen(void) - goto VpuOpenError; - } - -+ config = VPU_DEC_CONF_BUFDELAY; -+ param = 0; -+ ret = VPU_DecConfig(m_vpuHandle, config, ¶m); -+ if (ret != VPU_DEC_RET_SUCCESS) -+ { -+ CLog::Log(LOGERROR, "%s - iMX VPU set buffer delay failed (%d).\n", __FUNCTION__, ret); -+ goto VpuOpenError; -+ } -+ -+ config = VPU_DEC_CONF_INPUTTYPE; -+ param = VPU_DEC_IN_NORMAL; -+ ret = VPU_DecConfig(m_vpuHandle, config, ¶m); -+ if (ret != VPU_DEC_RET_SUCCESS) -+ { -+ CLog::Log(LOGERROR, "%s - iMX VPU configure input type failed (%d).\n", __FUNCTION__, ret); -+ goto VpuOpenError; -+ } -+ - // Note that libvpufsl (file vpu_wrapper.c) associates VPU_DEC_CAP_FRAMESIZE - // capability to the value of nDecFrameRptEnabled which is in fact directly - // related to the ability to generate VPU_DEC_ONE_FRM_CONSUMED even if the -@@ -225,52 +256,78 @@ VpuOpenError: - return false; - } - --bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void) -+bool CDVDVideoCodecIMX::VpuAllocFrameBuffers() - { -+ int totalSize = 0; -+ int ySize = 0; -+ int uSize = 0; -+ int vSize = 0; -+ int mvSize = 0; -+ int yStride = 0; -+ int uvStride = 0; -+ - VpuDecRetCode ret; - VpuMemDesc vpuMem; -- int totalSize=0; -- int mvSize=0; -- int ySize=0; -- int uvSize=0; -- int yStride=0; -- int uvStride=0; - unsigned char* ptr; - unsigned char* ptrVirt; - int nAlign; - -- m_vpuFrameBufferNum = m_initInfo.nMinFrameBufferCount + m_extraVpuBuffers; -+ m_vpuFrameBufferNum = m_initInfo.nMinFrameBufferCount + m_extraVpuBuffers; - m_vpuFrameBuffers = new VpuFrameBuffer[m_vpuFrameBufferNum]; - -- yStride=Align(m_initInfo.nPicWidth,FRAME_ALIGN); -+ yStride = Align(m_initInfo.nPicWidth,FRAME_ALIGN); - if(m_initInfo.nInterlace) - { -- ySize=Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,(2*FRAME_ALIGN)); -+ ySize = Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,(2*FRAME_ALIGN)); - } - else - { -- ySize=Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,FRAME_ALIGN); -+ ySize = Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,FRAME_ALIGN); - } - -- //NV12 for all video -- uvStride=yStride; -- uvSize=ySize/2; -- mvSize=uvSize/2; -+#ifdef IMX_INPUT_FORMAT_I420 -+ switch (m_initInfo.nMjpgSourceFormat) -+ { -+ case 0: // I420 (4:2:0) -+ uvStride = yStride / 2; -+ uSize = vSize = mvSize = ySize / 4; -+ break; -+ case 1: // Y42B (4:2:2 horizontal) -+ uvStride = yStride / 2; -+ uSize = vSize = mvSize = ySize / 2; -+ break; -+ case 3: // Y444 (4:4:4) -+ uvStride = yStride; -+ uSize = vSize = mvSize = ySize; -+ break; -+ default: -+ CLog::Log(LOGERROR, "%s: invalid source format in init info\n",__FUNCTION__,ret); -+ return false; -+ } -+ -+#else -+ // NV12 -+ uvStride = yStride; -+ uSize = ySize/2; -+ mvSize = uSize/2; -+#endif - -- nAlign=m_initInfo.nAddressAlignment; -+ nAlign = m_initInfo.nAddressAlignment; - if(nAlign>1) - { -- ySize=Align(ySize,nAlign); -- uvSize=Align(uvSize,nAlign); -+ ySize = Align(ySize, nAlign); -+ uSize = Align(uSize, nAlign); -+ vSize = Align(vSize, nAlign); -+ mvSize = Align(mvSize, nAlign); - } - - m_outputBuffers = new CDVDVideoCodecIMXBuffer*[m_vpuFrameBufferNum]; - - for (int i=0 ; i < m_vpuFrameBufferNum; i++) - { -- totalSize=(ySize+uvSize+mvSize+nAlign)*1; -+ totalSize = ySize + uSize + vSize + mvSize + nAlign; - -- vpuMem.nSize=totalSize; -+ vpuMem.nSize = totalSize; - ret = VPU_DecGetMem(&vpuMem); - if(ret != VPU_DEC_RET_SUCCESS) - { -@@ -287,42 +344,52 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void) - m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nSize = vpuMem.nSize; - - //fill frameBuf -- ptr=(unsigned char*)vpuMem.nPhyAddr; -- ptrVirt=(unsigned char*)vpuMem.nVirtAddr; -+ ptr = (unsigned char*)vpuMem.nPhyAddr; -+ ptrVirt = (unsigned char*)vpuMem.nVirtAddr; - - //align the base address - if(nAlign>1) - { -- ptr=(unsigned char*)Align(ptr,nAlign); -- ptrVirt=(unsigned char*)Align(ptrVirt,nAlign); -+ ptr = (unsigned char*)Align(ptr,nAlign); -+ ptrVirt = (unsigned char*)Align(ptrVirt,nAlign); - } - - // fill stride info -- m_vpuFrameBuffers[i].nStrideY=yStride; -- m_vpuFrameBuffers[i].nStrideC=uvStride; -+ m_vpuFrameBuffers[i].nStrideY = yStride; -+ m_vpuFrameBuffers[i].nStrideC = uvStride; - - // fill phy addr -- m_vpuFrameBuffers[i].pbufY=ptr; -- m_vpuFrameBuffers[i].pbufCb=ptr+ySize; -- m_vpuFrameBuffers[i].pbufCr=0; -- m_vpuFrameBuffers[i].pbufMvCol=ptr+ySize+uvSize; -+ m_vpuFrameBuffers[i].pbufY = ptr; -+ m_vpuFrameBuffers[i].pbufCb = ptr + ySize; -+#ifdef IMX_INPUT_FORMAT_I420 -+ m_vpuFrameBuffers[i].pbufCr = ptr + ySize + uSize; -+#else -+ m_vpuFrameBuffers[i].pbufCr = 0; -+#endif -+ m_vpuFrameBuffers[i].pbufMvCol = ptr + ySize + uSize + vSize; - - // fill virt addr -- m_vpuFrameBuffers[i].pbufVirtY=ptrVirt; -- m_vpuFrameBuffers[i].pbufVirtCb=ptrVirt+ySize; -- m_vpuFrameBuffers[i].pbufVirtCr=0; -- m_vpuFrameBuffers[i].pbufVirtMvCol=ptrVirt+ySize+uvSize; -+ m_vpuFrameBuffers[i].pbufVirtY = ptrVirt; -+ m_vpuFrameBuffers[i].pbufVirtCb = ptrVirt + ySize; -+#ifdef IMX_INPUT_FORMAT_I420 -+ m_vpuFrameBuffers[i].pbufVirtCr = ptrVirt + ySize + uSize; -+#else -+ m_vpuFrameBuffers[i].pbufVirtCr = 0; -+#endif -+ m_vpuFrameBuffers[i].pbufVirtMvCol = ptrVirt + ySize + uSize + vSize; - -- m_vpuFrameBuffers[i].pbufY_tilebot=0; -- m_vpuFrameBuffers[i].pbufCb_tilebot=0; -- m_vpuFrameBuffers[i].pbufVirtY_tilebot=0; -- m_vpuFrameBuffers[i].pbufVirtCb_tilebot=0; -+ m_vpuFrameBuffers[i].pbufY_tilebot = 0; -+ m_vpuFrameBuffers[i].pbufCb_tilebot = 0; -+ m_vpuFrameBuffers[i].pbufVirtY_tilebot = 0; -+ m_vpuFrameBuffers[i].pbufVirtCb_tilebot = 0; - - #ifdef TRACE_FRAMES - m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer(i); - #else -- m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer(); -+ m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer; - #endif -+ // Those buffers are ours so lock them to prevent destruction -+ m_outputBuffers[i]->Lock(); - } - - return true; -@@ -335,6 +402,7 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX() - m_vpuFrameBuffers = NULL; - m_outputBuffers = NULL; - m_lastBuffer = NULL; -+ m_currentBuffer = NULL; - m_extraMem = NULL; - m_vpuFrameBufferNum = 0; - m_dropState = false; -@@ -349,6 +417,9 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX() - m_convert_bitstream = false; - m_bytesToBeConsumed = 0; - m_previousPts = DVD_NOPTS_VALUE; -+#ifdef DUMP_STREAM -+ m_dump = NULL; -+#endif - } - - CDVDVideoCodecIMX::~CDVDVideoCodecIMX() -@@ -364,6 +435,26 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) - return false; - } - -+ if (!g_IMXContext.Configure()) -+ return false; -+ -+#ifdef DUMP_STREAM -+ m_dump = fopen("stream.dump", "wb"); -+ if (m_dump != NULL) -+ { -+ fwrite(&hints.software, sizeof(hints.software), 1, m_dump); -+ fwrite(&hints.codec, sizeof(hints.codec), 1, m_dump); -+ fwrite(&hints.profile, sizeof(hints.profile), 1, m_dump); -+ fwrite(&hints.codec_tag, sizeof(hints.codec_tag), 1, m_dump); -+ fwrite(&hints.extrasize, sizeof(hints.extrasize), 1, m_dump); -+ CLog::Log(LOGNOTICE, "Dump: HEADER: %d %d %d %d %d\n", -+ hints.software, hints.codec, hints.profile, -+ hints.codec_tag, hints.extrasize); -+ if (hints.extrasize > 0) -+ fwrite(hints.extradata, 1, hints.extrasize, m_dump); -+ } -+#endif -+ - m_hints = hints; - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "Let's decode with iMX VPU\n"); -@@ -494,17 +585,26 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) - return true; - } - --void CDVDVideoCodecIMX::Dispose(void) -+void CDVDVideoCodecIMX::Dispose() - { -+#ifdef DUMP_STREAM -+ if (m_dump) -+ { -+ fclose(m_dump); -+ m_dump = NULL; -+ } -+#endif -+ -+ g_IMXContext.Clear(); -+ - VpuDecRetCode ret; - bool VPU_loaded = m_vpuHandle; - -- // Prevent rendering thread from using frame buffers -- Enter(); -- - // Release last buffer -- if(m_lastBuffer) -- SAFE_RELEASE(m_lastBuffer); -+ SAFE_RELEASE(m_lastBuffer); -+ SAFE_RELEASE(m_currentBuffer); -+ -+ Enter(); - - // Invalidate output buffers to prevent the renderer from mapping this memory - for (int i=0; iClose(); - SAFE_DELETE(m_converter); - } -+ - return; - } - -@@ -579,9 +680,26 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - - #ifdef IMX_PROFILE - static unsigned long long previous, current; -+#endif -+#if defined(IMX_PROFILE) || defined(IMX_PROFILE_BUFFERS) - unsigned long long before_dec; - #endif - -+#ifdef DUMP_STREAM -+ if (m_dump != NULL) -+ { -+ if (pData) -+ { -+ fwrite(&dts, sizeof(double), 1, m_dump); -+ fwrite(&pts, sizeof(double), 1, m_dump); -+ fwrite(&iSize, sizeof(int), 1, m_dump); -+ fwrite(pData, 1, iSize, m_dump); -+ } -+ } -+#endif -+ -+ SAFE_RELEASE(m_currentBuffer); -+ - if (!m_vpuHandle) - { - VpuOpen(); -@@ -610,6 +728,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - if ((pData && iSize) || - (m_bytesToBeConsumed)) - { -+ //printf("D %f %d\n", pts, iSize); - if ((m_convert_bitstream) && (iSize)) - { - // convert demuxer packet from bitstream to bytestream (AnnexB) -@@ -638,16 +757,24 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - inData.sCodecData.nSize = 0; - } - -+#ifdef IMX_PROFILE_BUFFERS -+ static unsigned long long dec_time = 0; -+#endif -+ - while (true) // Decode as long as the VPU consumes data - { --#ifdef IMX_PROFILE -+#if defined(IMX_PROFILE) || defined(IMX_PROFILE_BUFFERS) - before_dec = XbmcThreads::SystemClockMillis(); - #endif - if (m_frameReported) - m_bytesToBeConsumed += inData.nSize; - ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet); -+#ifdef IMX_PROFILE_BUFFERS -+ unsigned long long dec_single_call = XbmcThreads::SystemClockMillis()-before_dec; -+ dec_time += dec_single_call; -+#endif - #ifdef IMX_PROFILE -- CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec); -+ CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec); - #endif - - if (ret != VPU_DEC_RET_SUCCESS) -@@ -736,14 +863,53 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - m_frameInfo.pExtInfo->nFrmWidth = (((m_frameInfo.pExtInfo->nFrmWidth) + 15) & ~15); - m_frameInfo.pExtInfo->nFrmHeight = (((m_frameInfo.pExtInfo->nFrmHeight) + 15) & ~15); - -- /* quick & dirty fix to get proper timestamping for VP8 codec */ -- if (m_decOpenParam.CodecFormat == VPU_V_VP8) -+ idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY); -+ if (idx != -1) - { -- idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY); -- m_outputBuffers[idx]->SetPts(pts); -- } -+ CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[idx]; - -- retStatus |= VC_PICTURE; -+ /* quick & dirty fix to get proper timestamping for VP8 codec */ -+ if (m_decOpenParam.CodecFormat == VPU_V_VP8) -+ buffer->SetPts(pts); -+ -+ buffer->Lock(); -+ buffer->SetDts(dts); -+ buffer->Queue(&m_frameInfo, m_lastBuffer); -+ -+#ifdef IMX_PROFILE_BUFFERS -+ CLog::Log(LOGNOTICE, "+D %f %lld\n", buffer->GetPts(), dec_time); -+ dec_time = 0; -+#endif -+ -+#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts); -+#endif -+ -+ if (!m_usePTS) -+ { -+ buffer->SetPts(DVD_NOPTS_VALUE); -+ buffer->SetDts(DVD_NOPTS_VALUE); -+ } -+ -+ // Save last buffer -+ SAFE_RELEASE(m_lastBuffer); -+ m_lastBuffer = buffer; -+ m_lastBuffer->Lock(); -+ -+#ifdef IMX_PROFILE_BUFFERS -+ static unsigned long long lastD = 0; -+ unsigned long long current = XbmcThreads::SystemClockMillis(), tmp; -+ CLog::Log(LOGNOTICE, "+V %f %lld\n", buffer->GetPts(), current-lastD); -+ lastD = current; -+#endif -+ -+ m_currentBuffer = buffer; -+ -+ if (m_currentBuffer) -+ { -+ retStatus |= VC_PICTURE; -+ } -+ } - } //VPU_DEC_OUTPUT_DIS - - // According to libfslvpuwrap: If this flag is set then the frame should -@@ -822,10 +988,8 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - } // Decode loop - } //(pData && iSize) - -- if (retStatus == 0) -- { -+ if (!retStatus) - retStatus |= VC_BUFFER; -- } - - if (m_bytesToBeConsumed > 0) - { -@@ -835,8 +999,6 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - // at next call... - m_previousPts = pts; - } -- // Store current dts (will be used only if VC_PICTURE is set) -- m_dts = dts; - - #ifdef IMX_PROFILE - CLog::Log(LOGDEBUG, "%s - returns %x - duration %lld\n", __FUNCTION__, retStatus, XbmcThreads::SystemClockMillis() - previous); -@@ -855,8 +1017,8 @@ void CDVDVideoCodecIMX::Reset() - CLog::Log(LOGDEBUG, "%s - called\n", __FUNCTION__); - - // Release last buffer -- if(m_lastBuffer) -- SAFE_RELEASE(m_lastBuffer); -+ SAFE_RELEASE(m_lastBuffer); -+ SAFE_RELEASE(m_currentBuffer); - - // Invalidate all buffers - for(int i=0; i < m_vpuFrameBufferNum; i++) -@@ -872,12 +1034,11 @@ void CDVDVideoCodecIMX::Reset() - { - CLog::Log(LOGERROR, "%s - VPU flush failed with error code %d.\n", __FUNCTION__, ret); - } -- - } - - unsigned CDVDVideoCodecIMX::GetAllowedReferences() - { -- return 3; -+ return RENDER_QUEUE_SIZE; - } - - bool CDVDVideoCodecIMX::ClearPicture(DVDVideoPicture* pDvdVideoPicture) -@@ -909,46 +1070,29 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) - else - pDvdVideoPicture->iFlags &= ~DVP_FLAG_DROPPED; - -+ if (m_initInfo.nInterlace) -+ pDvdVideoPicture->iFlags |= DVP_FLAG_INTERLACED; -+ else -+ pDvdVideoPicture->iFlags &= ~DVP_FLAG_INTERLACED; -+ -+ if (m_currentBuffer->GetFieldType() != VPU_FIELD_BOTTOM && m_currentBuffer->GetFieldType() != VPU_FIELD_BT) -+ pDvdVideoPicture->iFlags |= DVP_FLAG_TOP_FIELD_FIRST; -+ else -+ pDvdVideoPicture->iFlags &= ~DVP_FLAG_TOP_FIELD_FIRST; -+ - pDvdVideoPicture->format = RENDER_FMT_IMXMAP; -- pDvdVideoPicture->dts = DVD_NOPTS_VALUE; - pDvdVideoPicture->iWidth = m_frameInfo.pExtInfo->FrmCropRect.nRight - m_frameInfo.pExtInfo->FrmCropRect.nLeft; - pDvdVideoPicture->iHeight = m_frameInfo.pExtInfo->FrmCropRect.nBottom - m_frameInfo.pExtInfo->FrmCropRect.nTop; - - pDvdVideoPicture->iDisplayWidth = ((pDvdVideoPicture->iWidth * m_frameInfo.pExtInfo->nQ16ShiftWidthDivHeightRatio) + 32767) >> 16; - pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight; - -- int idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY); -- if (idx != -1) -- { -- CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[idx]; -- -- pDvdVideoPicture->pts = buffer->GetPts(); -- pDvdVideoPicture->dts = m_dts; -- if (!m_usePTS) -- { -- pDvdVideoPicture->pts = DVD_NOPTS_VALUE; -- pDvdVideoPicture->dts = DVD_NOPTS_VALUE; -- } -+ // Current buffer is locked already -> hot potato -+ pDvdVideoPicture->pts = m_currentBuffer->GetPts(); -+ pDvdVideoPicture->dts = m_currentBuffer->GetDts(); - -- buffer->Queue(&m_frameInfo, m_lastBuffer); -- --#ifdef TRACE_FRAMES -- CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts); --#endif -- -- pDvdVideoPicture->IMXBuffer = buffer; -- pDvdVideoPicture->IMXBuffer->Lock(); -- -- // Save last buffer -- if (m_lastBuffer) -- SAFE_RELEASE(m_lastBuffer); -- m_lastBuffer = buffer; -- m_lastBuffer->Lock(); -- } -- else -- { -- CLog::Log(LOGERROR, "%s - could not find frame buffer\n", __FUNCTION__); -- } -+ pDvdVideoPicture->IMXBuffer = m_currentBuffer; -+ m_currentBuffer = NULL; - - return true; - } -@@ -980,44 +1124,54 @@ void CDVDVideoCodecIMX::Leave() - } - - /*******************************************/ -- - #ifdef TRACE_FRAMES - CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer(int idx) -- : m_refs(1) -- , m_idx(idx) -+ : m_idx(idx) -+ , - #else - CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer() -- : m_refs(1) -+ : - #endif -+ m_pts(DVD_NOPTS_VALUE) -+ , m_dts(DVD_NOPTS_VALUE) - , m_frameBuffer(NULL) - , m_rendered(false) -- , m_pts(DVD_NOPTS_VALUE) - , m_previousBuffer(NULL) - { - } - -+void CDVDVideoCodecIMXBuffer::SetPts(double pts) -+{ -+ m_pts = pts; -+} -+ -+void CDVDVideoCodecIMXBuffer::SetDts(double dts) -+{ -+ m_dts = dts; -+} -+ - void CDVDVideoCodecIMXBuffer::Lock() - { - #ifdef TRACE_FRAMES -- long count = AtomicIncrement(&m_refs); -+ long count = AtomicIncrement(&m_iRefs); - CLog::Log(LOGDEBUG, "R+ %02d - ref : %d (VPU)\n", m_idx, count); - #else -- AtomicIncrement(&m_refs); -+ AtomicIncrement(&m_iRefs); - #endif - } - - long CDVDVideoCodecIMXBuffer::Release() - { -- long count = AtomicDecrement(&m_refs); -+ long count = AtomicDecrement(&m_iRefs); - #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "R- %02d - ref : %d (VPU)\n", m_idx, count); - #endif - if (count == 2) - { -- // Only referenced by the coded and its next frame, release the previous -+ // Only referenced by the codec and its next frame, release the previous - SAFE_RELEASE(m_previousBuffer); - } -- if (count == 1) -+ else if (count == 1) - { - // If count drops to 1 then the only reference is being held by the codec - // that it can be released in the next Decode call. -@@ -1043,6 +1197,16 @@ bool CDVDVideoCodecIMXBuffer::IsValid() - return m_frameBuffer != NULL; - } - -+void CDVDVideoCodecIMXBuffer::BeginRender() -+{ -+ CDVDVideoCodecIMX::Enter(); -+} -+ -+void CDVDVideoCodecIMXBuffer::EndRender() -+{ -+ CDVDVideoCodecIMX::Leave(); -+} -+ - bool CDVDVideoCodecIMXBuffer::Rendered() const - { - return m_rendered; -@@ -1059,10 +1223,16 @@ void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo, - if (m_previousBuffer) - m_previousBuffer->Lock(); - -- m_iWidth = frameInfo->pExtInfo->nFrmWidth; -- m_iHeight = frameInfo->pExtInfo->nFrmHeight; -- m_VirtAddr = m_frameBuffer->pbufVirtY; -- m_phyAddr = m_frameBuffer->pbufY; -+#ifdef IMX_INPUT_FORMAT_I420 -+ iFormat = _4CC('I', '4', '2', '0'); -+#else -+ iFormat = _4CC('N', 'V', '1', '2'); -+#endif -+ iWidth = frameInfo->pExtInfo->nFrmWidth; -+ iHeight = frameInfo->pExtInfo->nFrmHeight; -+ pVirtAddr = m_frameBuffer->pbufVirtY; -+ pPhysAddr = (int)m_frameBuffer->pbufY; -+ m_fieldType = frameInfo->eFieldType; - } - - VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle) -@@ -1082,31 +1252,679 @@ VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle) - #endif - m_rendered = false; - m_frameBuffer = NULL; -- m_pts = DVD_NOPTS_VALUE; -+ SetPts(DVD_NOPTS_VALUE); - SAFE_RELEASE(m_previousBuffer); - - return ret; - } - --void CDVDVideoCodecIMXBuffer::SetPts(double pts) -+CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer() - { -- m_pts = pts; -+ assert(m_iRefs == 0); -+#ifdef TRACE_FRAMES -+ CLog::Log(LOGDEBUG, "~ %02d (VPU)\n", m_idx); -+#endif - } - --double CDVDVideoCodecIMXBuffer::GetPts(void) const -+CIMXContext::CIMXContext() -+ : CThread("iMX IPU") -+ , m_fbHandle(0) -+ , m_fbPages(0) -+ , m_fbPhysAddr(0) -+ , m_fbVirtAddr(NULL) -+ , m_ipuHandle(0) -+ , m_vsync(true) -+ , m_pageCrops(NULL) - { -- return m_pts; -+ // Limit queue to 2 -+ m_input.resize(2); -+ m_beginInput = m_endInput = m_bufferedInput = 0; - } - --CDVDVideoCodecIMXBuffer *CDVDVideoCodecIMXBuffer::GetPreviousBuffer() const -+CIMXContext::~CIMXContext() - { -- return m_previousBuffer; -+ Close(); - } - --CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer() -+bool CIMXContext::Configure(int pages) - { -- assert(m_refs == 0); --#ifdef TRACE_FRAMES -- CLog::Log(LOGDEBUG, "~ %02d (VPU)\n", m_idx); -+ SetBlitRects(CRectInt(), CRectInt()); -+ m_fbCurrentPage = 0; -+ -+ int fb0 = open("/dev/fb0", O_RDWR, 0); -+ -+ if (fb0 < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to open /dev/fb0\n"); -+ return false; -+ } -+ -+ struct fb_var_screeninfo fbVar; -+ if (ioctl(fb0, FBIOGET_VSCREENINFO, &fbVar) < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to read primary screen resolution\n"); -+ close(fb0); -+ return false; -+ } -+ -+ close(fb0); -+ -+ if (m_fbHandle) -+ { -+ // Check for updated screen resolution -+ if ((m_fbWidth != fbVar.xres) || (m_fbHeight != fbVar.yres) || (pages != m_fbPages)) -+ Close(); -+ else -+ { -+ Clear(); -+ Unblank(); -+ return true; -+ } -+ } -+ -+ CLog::Log(LOGNOTICE, "iMX : Initialize render buffers\n"); -+ -+ memcpy(&m_fbVar, &fbVar, sizeof(fbVar)); -+ -+ const char *deviceName = "/dev/fb1"; -+ -+ m_fbHandle = open(deviceName, O_RDWR | O_NONBLOCK, 0); -+ if (m_fbHandle < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to open framebuffer: %s\n", deviceName); -+ return false; -+ } -+ -+ m_fbWidth = m_fbVar.xres; -+ m_fbHeight = m_fbVar.yres; -+ -+ if (ioctl(m_fbHandle, FBIOGET_VSCREENINFO, &m_fbVar) < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to query variable screen info at %s\n", deviceName); -+ return false; -+ } -+ -+ // We want n fb pages -+ m_fbPages = pages; -+ m_pageCrops = new CRectInt[m_fbPages]; -+ -+ m_fbVar.xoffset = 0; -+ m_fbVar.yoffset = 0; -+ m_fbVar.bits_per_pixel = 16; -+ m_fbVar.nonstd = _4CC('U', 'Y', 'V', 'Y'); -+ m_fbVar.activate = FB_ACTIVATE_NOW; -+ m_fbVar.xres = m_fbWidth; -+ m_fbVar.yres = m_fbHeight; -+ // One additional line that is required for deinterlacing -+ m_fbVar.yres_virtual = (m_fbVar.yres+1) * m_fbPages; -+ m_fbVar.xres_virtual = m_fbVar.xres; -+ -+ if (ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar) < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", deviceName); -+ close(m_fbHandle); -+ m_fbHandle = 0; -+ m_fbPages = 0; -+ return false; -+ } -+ -+ struct fb_fix_screeninfo fb_fix; -+ if (ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix) < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", deviceName); -+ close(m_fbHandle); -+ m_fbHandle = 0; -+ m_fbPages = 0; -+ return false; -+ } -+ -+ // Final setup -+ m_fbLineLength = fb_fix.line_length; -+ m_fbPhysSize = fb_fix.smem_len; -+ m_fbPageSize = m_fbLineLength * m_fbVar.yres_virtual / m_fbPages; -+ m_fbPhysAddr = fb_fix.smem_start; -+ m_fbVirtAddr = (uint8_t*)mmap(0, m_fbPhysSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fbHandle, 0); -+ -+ CLog::Log(LOGDEBUG, "iMX : Allocated %d render buffers\n", m_fbPages); -+ -+ m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0); -+ if (m_ipuHandle < 0) -+ { -+ CLog::Log(LOGWARNING, "iMX : Failed to initialize IPU: %s\n", strerror(errno)); -+ m_ipuHandle = 0; -+ Close(); -+ return false; -+ } -+ -+ Clear(); -+ Unblank(); -+ -+ // Start the ipu thread -+ Create(); -+ return true; -+} -+ -+bool CIMXContext::Close() -+{ -+ CLog::Log(LOGINFO, "iMX : Closing context\n"); -+ -+ // Stop the ipu thread -+ StopThread(); -+ -+ if (m_pageCrops) -+ { -+ delete[] m_pageCrops; -+ m_pageCrops = NULL; -+ } -+ -+ if (m_fbVirtAddr) -+ { -+ Clear(); -+ munmap(m_fbVirtAddr, m_fbPhysSize); -+ m_fbVirtAddr = NULL; -+ } -+ -+ if (m_fbHandle) -+ { -+ Blank(); -+ close(m_fbHandle); -+ m_fbPages = 0; -+ m_fbHandle = 0; -+ m_fbPhysAddr = 0; -+ } -+ -+ if (m_ipuHandle) -+ { -+ // Close IPU device -+ if (close(m_ipuHandle)) -+ CLog::Log(LOGERROR, "iMX : Failed to close IPU: %s\n", strerror(errno)); -+ -+ m_ipuHandle = 0; -+ } -+ -+ CLog::Log(LOGNOTICE, "iMX : Deinitialized render context\n", m_fbPages); -+ -+ return true; -+} -+ -+bool CIMXContext::GetPageInfo(CIMXBuffer *info, int page) -+{ -+ if (page < 0 || page >= m_fbPages) -+ return false; -+ -+ info->iWidth = m_fbWidth; -+ info->iHeight = m_fbHeight; -+ info->iFormat = m_fbVar.nonstd; -+ info->pPhysAddr = m_fbPhysAddr + page*m_fbPageSize; -+ info->pVirtAddr = m_fbVirtAddr + page*m_fbPageSize; -+ -+ return true; -+} -+ -+bool CIMXContext::Blank() -+{ -+ if (!m_fbHandle) return false; -+ return ioctl(m_fbHandle, FBIOBLANK, 1) == 0; -+} -+ -+bool CIMXContext::Unblank() -+{ -+ if (!m_fbHandle) return false; -+ return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_UNBLANK) == 0; -+} -+ -+bool CIMXContext::SetVSync(bool enable) -+{ -+ m_vsync = enable; -+} -+ -+void CIMXContext::SetDoubleRate(bool flag) -+{ -+ if (flag) -+ m_currentFieldFmt |= IPU_DEINTERLACE_RATE_EN; -+ else -+ m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_EN; -+ -+ m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_FRAME1; -+} -+ -+bool CIMXContext::DoubleRate() const -+{ -+ return m_currentFieldFmt & IPU_DEINTERLACE_RATE_EN; -+} -+ -+void CIMXContext::SetInterpolatedFrame(bool flag) -+{ -+ if (flag) -+ m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_FRAME1; -+ else -+ m_currentFieldFmt |= IPU_DEINTERLACE_RATE_FRAME1; -+} -+ -+void CIMXContext::SetDeInterlacing(bool flag) -+{ -+ m_deInterlacing = flag; -+} -+ -+void CIMXContext::SetBlitRects(const CRect &srcRect, const CRect &dstRect) -+{ -+ m_srcRect = srcRect; -+ m_dstRect = dstRect; -+} -+ -+bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields) -+{ -+ if (page < 0 || page >= m_fbPages) -+ return false; -+ -+ IPUTask ipu; -+ PrepareTask(ipu, source_p, source, topBottomFields); -+ return DoTask(ipu, page); -+} -+ -+bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields) -+{ -+ IPUTask ipu; -+ PrepareTask(ipu, source_p, source, topBottomFields); -+ return PushTask(ipu); -+} -+ -+bool CIMXContext::ShowPage(int page) -+{ -+ int ret; -+ -+ if (!m_fbHandle) return false; -+ if (page < 0 || page >= m_fbPages) return false; -+ -+ // Protect page swapping from screen capturing that does read the current -+ // front buffer. This is actually not done very frequently so the lock -+ // does not hurt. -+ CSingleLock lk(m_pageSwapLock); -+ -+ m_fbCurrentPage = page; -+ m_fbVar.activate = FB_ACTIVATE_VBL; -+ m_fbVar.yoffset = (m_fbVar.yres+1)*page; -+ if ((ret = ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar)) < 0) -+ CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); -+ -+ // Wait for sync -+ if (m_vsync) -+ { -+ if (ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) -+ CLog::Log(LOGWARNING, "Vsync failed: %s\n", strerror(errno)); -+ } -+ -+ return true; -+} -+ -+void CIMXContext::Clear(int page) -+{ -+ if (!m_fbVirtAddr) return; -+ -+ uint8_t *tmp_buf; -+ int pixels; -+ -+ if (page < 0) -+ { -+ tmp_buf = m_fbVirtAddr; -+ pixels = m_fbPageSize*m_fbPages/2; -+ } -+ else if (page < m_fbPages) -+ { -+ tmp_buf = m_fbVirtAddr + page*m_fbPageSize; -+ pixels = m_fbPageSize/2; -+ } -+ else -+ // out of range -+ return; -+ -+ for (int i = 0; i < pixels; ++i, tmp_buf += 2) -+ { -+ tmp_buf[0] = 128; -+ tmp_buf[1] = 16; -+ } -+} -+ -+#define clamp_byte(x) (x<0?0:(x>255?255:x)) -+ -+void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) -+{ -+ if (m_fbVar.nonstd != _4CC('U', 'Y', 'V', 'Y')) -+ { -+ CLog::Log(LOGWARNING, "iMX : Unknown screen capture format\n"); -+ return; -+ } -+ -+ // Prevent page swaps -+ CSingleLock lk(m_pageSwapLock); -+ if (m_fbCurrentPage < 0 || m_fbCurrentPage >= m_fbPages) -+ { -+ CLog::Log(LOGWARNING, "iMX : Invalid page to capture\n"); -+ return; -+ } -+ -+ int r,g,b,a; -+ int u, y0, v, y1; -+ -+ unsigned char *display = m_fbVirtAddr + m_fbCurrentPage*m_fbPageSize; -+ int iStride = m_fbWidth*2; -+ int oStride = iWidth*4; -+ -+ int cy = 1*(1 << 16); -+ int cr1 = 1.40200*(1 << 16); -+ int cr2 = -0.71414*(1 << 16); -+ int cr3 = 0*(1 << 16); -+ int cb1 = 0*(1 << 16); -+ int cb2 = -0.34414*(1 << 16); -+ int cb3 = 1.77200*(1 << 16); -+ -+ iWidth = std::min(iWidth/2, m_fbWidth/2); -+ iHeight = std::min(iHeight, m_fbHeight); -+ -+ for (int y = 0; y < iHeight; ++y, display += iStride, buffer += oStride) -+ { -+ unsigned char *iLine = display; -+ unsigned char *oLine = buffer; -+ -+ for (int x = 0; x < iWidth; ++x, iLine += 4, oLine += 8 ) -+ { -+ u = iLine[0]-128; -+ y0 = iLine[1]-16; -+ v = iLine[2]-128; -+ y1 = iLine[3]-16; -+ -+ a = 255-oLine[3]; -+ r = (cy*y0 + cb1*u + cr1*v) >> 16; -+ g = (cy*y0 + cb2*u + cr2*v) >> 16; -+ b = (cy*y0 + cb3*u + cr3*v) >> 16; -+ -+ oLine[0] = (clamp_byte(b)*a + oLine[0]*oLine[3])/255; -+ oLine[1] = (clamp_byte(g)*a + oLine[1]*oLine[3])/255; -+ oLine[2] = (clamp_byte(r)*a + oLine[2]*oLine[3])/255; -+ oLine[3] = 255; -+ -+ a = 255-oLine[7]; -+ r = (cy*y0 + cb1*u + cr1*v) >> 16; -+ g = (cy*y0 + cb2*u + cr2*v) >> 16; -+ b = (cy*y0 + cb3*u + cr3*v) >> 16; -+ -+ oLine[4] = (clamp_byte(b)*a + oLine[4]*oLine[7])/255; -+ oLine[5] = (clamp_byte(g)*a + oLine[5]*oLine[7])/255; -+ oLine[6] = (clamp_byte(r)*a + oLine[6]*oLine[7])/255; -+ oLine[7] = 255; -+ } -+ } -+} -+ -+bool CIMXContext::PushTask(const IPUTask &task) -+{ -+ if (!task.current) -+ return false; -+ -+ CSingleLock lk(m_monitor); -+ -+ if (m_bStop) -+ { -+ m_inputNotEmpty.notifyAll(); -+ return false; -+ } -+ -+ // If the input queue is full, wait for a free slot -+ while ((m_bufferedInput == m_input.size()) && !m_bStop) -+ m_inputNotFull.wait(lk); -+ -+ if (m_bStop) -+ { -+ m_inputNotEmpty.notifyAll(); -+ return false; -+ } -+ -+ // Store the value -+ if (task.previous) task.previous->Lock(); -+ task.current->Lock(); -+ -+ memcpy(&m_input[m_endInput], &task, sizeof(IPUTask)); -+ m_endInput = (m_endInput+1) % m_input.size(); -+ ++m_bufferedInput; -+ m_inputNotEmpty.notifyAll(); -+ -+ return true; -+} -+ -+void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, -+ bool topBottomFields) -+{ -+ // Fill with zeros -+ ipu.Zero(); -+ ipu.previous = source_p; -+ ipu.current = source; -+ -+ CRect srcRect = m_srcRect; -+ CRect dstRect = m_dstRect; -+ CRectInt iSrcRect, iDstRect; -+ -+ float srcWidth = srcRect.Width(); -+ float srcHeight = srcRect.Height(); -+ float dstWidth = dstRect.Width(); -+ float dstHeight = dstRect.Height(); -+ -+ // Project coordinates outside the target buffer rect to -+ // the source rect otherwise the IPU task will fail -+ // This is under the assumption that the srcRect is always -+ // inside the input buffer rect. If that is not the case -+ // it needs to be projected to the ouput buffer rect as well -+ if (dstRect.x1 < 0) -+ { -+ srcRect.x1 -= dstRect.x1*srcWidth / dstWidth; -+ dstRect.x1 = 0; -+ } -+ if (dstRect.x2 > m_fbWidth) -+ { -+ srcRect.x2 -= (dstRect.x2-m_fbWidth)*srcWidth / dstWidth; -+ dstRect.x2 = m_fbWidth; -+ } -+ if (dstRect.y1 < 0) -+ { -+ srcRect.y1 -= dstRect.y1*srcHeight / dstHeight; -+ dstRect.y1 = 0; -+ } -+ if (dstRect.y2 > m_fbHeight) -+ { -+ srcRect.y2 -= (dstRect.y2-m_fbHeight)*srcHeight / dstHeight; -+ dstRect.y2 = m_fbHeight; -+ } -+ -+ iSrcRect.x1 = Align((int)srcRect.x1,8); -+ iSrcRect.y1 = Align((int)srcRect.y1,8); -+ iSrcRect.x2 = Align((int)srcRect.x2,8); -+ iSrcRect.y2 = Align((int)srcRect.y2,8); -+ -+ iDstRect.x1 = Align((int)dstRect.x1,8); -+ iDstRect.y1 = Align((int)dstRect.y1,8); -+ iDstRect.x2 = Align((int)dstRect.x2,8); -+ iDstRect.y2 = Align((int)dstRect.y2,8); -+ -+ ipu.task.input.crop.pos.x = iSrcRect.x1; -+ ipu.task.input.crop.pos.y = iSrcRect.y1; -+ ipu.task.input.crop.w = iSrcRect.Width(); -+ ipu.task.input.crop.h = iSrcRect.Height(); -+ -+ ipu.task.output.crop.pos.x = iDstRect.x1; -+ ipu.task.output.crop.pos.y = iDstRect.y1; -+ ipu.task.output.crop.w = iDstRect.Width(); -+ ipu.task.output.crop.h = iDstRect.Height(); -+ -+ // Setup deinterlacing if enabled -+ if (m_deInterlacing) -+ { -+ ipu.task.input.deinterlace.enable = 1; -+ /* -+ if (source_p) -+ { -+ task.input.deinterlace.motion = MED_MOTION; -+ task.input.paddr = source_p->pPhysAddr; -+ task.input.paddr_n = source->pPhysAddr; -+ } -+ else -+ */ -+ ipu.task.input.deinterlace.motion = HIGH_MOTION; -+ ipu.task.input.deinterlace.field_fmt = m_currentFieldFmt; -+ -+ if (topBottomFields) -+ ipu.task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_TOP; -+ else -+ ipu.task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_BOTTOM; -+ } -+} -+ -+bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) -+{ -+ // Clear page if cropping changes -+ CRectInt dstRect(ipu.task.output.crop.pos.x, ipu.task.output.crop.pos.y, -+ ipu.task.output.crop.pos.x + ipu.task.output.crop.w, -+ ipu.task.output.crop.pos.y + ipu.task.output.crop.h); -+ -+ // Populate input block -+ ipu.task.input.width = ipu.current->iWidth; -+ ipu.task.input.height = ipu.current->iHeight; -+ ipu.task.input.format = ipu.current->iFormat; -+ ipu.task.input.paddr = ipu.current->pPhysAddr; -+ -+ // Populate output block -+ ipu.task.output.width = m_fbWidth; -+ ipu.task.output.height = m_fbHeight; -+ ipu.task.output.format = m_fbVar.nonstd; -+ ipu.task.output.paddr = m_fbPhysAddr + targetPage*m_fbPageSize; -+ -+ if (m_pageCrops[targetPage] != dstRect) -+ { -+ m_pageCrops[targetPage] = dstRect; -+ Clear(targetPage); -+ } -+ -+ if ((ipu.task.input.crop.w <= 0) || (ipu.task.input.crop.h <= 0) -+ || (ipu.task.output.crop.w <= 0) || (ipu.task.output.crop.h <= 0)) -+ return false; -+ -+#ifdef IMX_PROFILE_BUFFERS -+ unsigned long long before = XbmcThreads::SystemClockMillis(); - #endif -+ -+ int ret = IPU_CHECK_ERR_INPUT_CROP; -+ while (ret != IPU_CHECK_OK && ret > IPU_CHECK_ERR_MIN) -+ { -+ ret = ioctl(m_ipuHandle, IPU_CHECK_TASK, &ipu.task); -+ switch (ret) -+ { -+ case IPU_CHECK_OK: -+ break; -+ case IPU_CHECK_ERR_SPLIT_INPUTW_OVER: -+ ipu.task.input.crop.w -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_INPUTH_OVER: -+ ipu.task.input.crop.h -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER: -+ ipu.task.output.crop.w -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER: -+ ipu.task.output.crop.h -= 8; -+ break; -+ default: -+ CLog::Log(LOGWARNING, "iMX : unhandled IPU check error: %d\n", ret); -+ return false; -+ } -+ } -+ -+ // Need to find another interface to protect ipu.current from disposing -+ // in CDVDVideoCodecIMX::Dispose. CIMXContext must not have knowledge -+ // about CDVDVideoCodecIMX. -+ ipu.current->BeginRender(); -+ if (ipu.current->IsValid()) -+ ret = ioctl(m_ipuHandle, IPU_QUEUE_TASK, &ipu.task); -+ else -+ ret = 0; -+ ipu.current->EndRender(); -+ -+ if (ret < 0) -+ { -+ CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno)); -+ return false; -+ } -+ -+ // Duplicate 2nd scandline if double rate is active -+ if (ipu.task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) -+ { -+ uint8_t *pageAddr = m_fbVirtAddr + targetPage*m_fbPageSize; -+ memcpy(pageAddr, pageAddr+m_fbLineLength, m_fbLineLength); -+ } -+ -+#ifdef IMX_PROFILE_BUFFERS -+ unsigned long long after = XbmcThreads::SystemClockMillis(); -+ CLog::Log(LOGNOTICE, "+P %f %d\n", ((CDVDVideoCodecIMXBuffer*)ipu.current)->GetPts(), (int)(after-before)); -+#endif -+ -+ return true; -+} -+ -+void CIMXContext::OnStartup() -+{ -+ CLog::Log(LOGNOTICE, "iMX : IPU thread started"); -+} -+ -+void CIMXContext::OnExit() -+{ -+ CLog::Log(LOGNOTICE, "iMX : IPU thread terminated"); -+} -+ -+void CIMXContext::StopThread(bool bWait /*= true*/) -+{ -+ CThread::StopThread(false); -+ m_inputNotFull.notifyAll(); -+ m_inputNotEmpty.notifyAll(); -+ if (bWait) -+ CThread::StopThread(true); -+} -+ -+void CIMXContext::Process() -+{ -+ bool ret, useBackBuffer; -+ int backBuffer; -+ -+ while (!m_bStop) -+ { -+ { -+ CSingleLock lk(m_monitor); -+ while (!m_bufferedInput && !m_bStop) -+ m_inputNotEmpty.wait(lk); -+ -+ if (m_bStop) break; -+ -+ useBackBuffer = m_vsync; -+ IPUTask &task = m_input[m_beginInput]; -+ backBuffer = useBackBuffer?1-m_fbCurrentPage:m_fbCurrentPage; -+ ret = DoTask(task, backBuffer); -+ -+ // Free resources -+ task.Done(); -+ -+ m_beginInput = (m_beginInput+1) % m_input.size(); -+ --m_bufferedInput; -+ m_inputNotFull.notifyAll(); -+ } -+ -+ // Show back buffer -+ if (useBackBuffer && ret) ShowPage(backBuffer); -+ } -+ -+ // Mark all pending jobs as done -+ CSingleLock lk(m_monitor); -+ while (m_bufferedInput > 0) -+ { -+ m_input[m_beginInput].Done(); -+ m_beginInput = (m_beginInput+1) % m_input.size(); -+ --m_bufferedInput; -+ } -+ -+ return; - } -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -index 6533683..dca3f2f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -@@ -18,17 +18,201 @@ - * . - * - */ --#include --#include --#include "DVDVideoCodec.h" --#include "DVDStreamInfo.h" -+ - #include "threads/CriticalSection.h" -+#include "threads/Condition.h" -+#include "threads/Thread.h" - #include "utils/BitstreamConverter.h" -+#include "guilib/Geometry.h" -+#include "DVDVideoCodec.h" -+#include "DVDStreamInfo.h" -+ -+#include -+#include -+#include -+#include -+ - -+// The decoding format of the VPU buffer. Comment this to decode -+// as NV12. The VPU works faster with NV12 in combination with -+// deinterlacing. -+// Progressive content seems to be handled faster with I420 whereas -+// interlaced content is processed faster with NV12 as output format. -+//#define IMX_INPUT_FORMAT_I420 -+ -+// This enables logging of times for Decode, Render->Render, -+// Deinterlace. It helps to profile several stages of -+// processing with respect to changed kernels or other configurations. -+// Since we utilize VPU, IPU and GPU at the same time different kernel -+// priorities to those subsystems can result in a very different user -+// experience. With that setting enabled we can build some statistics, -+// as numbers are always better than "feelings" -+//#define IMX_PROFILE_BUFFERS - - //#define IMX_PROFILE - //#define TRACE_FRAMES - -+// If uncommented a file "stream.dump" will be created in the current -+// directory whenever a new stream is started. This is only for debugging -+// and performance tests. This define must never be active in distributions. -+//#define DUMP_STREAM -+ -+ -+/*>> TO BE MOVED TO A MORE CENTRAL PLACE IN THE SOURCE DIR >>>>>>>>>>>>>>>>>>>*/ -+// Generell description of a buffer used by -+// the IMX context, e.g. for blitting -+class CIMXBuffer { -+public: -+ CIMXBuffer() : m_iRefs(0) {} -+ -+ // Shared pointer interface -+ virtual void Lock() = 0; -+ virtual long Release() = 0; -+ virtual bool IsValid() = 0; -+ -+ virtual void BeginRender() = 0; -+ virtual void EndRender() = 0; -+ -+public: -+ uint32_t iWidth; -+ uint32_t iHeight; -+ int pPhysAddr; -+ uint8_t *pVirtAddr; -+ int iFormat; -+ -+protected: -+ long m_iRefs; -+}; -+ -+ -+// iMX context class that handles all iMX hardware -+// related stuff -+class CIMXContext : private CThread -+{ -+public: -+ CIMXContext(); -+ ~CIMXContext(); -+ -+ bool Configure(int pages = 2); -+ bool Close(); -+ -+ bool Blank(); -+ bool Unblank(); -+ bool SetVSync(bool enable); -+ -+ bool IsValid() const { return m_fbPages > 0; } -+ -+ // Returns the number of available pages -+ int PageCount() const { return m_fbPages; } -+ -+ // Populates a CIMXBuffer with attributes of a page -+ bool GetPageInfo(CIMXBuffer *info, int page); -+ -+ // Blitter configuration -+ void SetDeInterlacing(bool flag); -+ void SetDoubleRate(bool flag); -+ bool DoubleRate() const; -+ void SetInterpolatedFrame(bool flag); -+ -+ void SetBlitRects(const CRect &srcRect, const CRect &dstRect); -+ -+ // Blits a buffer to a particular page. -+ // source_p (previous buffer) is required for de-interlacing -+ // modes LOW_MOTION and MED_MOTION. -+ bool Blit(int targetPage, CIMXBuffer *source_p, -+ CIMXBuffer *source, -+ bool topBottomFields = true); -+ -+ // Same as blit but runs in another thread and returns after the task has -+ // been queued. BlitAsync renders always to the current backbuffer and -+ // swaps the pages. -+ bool BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, -+ bool topBottomFields = true); -+ -+ // Shows a page vsynced -+ bool ShowPage(int page); -+ -+ // Returns the visible page -+ int GetCurrentPage() const { return m_fbCurrentPage; } -+ -+ // Clears the pages or a single page with 'black' -+ void Clear(int page = -1); -+ -+ // Captures the current visible frame buffer page and blends it into -+ // the passed overlay. The buffer format is BGRA (4 byte) -+ void CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight); -+ -+private: -+ struct IPUTask -+ { -+ void Zero() -+ { -+ current = previous = NULL; -+ memset(&task, 0, sizeof(task)); -+ } -+ -+ void Done() -+ { -+ SAFE_RELEASE(previous); -+ SAFE_RELEASE(current); -+ } -+ -+ // Kept for reference -+ CIMXBuffer *previous; -+ CIMXBuffer *current; -+ -+ // The actual task -+ struct ipu_task task; -+ }; -+ -+ bool PushTask(const IPUTask &); -+ void PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, -+ bool topBottomFields); -+ bool DoTask(IPUTask &ipu, int targetPage); -+ -+ virtual void OnStartup(); -+ virtual void OnExit(); -+ virtual void StopThread(bool bWait = true); -+ virtual void Process(); -+ -+private: -+ typedef std::vector TaskQueue; -+ -+ int m_fbHandle; -+ int m_fbPages; -+ int m_fbCurrentPage; -+ int m_fbWidth; -+ int m_fbHeight; -+ int m_fbLineLength; -+ int m_fbPageSize; -+ int m_fbPhysSize; -+ int m_fbPhysAddr; -+ uint8_t *m_fbVirtAddr; -+ struct fb_var_screeninfo m_fbVar; -+ int m_ipuHandle; -+ int m_currentFieldFmt; -+ bool m_vsync; -+ bool m_deInterlacing; -+ CRect m_srcRect; -+ CRect m_dstRect; -+ CRectInt m_inputRect; -+ CRectInt m_outputRect; -+ CRectInt *m_pageCrops; -+ -+ CCriticalSection m_pageSwapLock; -+ TaskQueue m_input; -+ volatile int m_beginInput, m_endInput; -+ volatile size_t m_bufferedInput; -+ XbmcThreads::ConditionVariable m_inputNotEmpty; -+ XbmcThreads::ConditionVariable m_inputNotFull; -+ mutable CCriticalSection m_monitor; -+}; -+ -+ -+extern CIMXContext g_IMXContext; -+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ -+ -+ - class CDecMemInfo - { - public: -@@ -40,16 +224,17 @@ public: - {} - - //virtual mem info -- int nVirtNum; -- void** virtMem; -+ int nVirtNum; -+ void **virtMem; - - //phy mem info -- int nPhyNum; -- VpuMemDesc* phyMem; -+ int nPhyNum; -+ VpuMemDesc *phyMem; - }; - --class CDVDVideoCodecIMXBuffer --{ -+ -+// Base class of IMXVPU and IMXIPU buffer -+class CDVDVideoCodecIMXBuffer : public CIMXBuffer { - public: - #ifdef TRACE_FRAMES - CDVDVideoCodecIMXBuffer(int idx); -@@ -58,94 +243,98 @@ public: - #endif - - // reference counting -- virtual void Lock(); -- virtual long Release(); -- virtual bool IsValid(); -- -- bool Rendered() const; -- void Queue(VpuDecOutFrameInfo *frameInfo, -- CDVDVideoCodecIMXBuffer *previous); -- VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle); -- void SetPts(double pts); -- double GetPts(void) const; -- CDVDVideoCodecIMXBuffer *GetPreviousBuffer() const; -- -- uint32_t m_iWidth; -- uint32_t m_iHeight; -- uint8_t *m_phyAddr; -- uint8_t *m_VirtAddr; -+ virtual void Lock(); -+ virtual long Release(); -+ virtual bool IsValid(); -+ -+ virtual void BeginRender(); -+ virtual void EndRender(); -+ -+ void SetPts(double pts); -+ double GetPts() const { return m_pts; } -+ -+ void SetDts(double dts); -+ double GetDts() const { return m_dts; } -+ -+ bool Rendered() const; -+ void Queue(VpuDecOutFrameInfo *frameInfo, -+ CDVDVideoCodecIMXBuffer *previous); -+ VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle); -+ CDVDVideoCodecIMXBuffer *GetPreviousBuffer() const { return m_previousBuffer; } -+ VpuFieldType GetFieldType() const { return m_fieldType; } - - private: - // private because we are reference counted -- virtual ~CDVDVideoCodecIMXBuffer(); -+ virtual ~CDVDVideoCodecIMXBuffer(); - --private: -+protected: - #ifdef TRACE_FRAMES - int m_idx; - #endif -- long m_refs; -+ -+private: -+ double m_pts; -+ double m_dts; -+ VpuFieldType m_fieldType; - VpuFrameBuffer *m_frameBuffer; - bool m_rendered; -- double m_pts; -- CDVDVideoCodecIMXBuffer *m_previousBuffer; // Holds a the reference counted -- // previous buffer -+ CDVDVideoCodecIMXBuffer *m_previousBuffer; // Holds the reference counted previous buffer - }; - -+ - class CDVDVideoCodecIMX : public CDVDVideoCodec - { -- friend class CDVDVideoCodecIMXBuffer; -- friend class CDVDVideoCodecIPUBuffer; -- - public: - CDVDVideoCodecIMX(); - virtual ~CDVDVideoCodecIMX(); - - // Methods from CDVDVideoCodec which require overrides - virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options); -- virtual void Dispose(void); -+ virtual void Dispose(); - virtual int Decode(BYTE *pData, int iSize, double dts, double pts); -- virtual void Reset(void); -+ virtual void Reset(); - virtual bool ClearPicture(DVDVideoPicture *pDvdVideoPicture); - virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); - virtual void SetDropState(bool bDrop); -- virtual const char* GetName(void) { return (const char*)m_pFormatName; } -+ virtual const char* GetName() { return (const char*)m_pFormatName; } - virtual unsigned GetAllowedReferences(); - - static void Enter(); - static void Leave(); - - protected: -- - bool VpuOpen(); - bool VpuAllocBuffers(VpuMemInfo *); - bool VpuFreeBuffers(); - bool VpuAllocFrameBuffers(); - int VpuFindBuffer(void *frameAddr); - -- static const int m_extraVpuBuffers; // Number of additional buffers for VPU -- static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop -- static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled -- // by both decoding and rendering threads -- -- CDVDStreamInfo m_hints; // Hints from demuxer at stream opening -- const char *m_pFormatName; // Current decoder format name -- VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen -- CDecMemInfo m_decMemInfo; // VPU dedicated memory description -- VpuDecHandle m_vpuHandle; // Handle for VPU library calls -- VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start -- bool m_dropState; // Current drop state -- int m_vpuFrameBufferNum; // Total number of allocated frame buffers -- VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description -- CDVDVideoCodecIMXBuffer **m_outputBuffers; // Table of VPU output buffers -- CDVDVideoCodecIMXBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin) -- VpuMemDesc *m_extraMem; // Table of allocated extra Memory -- int m_frameCounter; // Decoded frames counter -- bool m_usePTS; // State whether pts out of decoding process should be used -- VpuDecOutFrameInfo m_frameInfo; // Store last VPU output frame info -- CBitstreamConverter *m_converter; // H264 annex B converter -- bool m_convert_bitstream; // State whether bitstream conversion is required -- int m_bytesToBeConsumed; // Remaining bytes in VPU -- double m_previousPts; // Enable to keep pts when needed -- bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu -- double m_dts; // Current dts -+ static const int m_extraVpuBuffers; // Number of additional buffers for VPU -+ static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop -+ // by both decoding and rendering threads -+ static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled -+ CDVDStreamInfo m_hints; // Hints from demuxer at stream opening -+ const char *m_pFormatName; // Current decoder format name -+ VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen -+ CDecMemInfo m_decMemInfo; // VPU dedicated memory description -+ VpuDecHandle m_vpuHandle; // Handle for VPU library calls -+ VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start -+ bool m_dropState; // Current drop state -+ int m_vpuFrameBufferNum; // Total number of allocated frame buffers -+ VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description -+ CDVDVideoCodecIMXBuffer **m_outputBuffers; // Table of VPU output buffers -+ CDVDVideoCodecIMXBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin) -+ CDVDVideoCodecIMXBuffer *m_currentBuffer; -+ VpuMemDesc *m_extraMem; // Table of allocated extra Memory -+ int m_frameCounter; // Decoded frames counter -+ bool m_usePTS; // State whether pts out of decoding process should be used -+ VpuDecOutFrameInfo m_frameInfo; // Store last VPU output frame info -+ CBitstreamConverter *m_converter; // H264 annex B converter -+ bool m_convert_bitstream; // State whether bitstream conversion is required -+ int m_bytesToBeConsumed; // Remaining bytes in VPU -+ double m_previousPts; // Enable to keep pts when needed -+ bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu -+#ifdef DUMP_STREAM -+ FILE *m_dump; -+#endif - }; -diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp -index 126e95f..2b8c2cf 100644 ---- a/xbmc/guilib/GUIVideoControl.cpp -+++ b/xbmc/guilib/GUIVideoControl.cpp -@@ -77,7 +77,11 @@ void CGUIVideoControl::Render() - region.Intersect(old); - g_graphicsContext.BeginPaint(); - g_graphicsContext.SetScissors(region); -+#ifdef HAS_IMXVPU -+ g_graphicsContext.Clear((16 << 16)|(8 << 8)|16); -+#else - g_graphicsContext.Clear(0); -+#endif - g_graphicsContext.SetScissors(old); - g_graphicsContext.EndPaint(); - } -diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp -index db73d4a..2335178 100644 ---- a/xbmc/utils/Screenshot.cpp -+++ b/xbmc/utils/Screenshot.cpp -@@ -37,6 +37,11 @@ - #include "cores/VideoRenderers/RenderManager.h" - #endif - -+#ifdef HAS_IMXVPU -+// This has to go into another header file -+#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" -+#endif -+ - #include "filesystem/File.h" - #include "guilib/GraphicContext.h" - -@@ -156,13 +161,19 @@ bool CScreenshotSurface::capture() - for (int x = 0; x < m_width; x++, swap_pixels+=4) - { - std::swap(swap_pixels[0], swap_pixels[2]); -- } -+ } - #endif - memcpy(m_buffer + y * m_stride, surface + (m_height - y - 1) *m_stride, m_stride); - } - - delete [] surface; - -+#ifdef HAS_IMXVPU -+ // Captures the current visible framebuffer page and blends it into the -+ // captured GL overlay -+ g_IMXContext.CaptureDisplay(m_buffer, m_width, m_height); -+#endif -+ - #else - //nothing to take a screenshot from - return false; -diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp -index ed7c090..17857dd 100644 ---- a/xbmc/video/windows/GUIWindowFullScreen.cpp -+++ b/xbmc/video/windows/GUIWindowFullScreen.cpp -@@ -356,7 +356,11 @@ bool CGUIWindowFullScreen::OnAction(const CAction &action) - void CGUIWindowFullScreen::ClearBackground() - { - if (g_renderManager.IsVideoLayer()) -+#ifdef HAS_IMXVPU -+ g_graphicsContext.Clear((16 << 16)|(8 << 8)|16); -+#else - g_graphicsContext.Clear(0); -+#endif - } - - void CGUIWindowFullScreen::OnWindowLoaded() -diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -index 061f6e6..cf2f706 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include "utils/log.h" - #include "utils/RegExp.h" - #include "utils/StringUtils.h" -@@ -55,6 +56,40 @@ void CEGLNativeTypeIMX::Initialize() - { - int fd; - -+ // Check if we can change the framebuffer resolution -+ fd = open("/sys/class/graphics/fb0/mode", O_RDWR); -+ if (fd >= 0) -+ { -+ CLog::Log(LOGNOTICE, "%s - graphics sysfs is writable\n", __FUNCTION__); -+ m_readonly = false; -+ } -+ else -+ { -+ CLog::Log(LOGNOTICE, "%s - graphics sysfs is read-only\n", __FUNCTION__); -+ m_readonly = true; -+ } -+ close(fd); -+ -+ bool alphaBlending = false; -+ std::string bpp; -+ if (SysfsUtils::GetString("/sys/class/graphics/fb0/bits_per_pixel", bpp)) -+ { -+ CLog::Log(LOGWARNING, "%s - determining current bits per pixel failed, assuming 16bpp\n", __FUNCTION__); -+ } -+ else -+ { -+ StringUtils::Trim(bpp); -+ if (bpp == "32") -+ { -+ CLog::Log(LOGNOTICE, "%s - 32bpp: configure alpha blending\n", __FUNCTION__); -+ alphaBlending = true; -+ } -+ else -+ { -+ CLog::Log(LOGNOTICE, "%s - %sbpp: configure color keying\n", __FUNCTION__, bpp.c_str()); -+ } -+ } -+ - fd = open("/dev/fb0",O_RDWR); - if (fd < 0) - { -@@ -62,6 +97,27 @@ void CEGLNativeTypeIMX::Initialize() - return; - } - -+ struct mxcfb_color_key colorKey; -+ struct mxcfb_gbl_alpha gbl_alpha; -+ struct mxcfb_loc_alpha lalpha; -+ memset(&lalpha, 0, sizeof(lalpha)); -+ -+ // Configure local alpha -+ lalpha.enable = alphaBlending?1:0; -+ lalpha.alpha_in_pixel = 1; -+ if (ioctl(fd, MXCFB_SET_LOC_ALPHA, &lalpha) < 0) -+ CLog::Log(LOGERROR, "%s - Failed to setup alpha blending\n", __FUNCTION__); -+ -+ gbl_alpha.alpha = 255; -+ gbl_alpha.enable = alphaBlending?0:1; -+ if (ioctl(fd, MXCFB_SET_GBL_ALPHA, &gbl_alpha) < 0) -+ CLog::Log(LOGERROR, "%s - Failed to setup global alpha\n", __FUNCTION__); -+ -+ colorKey.enable = alphaBlending?0:1; -+ colorKey.color_key = (16 << 16)|(8 << 8)|16; -+ if (ioctl(fd, MXCFB_SET_CLR_KEY, &colorKey) < 0) -+ CLog::Log(LOGERROR, "%s - Failed to setup color keying\n", __FUNCTION__); -+ - // Unblank the fb - if (ioctl(fd, FBIOBLANK, 0) < 0) - { -@@ -70,20 +126,6 @@ void CEGLNativeTypeIMX::Initialize() - - close(fd); - -- // Check if we can change the framebuffer resolution -- fd = open("/sys/class/graphics/fb0/mode", O_RDWR); -- if (fd >= 0) -- { -- CLog::Log(LOGNOTICE, "%s - graphics sysfs is writable", __FUNCTION__); -- m_readonly = false; -- } -- else -- { -- CLog::Log(LOGNOTICE, "%s - graphics sysfs is read-only", __FUNCTION__); -- m_readonly = true; -- } -- close(fd); -- - return; - } - -diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp -index 2bdd4fa..dec2ba9 100644 ---- a/xbmc/windowing/egl/WinSystemEGL.cpp -+++ b/xbmc/windowing/egl/WinSystemEGL.cpp -@@ -31,6 +31,10 @@ - #include "settings/DisplaySettings.h" - #include "guilib/DispResource.h" - #include "threads/SingleLock.h" -+#ifdef HAS_IMXVPU -+// This has to go into another header file -+#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" -+#endif - #include "utils/log.h" - #include "EGLWrapper.h" - #include "EGLQuirks.h" -@@ -266,7 +270,7 @@ bool CWinSystemEGL::CreateNewWindow(const CStdString& name, bool fullScreen, RES - RESOLUTION_INFO current_resolution; - current_resolution.iWidth = current_resolution.iHeight = 0; - -- m_nWidth = res.iWidth; -+ m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_displayWidth = res.iScreenWidth; - m_displayHeight = res.iScreenHeight; -@@ -450,6 +454,9 @@ void CWinSystemEGL::SetVSyncImpl(bool enable) - m_iVSyncMode = 0; - CLog::Log(LOGERROR, "%s,Could not set egl vsync", __FUNCTION__); - } -+#ifdef HAS_IMXVPU -+ g_IMXContext.SetVSync(enable); -+#endif - } - - void CWinSystemEGL::ShowOSMouse(bool show) --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-13-iMX6-Implement-rendercapture-for-latest-rendering-re.patch b/projects/imx6/patches/kodi/kodi-13-iMX6-Implement-rendercapture-for-latest-rendering-re.patch deleted file mode 100644 index 68e2d3ab4b..0000000000 --- a/projects/imx6/patches/kodi/kodi-13-iMX6-Implement-rendercapture-for-latest-rendering-re.patch +++ /dev/null @@ -1,895 +0,0 @@ -From 85ca69f3fc1f9bfd30f828921db1283366c7bfea Mon Sep 17 00:00:00 2001 -From: wolfgar -Date: Sat, 14 Feb 2015 03:06:03 +0100 -Subject: [PATCH 13/16] [iMX6] Implement rendercapture for latest rendering - rework blit fb using g2d when no deinterlacing is required - ---- - configure.in | 2 +- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 12 + - xbmc/cores/VideoRenderers/RenderCapture.cpp | 43 ++- - xbmc/cores/VideoRenderers/RenderCapture.h | 28 +- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 430 +++++++++++++++------ - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 23 +- - 6 files changed, 401 insertions(+), 137 deletions(-) - -diff --git a/configure.in b/configure.in -index 32e37c5..a8cdca0 100644 ---- a/configure.in -+++ b/configure.in -@@ -1935,7 +1935,7 @@ for codecs in `echo $add_codecs | sed 's/,/ /g'`; do - ;; - *imxvpu*) - AC_CHECK_HEADER([imx-mm/vpu/vpu_wrapper.h],, AC_MSG_ERROR($missing_headers)) -- AC_CHECK_LIB([vpu], main, LIBS="$LIBS -lfslvpuwrap -lvpu", AC_MSG_ERROR($missing_library)) -+ AC_CHECK_LIB([vpu], main, LIBS="$LIBS -lfslvpuwrap -lvpu -lg2d", AC_MSG_ERROR($missing_library)) - XB_ADD_CODEC([IMXVPU], [imxvpu], [$codecs]) - CXXFLAGS="$CXXFLAGS -Wno-psabi -DLINUX " - CFLAGS="$CFLAGS -DLINUX" -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index 94fb19b..d523db4 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -1733,6 +1733,18 @@ bool CLinuxRendererGLES::RenderCapture(CRenderCapture* capture) - return true; - } - -+#ifdef HAS_IMXVPU -+ if (m_renderMethod & RENDER_IMXMAP) -+ { -+ CRect rect(0, 0, capture->GetWidth(), capture->GetHeight()); -+ CDVDVideoCodecIMXBuffer *buffer = m_buffers[m_iYV12RenderBuffer].IMXBuffer; -+ capture->BeginRender(); -+ g_IMXContext.PushCaptureTask(buffer, &rect); -+ capture->EndRender(); -+ return true; -+ } -+#endif -+ - // save current video rect - CRect saveSize = m_destRect; - saveRotatedCoords();//backup current m_rotatedDestCoords -diff --git a/xbmc/cores/VideoRenderers/RenderCapture.cpp b/xbmc/cores/VideoRenderers/RenderCapture.cpp -index 0fac398..62605c8 100644 ---- a/xbmc/cores/VideoRenderers/RenderCapture.cpp -+++ b/xbmc/cores/VideoRenderers/RenderCapture.cpp -@@ -54,7 +54,48 @@ bool CRenderCaptureBase::UseOcclusionQuery() - return true; - } - --#if defined(TARGET_RASPBERRY_PI) -+ -+#if defined(HAS_IMXVPU) -+CRenderCaptureIMX::CRenderCaptureIMX() -+{ -+} -+ -+CRenderCaptureIMX::~CRenderCaptureIMX() -+{ -+} -+ -+int CRenderCaptureIMX::GetCaptureFormat() -+{ -+ return CAPTUREFORMAT_RGBA; -+} -+ -+void CRenderCaptureIMX::BeginRender() -+{ -+ m_asyncChecked = true; -+ m_asyncSupported = true; -+} -+ -+void CRenderCaptureIMX::EndRender() -+{ -+ if (m_flags & CAPTUREFLAG_IMMEDIATELY) -+ ReadOut(); -+ else -+ SetState(CAPTURESTATE_NEEDSREADOUT); -+} -+ -+void* CRenderCaptureIMX::GetRenderBuffer() -+{ -+ return m_pixels; -+} -+ -+void CRenderCaptureIMX::ReadOut() -+{ -+ g_IMXContext.WaitCapture(); -+ m_pixels = reinterpret_cast(g_IMXContext.GetCaptureBuffer()); -+ SetState(CAPTURESTATE_DONE); -+} -+ -+#elif defined(TARGET_RASPBERRY_PI) - - CRenderCaptureDispmanX::CRenderCaptureDispmanX() - { -diff --git a/xbmc/cores/VideoRenderers/RenderCapture.h b/xbmc/cores/VideoRenderers/RenderCapture.h -index 56d269a..5610945 100644 ---- a/xbmc/cores/VideoRenderers/RenderCapture.h -+++ b/xbmc/cores/VideoRenderers/RenderCapture.h -@@ -172,7 +172,33 @@ class CRenderCaptureBase - bool m_asyncChecked; - }; - --#if defined(TARGET_RASPBERRY_PI) -+ -+#if defined(HAS_IMXVPU) -+#include "../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" -+ -+class CRenderCaptureIMX : public CRenderCaptureBase -+{ -+ public: -+ CRenderCaptureIMX(); -+ ~CRenderCaptureIMX(); -+ -+ int GetCaptureFormat(); -+ -+ void BeginRender(); -+ void EndRender(); -+ void ReadOut(); -+ -+ void* GetRenderBuffer(); -+}; -+ -+class CRenderCapture : public CRenderCaptureIMX -+{ -+ public: -+ CRenderCapture() {}; -+}; -+ -+ -+#elif defined(TARGET_RASPBERRY_PI) - #include "xbmc/linux/RBP.h" - - class CRenderCaptureDispmanX : public CRenderCaptureBase -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -index 65adced..fcd8b02 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -@@ -45,6 +45,8 @@ - // Global instance - CIMXContext g_IMXContext; - -+// Number of fb pages used for paning -+const int CIMXContext::m_fbPages = 2; - - // Experiments show that we need at least one more (+1) VPU buffer than the min value returned by the VPU - const int CDVDVideoCodecIMX::m_extraVpuBuffers = 1+RENDER_QUEUE_SIZE+2; -@@ -435,8 +437,7 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) - return false; - } - -- if (!g_IMXContext.Configure()) -- return false; -+ g_IMXContext.RequireConfiguration(); - - #ifdef DUMP_STREAM - m_dump = fopen("stream.dump", "wb"); -@@ -810,6 +811,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - { - goto out_error; - } -+ - } - else - { -@@ -882,7 +884,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - #endif - - #ifdef TRACE_FRAMES -- CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts); -+ CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, dts, pts); - #endif - - if (!m_usePTS) -@@ -1269,12 +1271,15 @@ CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer() - CIMXContext::CIMXContext() - : CThread("iMX IPU") - , m_fbHandle(0) -- , m_fbPages(0) -+ , m_fbCurrentPage(0) - , m_fbPhysAddr(0) - , m_fbVirtAddr(NULL) - , m_ipuHandle(0) - , m_vsync(true) - , m_pageCrops(NULL) -+ , m_g2dHandle(NULL) -+ , m_bufferCapture(NULL) -+ , m_checkConfigRequired(true) - { - // Limit queue to 2 - m_input.resize(2); -@@ -1286,8 +1291,13 @@ CIMXContext::~CIMXContext() - Close(); - } - --bool CIMXContext::Configure(int pages) -+ -+bool CIMXContext::Configure() - { -+ -+ if (!m_checkConfigRequired) -+ return false; -+ - SetBlitRects(CRectInt(), CRectInt()); - m_fbCurrentPage = 0; - -@@ -1310,17 +1320,7 @@ bool CIMXContext::Configure(int pages) - close(fb0); - - if (m_fbHandle) -- { -- // Check for updated screen resolution -- if ((m_fbWidth != fbVar.xres) || (m_fbHeight != fbVar.yres) || (pages != m_fbPages)) -- Close(); -- else -- { -- Clear(); -- Unblank(); -- return true; -- } -- } -+ Close(); - - CLog::Log(LOGNOTICE, "iMX : Initialize render buffers\n"); - -@@ -1344,14 +1344,20 @@ bool CIMXContext::Configure(int pages) - return false; - } - -- // We want n fb pages -- m_fbPages = pages; - m_pageCrops = new CRectInt[m_fbPages]; - - m_fbVar.xoffset = 0; - m_fbVar.yoffset = 0; -- m_fbVar.bits_per_pixel = 16; -- m_fbVar.nonstd = _4CC('U', 'Y', 'V', 'Y'); -+ if (m_deInterlacing) -+ { -+ m_fbVar.nonstd = _4CC('U', 'Y', 'V', 'Y'); -+ m_fbVar.bits_per_pixel = 16; -+ } -+ else -+ { -+ m_fbVar.nonstd = _4CC('R', 'G', 'B', '4'); -+ m_fbVar.bits_per_pixel = 32; -+ } - m_fbVar.activate = FB_ACTIVATE_NOW; - m_fbVar.xres = m_fbWidth; - m_fbVar.yres = m_fbHeight; -@@ -1364,7 +1370,6 @@ bool CIMXContext::Configure(int pages) - CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", deviceName); - close(m_fbHandle); - m_fbHandle = 0; -- m_fbPages = 0; - return false; - } - -@@ -1374,7 +1379,6 @@ bool CIMXContext::Configure(int pages) - CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", deviceName); - close(m_fbHandle); - m_fbHandle = 0; -- m_fbPages = 0; - return false; - } - -@@ -1401,6 +1405,7 @@ bool CIMXContext::Configure(int pages) - - // Start the ipu thread - Create(); -+ m_checkConfigRequired = false; - return true; - } - -@@ -1428,7 +1433,6 @@ bool CIMXContext::Close() - { - Blank(); - close(m_fbHandle); -- m_fbPages = 0; - m_fbHandle = 0; - m_fbPhysAddr = 0; - } -@@ -1442,7 +1446,8 @@ bool CIMXContext::Close() - m_ipuHandle = 0; - } - -- CLog::Log(LOGNOTICE, "iMX : Deinitialized render context\n", m_fbPages); -+ m_checkConfigRequired = true; -+ CLog::Log(LOGNOTICE, "iMX : Deinitialized render context\n"); - - return true; - } -@@ -1503,7 +1508,14 @@ void CIMXContext::SetInterpolatedFrame(bool flag) - - void CIMXContext::SetDeInterlacing(bool flag) - { -+ bool sav_deInt = m_deInterlacing; - m_deInterlacing = flag; -+ // If deinterlacing configuration changes then fb has to be reconfigured -+ if (sav_deInt != m_deInterlacing) -+ { -+ m_checkConfigRequired = true; -+ Configure(); -+ } - } - - void CIMXContext::SetBlitRects(const CRect &srcRect, const CRect &dstRect) -@@ -1522,10 +1534,18 @@ bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source, bool - return DoTask(ipu, page); - } - --bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields) -+bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields, CRect *dest) - { - IPUTask ipu; -- PrepareTask(ipu, source_p, source, topBottomFields); -+ PrepareTask(ipu, source_p, source, topBottomFields, dest); -+ return PushTask(ipu); -+} -+ -+bool CIMXContext::PushCaptureTask(CIMXBuffer *source, CRect *dest) -+{ -+ IPUTask ipu; -+ m_CaptureDone = false; -+ PrepareTask(ipu, NULL, source, false, dest); - return PushTask(ipu); - } - -@@ -1562,34 +1582,44 @@ void CIMXContext::Clear(int page) - if (!m_fbVirtAddr) return; - - uint8_t *tmp_buf; -- int pixels; -+ int bytes; - - if (page < 0) - { - tmp_buf = m_fbVirtAddr; -- pixels = m_fbPageSize*m_fbPages/2; -+ bytes = m_fbPageSize*m_fbPages; - } - else if (page < m_fbPages) - { - tmp_buf = m_fbVirtAddr + page*m_fbPageSize; -- pixels = m_fbPageSize/2; -+ bytes = m_fbPageSize; - } - else - // out of range - return; - -- for (int i = 0; i < pixels; ++i, tmp_buf += 2) -+ -+ if (m_fbVar.nonstd == _4CC('R', 'G', 'B', '4')) -+ memset(tmp_buf, 0, bytes); -+ else if (m_fbVar.nonstd == _4CC('U', 'Y', 'V', 'Y')) - { -- tmp_buf[0] = 128; -- tmp_buf[1] = 16; -+ int pixels = bytes / 2; -+ for (int i = 0; i < pixels; ++i, tmp_buf += 2) -+ { -+ tmp_buf[0] = 128; -+ tmp_buf[1] = 16; -+ } - } -+ else -+ CLog::Log(LOGERROR, "iMX Clear fb error : Unexpected format"); - } - - #define clamp_byte(x) (x<0?0:(x>255?255:x)) - - void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) - { -- if (m_fbVar.nonstd != _4CC('U', 'Y', 'V', 'Y')) -+ if ((m_fbVar.nonstd != _4CC('R', 'G', 'B', '4')) && -+ (m_fbVar.nonstd != _4CC('U', 'Y', 'V', 'Y'))) - { - CLog::Log(LOGWARNING, "iMX : Unknown screen capture format\n"); - return; -@@ -1602,56 +1632,60 @@ void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) - CLog::Log(LOGWARNING, "iMX : Invalid page to capture\n"); - return; - } -- -- int r,g,b,a; -- int u, y0, v, y1; -- - unsigned char *display = m_fbVirtAddr + m_fbCurrentPage*m_fbPageSize; -- int iStride = m_fbWidth*2; -- int oStride = iWidth*4; - -- int cy = 1*(1 << 16); -- int cr1 = 1.40200*(1 << 16); -- int cr2 = -0.71414*(1 << 16); -- int cr3 = 0*(1 << 16); -- int cb1 = 0*(1 << 16); -- int cb2 = -0.34414*(1 << 16); -- int cb3 = 1.77200*(1 << 16); -+ if (m_fbVar.nonstd != _4CC('R', 'G', 'B', '4')) -+ memcpy(buffer, display, iWidth * iHeight * 4); -+ else //_4CC('U', 'Y', 'V', 'Y'))) -+ { -+ int r,g,b,a; -+ int u, y0, v, y1; -+ int iStride = m_fbWidth*2; -+ int oStride = iWidth*4; - -- iWidth = std::min(iWidth/2, m_fbWidth/2); -- iHeight = std::min(iHeight, m_fbHeight); -+ int cy = 1*(1 << 16); -+ int cr1 = 1.40200*(1 << 16); -+ int cr2 = -0.71414*(1 << 16); -+ int cr3 = 0*(1 << 16); -+ int cb1 = 0*(1 << 16); -+ int cb2 = -0.34414*(1 << 16); -+ int cb3 = 1.77200*(1 << 16); - -- for (int y = 0; y < iHeight; ++y, display += iStride, buffer += oStride) -- { -- unsigned char *iLine = display; -- unsigned char *oLine = buffer; -+ iWidth = std::min(iWidth/2, m_fbWidth/2); -+ iHeight = std::min(iHeight, m_fbHeight); - -- for (int x = 0; x < iWidth; ++x, iLine += 4, oLine += 8 ) -+ for (int y = 0; y < iHeight; ++y, display += iStride, buffer += oStride) - { -- u = iLine[0]-128; -- y0 = iLine[1]-16; -- v = iLine[2]-128; -- y1 = iLine[3]-16; -- -- a = 255-oLine[3]; -- r = (cy*y0 + cb1*u + cr1*v) >> 16; -- g = (cy*y0 + cb2*u + cr2*v) >> 16; -- b = (cy*y0 + cb3*u + cr3*v) >> 16; -- -- oLine[0] = (clamp_byte(b)*a + oLine[0]*oLine[3])/255; -- oLine[1] = (clamp_byte(g)*a + oLine[1]*oLine[3])/255; -- oLine[2] = (clamp_byte(r)*a + oLine[2]*oLine[3])/255; -- oLine[3] = 255; -- -- a = 255-oLine[7]; -- r = (cy*y0 + cb1*u + cr1*v) >> 16; -- g = (cy*y0 + cb2*u + cr2*v) >> 16; -- b = (cy*y0 + cb3*u + cr3*v) >> 16; -- -- oLine[4] = (clamp_byte(b)*a + oLine[4]*oLine[7])/255; -- oLine[5] = (clamp_byte(g)*a + oLine[5]*oLine[7])/255; -- oLine[6] = (clamp_byte(r)*a + oLine[6]*oLine[7])/255; -- oLine[7] = 255; -+ unsigned char *iLine = display; -+ unsigned char *oLine = buffer; -+ -+ for (int x = 0; x < iWidth; ++x, iLine += 4, oLine += 8 ) -+ { -+ u = iLine[0]-128; -+ y0 = iLine[1]-16; -+ v = iLine[2]-128; -+ y1 = iLine[3]-16; -+ -+ a = 255-oLine[3]; -+ r = (cy*y0 + cb1*u + cr1*v) >> 16; -+ g = (cy*y0 + cb2*u + cr2*v) >> 16; -+ b = (cy*y0 + cb3*u + cr3*v) >> 16; -+ -+ oLine[0] = (clamp_byte(b)*a + oLine[0]*oLine[3])/255; -+ oLine[1] = (clamp_byte(g)*a + oLine[1]*oLine[3])/255; -+ oLine[2] = (clamp_byte(r)*a + oLine[2]*oLine[3])/255; -+ oLine[3] = 255; -+ -+ a = 255-oLine[7]; -+ r = (cy*y0 + cb1*u + cr1*v) >> 16; -+ g = (cy*y0 + cb2*u + cr2*v) >> 16; -+ b = (cy*y0 + cb3*u + cr3*v) >> 16; -+ -+ oLine[4] = (clamp_byte(b)*a + oLine[4]*oLine[7])/255; -+ oLine[5] = (clamp_byte(g)*a + oLine[5]*oLine[7])/255; -+ oLine[6] = (clamp_byte(r)*a + oLine[6]*oLine[7])/255; -+ oLine[7] = 255; -+ } - } - } - } -@@ -1691,16 +1725,29 @@ bool CIMXContext::PushTask(const IPUTask &task) - return true; - } - -+void CIMXContext::WaitCapture() -+{ -+ CSingleLock lk(m_monitor); -+ while (!m_CaptureDone) -+ m_inputNotFull.wait(lk); -+} -+ - void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, -- bool topBottomFields) -+ bool topBottomFields, CRect *dest) - { -+ Configure(); - // Fill with zeros - ipu.Zero(); - ipu.previous = source_p; - ipu.current = source; - - CRect srcRect = m_srcRect; -- CRect dstRect = m_dstRect; -+ CRect dstRect; -+ if (dest == NULL) -+ dstRect = m_dstRect; -+ else -+ dstRect = *dest; -+ - CRectInt iSrcRect, iDstRect; - - float srcWidth = srcRect.Width(); -@@ -1754,6 +1801,20 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so - ipu.task.output.crop.w = iDstRect.Width(); - ipu.task.output.crop.h = iDstRect.Height(); - -+ // If dest is set it means we do not want to blit to frame buffer -+ // but to a capture buffer and we state this capture buffer dimensions -+ if (dest) -+ { -+ // Populate partly output block -+ ipu.task.output.crop.pos.x = 0; -+ ipu.task.output.crop.pos.y = 0; -+ ipu.task.output.crop.w = iDstRect.Width(); -+ ipu.task.output.crop.h = iDstRect.Height(); -+ ipu.task.output.width = iDstRect.Width(); -+ ipu.task.output.height = iDstRect.Height(); -+ } -+ else -+ { - // Setup deinterlacing if enabled - if (m_deInterlacing) - { -@@ -1775,6 +1836,7 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so - else - ipu.task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_BOTTOM; - } -+ } - } - - bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) -@@ -1790,16 +1852,40 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) - ipu.task.input.format = ipu.current->iFormat; - ipu.task.input.paddr = ipu.current->pPhysAddr; - -- // Populate output block -- ipu.task.output.width = m_fbWidth; -- ipu.task.output.height = m_fbHeight; -- ipu.task.output.format = m_fbVar.nonstd; -- ipu.task.output.paddr = m_fbPhysAddr + targetPage*m_fbPageSize; -+ // Populate output block if it has not already been filled -+ if (ipu.task.output.width == 0) -+ { -+ ipu.task.output.width = m_fbWidth; -+ ipu.task.output.height = m_fbHeight; -+ ipu.task.output.format = m_fbVar.nonstd; -+ ipu.task.output.paddr = m_fbPhysAddr + targetPage*m_fbPageSize; - -- if (m_pageCrops[targetPage] != dstRect) -+ if (m_pageCrops[targetPage] != dstRect) -+ { -+ m_pageCrops[targetPage] = dstRect; -+ Clear(targetPage); -+ } -+ } -+ else - { -- m_pageCrops[targetPage] = dstRect; -- Clear(targetPage); -+ // If we have already set dest dimensions we want to use capture buffer -+ // Note we allocate this capture buffer as late as this function because -+ // all g2d functions have to be called from the same thread -+ int size = ipu.task.output.width * ipu.task.output.height * 4; -+ if ((m_bufferCapture) && (size != m_bufferCapture->buf_size)) -+ { -+ if (g2d_free(m_bufferCapture)) -+ CLog::Log(LOGERROR, "iMX : Error while freeing capture buuffer\n"); -+ m_bufferCapture = NULL; -+ } -+ -+ if (m_bufferCapture == NULL) -+ { -+ m_bufferCapture = g2d_alloc(size, 0); -+ if (m_bufferCapture == NULL) -+ CLog::Log(LOGERROR, "iMX : Error allocating capture buffer\n"); -+ } -+ ipu.task.output.paddr = m_bufferCapture->buf_paddr; - } - - if ((ipu.task.input.crop.w <= 0) || (ipu.task.input.crop.h <= 0) -@@ -1810,53 +1896,117 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) - unsigned long long before = XbmcThreads::SystemClockMillis(); - #endif - -- int ret = IPU_CHECK_ERR_INPUT_CROP; -- while (ret != IPU_CHECK_OK && ret > IPU_CHECK_ERR_MIN) -+ if (ipu.task.input.deinterlace.enable) - { -- ret = ioctl(m_ipuHandle, IPU_CHECK_TASK, &ipu.task); -- switch (ret) -+ //We really use IPU only if we have to deinterlace (using VDIC) -+ int ret = IPU_CHECK_ERR_INPUT_CROP; -+ while (ret != IPU_CHECK_OK && ret > IPU_CHECK_ERR_MIN) - { -- case IPU_CHECK_OK: -- break; -- case IPU_CHECK_ERR_SPLIT_INPUTW_OVER: -- ipu.task.input.crop.w -= 8; -- break; -- case IPU_CHECK_ERR_SPLIT_INPUTH_OVER: -- ipu.task.input.crop.h -= 8; -- break; -- case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER: -- ipu.task.output.crop.w -= 8; -- break; -- case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER: -- ipu.task.output.crop.h -= 8; -- break; -- default: -- CLog::Log(LOGWARNING, "iMX : unhandled IPU check error: %d\n", ret); -+ ret = ioctl(m_ipuHandle, IPU_CHECK_TASK, &ipu.task); -+ switch (ret) -+ { -+ case IPU_CHECK_OK: -+ break; -+ case IPU_CHECK_ERR_SPLIT_INPUTW_OVER: -+ ipu.task.input.crop.w -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_INPUTH_OVER: -+ ipu.task.input.crop.h -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER: -+ ipu.task.output.crop.w -= 8; -+ break; -+ case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER: -+ ipu.task.output.crop.h -= 8; -+ break; -+ default: -+ CLog::Log(LOGWARNING, "iMX : unhandled IPU check error: %d\n", ret); -+ return false; -+ } -+ } -+ -+ // Need to find another interface to protect ipu.current from disposing -+ // in CDVDVideoCodecIMX::Dispose. CIMXContext must not have knowledge -+ // about CDVDVideoCodecIMX. -+ ipu.current->BeginRender(); -+ if (ipu.current->IsValid()) -+ ret = ioctl(m_ipuHandle, IPU_QUEUE_TASK, &ipu.task); -+ else -+ ret = 0; -+ ipu.current->EndRender(); -+ -+ if (ret < 0) -+ { -+ CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno)); - return false; - } -- } - -- // Need to find another interface to protect ipu.current from disposing -- // in CDVDVideoCodecIMX::Dispose. CIMXContext must not have knowledge -- // about CDVDVideoCodecIMX. -- ipu.current->BeginRender(); -- if (ipu.current->IsValid()) -- ret = ioctl(m_ipuHandle, IPU_QUEUE_TASK, &ipu.task); -+ // Duplicate 2nd scandline if double rate is active -+ if (ipu.task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) -+ { -+ uint8_t *pageAddr = m_fbVirtAddr + targetPage*m_fbPageSize; -+ memcpy(pageAddr, pageAddr+m_fbLineLength, m_fbLineLength); -+ } -+ } - else -- ret = 0; -- ipu.current->EndRender(); -- -- if (ret < 0) - { -- CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno)); -- return false; -- } -+ // deinterlacing is not required, let's use g2d instead of IPU - -- // Duplicate 2nd scandline if double rate is active -- if (ipu.task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) -- { -- uint8_t *pageAddr = m_fbVirtAddr + targetPage*m_fbPageSize; -- memcpy(pageAddr, pageAddr+m_fbLineLength, m_fbLineLength); -+ struct g2d_surface src, dst; -+ memset(&src, 0, sizeof(src)); -+ memset(&dst, 0, sizeof(dst)); -+ -+ ipu.current->BeginRender(); -+ if (ipu.current->IsValid()) -+ { -+ if (ipu.current->iFormat == _4CC('I', '4', '2', '0')) -+ { -+ src.format = G2D_I420; -+ src.planes[0] = ipu.current->pPhysAddr; -+ src.planes[1] = src.planes[0] + Align(ipu.current->iWidth * ipu.current->iHeight, 64); -+ src.planes[2] = src.planes[1] + Align((ipu.current->iWidth * ipu.current->iHeight) / 2, 64); -+ } -+ else //_4CC('N', 'V', '1', '2'); -+ { -+ src.format = G2D_NV12; -+ src.planes[0] = ipu.current->pPhysAddr; -+ src.planes[1] = src.planes[0] + Align(ipu.current->iWidth * ipu.current->iHeight, 64); -+ } -+ -+ src.left = ipu.task.input.crop.pos.x; -+ src.right = ipu.task.input.crop.w + src.left ; -+ src.top = ipu.task.input.crop.pos.y; -+ src.bottom = ipu.task.input.crop.h + src.top; -+ src.stride = ipu.current->iWidth; -+ src.width = ipu.current->iWidth; -+ src.height = ipu.current->iHeight; -+ src.rot = G2D_ROTATION_0; -+ /*printf("src planes :%x -%x -%x \n",src.planes[0], src.planes[1], src.planes[2] ); -+ printf("src left %d right %d top %d bottom %d stride %d w : %d h %d rot : %d\n", -+ src.left, src.right, src.top, src.bottom, src.stride, src.width, src.height, src.rot);*/ -+ -+ dst.planes[0] = ipu.task.output.paddr; -+ dst.left = ipu.task.output.crop.pos.x; -+ dst.top = ipu.task.output.crop.pos.y; -+ dst.right = ipu.task.output.crop.w + dst.left; -+ dst.bottom = ipu.task.output.crop.h + dst.top; -+ -+ dst.stride = ipu.task.output.width; -+ dst.width = ipu.task.output.width; -+ dst.height = ipu.task.output.height; -+ dst.rot = G2D_ROTATION_0; -+ dst.format = G2D_RGBA8888; -+ /*printf("dst planes :%x -%x -%x \n",dst.planes[0], dst.planes[1], dst.planes[2] ); -+ printf("dst left %d right %d top %d bottom %d stride %d w : %d h %d rot : %d format %d\n", -+ dst.left, dst.right, dst.top, dst.bottom, dst.stride, dst.width, dst.height, dst.rot, dst.format);*/ -+ -+ // Launch synchronous blit -+ g2d_blit(m_g2dHandle, &src, &dst); -+ g2d_finish(m_g2dHandle); -+ if ((m_bufferCapture) && (ipu.task.output.paddr == m_bufferCapture->buf_paddr)) -+ m_CaptureDone = true; -+ } -+ ipu.current->EndRender(); - } - - #ifdef IMX_PROFILE_BUFFERS -@@ -1891,6 +2041,16 @@ void CIMXContext::Process() - bool ret, useBackBuffer; - int backBuffer; - -+ // open g2d here to ensure all g2d fucntions are called from the same thread -+ if (m_g2dHandle == NULL) -+ { -+ if (g2d_open(&m_g2dHandle) != 0) -+ { -+ m_g2dHandle = NULL; -+ CLog::Log(LOGERROR, "%s - Error while trying open G2D\n", __FUNCTION__); -+ } -+ } -+ - while (!m_bStop) - { - { -@@ -1903,6 +2063,10 @@ void CIMXContext::Process() - useBackBuffer = m_vsync; - IPUTask &task = m_input[m_beginInput]; - backBuffer = useBackBuffer?1-m_fbCurrentPage:m_fbCurrentPage; -+ -+ // Hack to detect we deal with capture buffer -+ if (task.task.output.width != 0) -+ useBackBuffer = false; - ret = DoTask(task, backBuffer); - - // Free resources -@@ -1926,5 +2090,19 @@ void CIMXContext::Process() - --m_bufferedInput; - } - -+ // close g2d here to ensure all g2d fucntions are called from the same thread -+ if (m_bufferCapture) -+ { -+ if (g2d_free(m_bufferCapture)) -+ CLog::Log(LOGERROR, "iMX : Failed to free capture buffers\n"); -+ m_bufferCapture = NULL; -+ } -+ if (m_g2dHandle) -+ { -+ if (g2d_close(m_g2dHandle)) -+ CLog::Log(LOGERROR, "iMX : Error while closing G2D\n"); -+ m_g2dHandle = NULL; -+ } -+ - return; - } -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -index dca3f2f..e414454 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - - // The decoding format of the VPU buffer. Comment this to decode -@@ -93,17 +94,15 @@ public: - CIMXContext(); - ~CIMXContext(); - -- bool Configure(int pages = 2); -+ void RequireConfiguration() { m_checkConfigRequired = true; } -+ bool Configure(); - bool Close(); - - bool Blank(); - bool Unblank(); - bool SetVSync(bool enable); - -- bool IsValid() const { return m_fbPages > 0; } -- -- // Returns the number of available pages -- int PageCount() const { return m_fbPages; } -+ bool IsValid() const { return m_checkConfigRequired == false; } - - // Populates a CIMXBuffer with attributes of a page - bool GetPageInfo(CIMXBuffer *info, int page); -@@ -127,7 +126,7 @@ public: - // been queued. BlitAsync renders always to the current backbuffer and - // swaps the pages. - bool BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, -- bool topBottomFields = true); -+ bool topBottomFields = true, CRect *dest = NULL); - - // Shows a page vsynced - bool ShowPage(int page); -@@ -141,6 +140,9 @@ public: - // Captures the current visible frame buffer page and blends it into - // the passed overlay. The buffer format is BGRA (4 byte) - void CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight); -+ bool PushCaptureTask(CIMXBuffer *source, CRect *dest); -+ void *GetCaptureBuffer() const { if (m_bufferCapture) return m_bufferCapture->buf_vaddr; else return NULL; } -+ void WaitCapture(); - - private: - struct IPUTask -@@ -167,7 +169,7 @@ private: - - bool PushTask(const IPUTask &); - void PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, -- bool topBottomFields); -+ bool topBottomFields, CRect *dest = NULL); - bool DoTask(IPUTask &ipu, int targetPage); - - virtual void OnStartup(); -@@ -179,7 +181,6 @@ private: - typedef std::vector TaskQueue; - - int m_fbHandle; -- int m_fbPages; - int m_fbCurrentPage; - int m_fbWidth; - int m_fbHeight; -@@ -206,6 +207,12 @@ private: - XbmcThreads::ConditionVariable m_inputNotEmpty; - XbmcThreads::ConditionVariable m_inputNotFull; - mutable CCriticalSection m_monitor; -+ -+ void *m_g2dHandle; -+ struct g2d_buf *m_bufferCapture; -+ bool m_CaptureDone; -+ bool m_checkConfigRequired; -+ static const int m_fbPages; - }; - - --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-15-imx-Output-associated-pts-for-TRACE_FRAMES.patch b/projects/imx6/patches/kodi/kodi-15-imx-Output-associated-pts-for-TRACE_FRAMES.patch deleted file mode 100644 index 7f663c51c1..0000000000 --- a/projects/imx6/patches/kodi/kodi-15-imx-Output-associated-pts-for-TRACE_FRAMES.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1ec717d9197fb0086c76197519f2b522b4ec73af Mon Sep 17 00:00:00 2001 -From: smallint -Date: Fri, 20 Feb 2015 15:40:29 +0100 -Subject: [PATCH 15/16] [imx] Output associated pts for TRACE_FRAMES - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -index fcd8b02..7789e38 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp -@@ -885,6 +885,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) - - #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, dts, pts); -+ CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, buffer->GetDts(), buffer->GetPts()); - #endif - - if (!m_usePTS) --- -1.9.3 - diff --git a/projects/imx6/patches/kodi/kodi-16-Add-guard-to-fix-build-on-non-iMX6-arch.patch b/projects/imx6/patches/kodi/kodi-16-Add-guard-to-fix-build-on-non-iMX6-arch.patch deleted file mode 100644 index 6bf9b479b7..0000000000 --- a/projects/imx6/patches/kodi/kodi-16-Add-guard-to-fix-build-on-non-iMX6-arch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d2113f254cabde119734440620d16aca7444acd8 Mon Sep 17 00:00:00 2001 -From: wolfgar -Date: Sat, 21 Feb 2015 23:45:26 +0100 -Subject: [PATCH 16/16] Add guard to fix build on non iMX6 arch - ---- - xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -index 25dbc9b..f482075 100644 ---- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -+++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp -@@ -96,7 +96,7 @@ void CEGLNativeTypeIMX::Initialize() - CLog::Log(LOGERROR, "%s - Error while opening /dev/fb0.\n", __FUNCTION__); - return; - } -- -+#ifdef HAS_IMXVPU - struct mxcfb_color_key colorKey; - struct mxcfb_gbl_alpha gbl_alpha; - struct mxcfb_loc_alpha lalpha; -@@ -117,7 +117,7 @@ void CEGLNativeTypeIMX::Initialize() - colorKey.color_key = (16 << 16)|(8 << 8)|16; - if (ioctl(fd, MXCFB_SET_CLR_KEY, &colorKey) < 0) - CLog::Log(LOGERROR, "%s - Failed to setup color keying\n", __FUNCTION__); -- -+#endif - // Unblank the fb - if (ioctl(fd, FBIOBLANK, 0) < 0) - { --- -1.9.3 -