From 3d5d9bb81010d62eb2b64fbe56378c31acafacfc Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Sat, 9 Mar 2013 14:45:13 +0200 Subject: [PATCH 01/14] tvheadend: update to tvheadend-3.3.491 --- packages/addons/service/multimedia/tvheadend/changelog.txt | 3 +++ packages/addons/service/multimedia/tvheadend/meta | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/addons/service/multimedia/tvheadend/changelog.txt b/packages/addons/service/multimedia/tvheadend/changelog.txt index 151f64fad0..e506d32d55 100644 --- a/packages/addons/service/multimedia/tvheadend/changelog.txt +++ b/packages/addons/service/multimedia/tvheadend/changelog.txt @@ -1,3 +1,6 @@ +3.0.6 +- update to TVHeadend 3.3.491 + 3.0.5 - update to TVHeadend 3.3.485 diff --git a/packages/addons/service/multimedia/tvheadend/meta b/packages/addons/service/multimedia/tvheadend/meta index 81cb85629c..66919ff43d 100644 --- a/packages/addons/service/multimedia/tvheadend/meta +++ b/packages/addons/service/multimedia/tvheadend/meta @@ -19,8 +19,8 @@ ################################################################################ PKG_NAME="tvheadend" -PKG_VERSION="3.3.485" -PKG_REV="5" +PKG_VERSION="3.3.491" +PKG_REV="6" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.lonelycoder.com/hts/tvheadend_overview.html" From 7b5bb1ecccf6f8e2d8780e23d85baec3072b9fe2 Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Sat, 9 Mar 2013 16:45:15 +0200 Subject: [PATCH 02/14] tvheadend: disable avahi support --- packages/addons/service/multimedia/tvheadend/build | 1 + packages/addons/service/multimedia/tvheadend/changelog.txt | 1 + packages/addons/service/multimedia/tvheadend/meta | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/addons/service/multimedia/tvheadend/build b/packages/addons/service/multimedia/tvheadend/build index 90c4c4481c..02fa45bdc6 100755 --- a/packages/addons/service/multimedia/tvheadend/build +++ b/packages/addons/service/multimedia/tvheadend/build @@ -36,6 +36,7 @@ cd $PKG_BUILD --cc=$TARGET_CC \ --enable-timeshift \ --disable-libav \ + --disable-avahi \ --enable-bundle make diff --git a/packages/addons/service/multimedia/tvheadend/changelog.txt b/packages/addons/service/multimedia/tvheadend/changelog.txt index e506d32d55..c912a5a531 100644 --- a/packages/addons/service/multimedia/tvheadend/changelog.txt +++ b/packages/addons/service/multimedia/tvheadend/changelog.txt @@ -1,5 +1,6 @@ 3.0.6 - update to TVHeadend 3.3.491 +- disable avahi support 3.0.5 - update to TVHeadend 3.3.485 diff --git a/packages/addons/service/multimedia/tvheadend/meta b/packages/addons/service/multimedia/tvheadend/meta index 66919ff43d..84d329f3d4 100644 --- a/packages/addons/service/multimedia/tvheadend/meta +++ b/packages/addons/service/multimedia/tvheadend/meta @@ -26,8 +26,8 @@ PKG_LICENSE="GPL" PKG_SITE="http://www.lonelycoder.com/hts/tvheadend_overview.html" #PKG_URL="https://github.com/downloads/tvheadend/tvheadend/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_URL="$DISTRO_SRC/${PKG_NAME}-${PKG_VERSION}.tar.gz" -PKG_DEPENDS="$ICONV avahi openssl curl" -PKG_BUILD_DEPENDS="toolchain $ICONV avahi openssl curl" +PKG_DEPENDS="$ICONV openssl curl" +PKG_BUILD_DEPENDS="toolchain $ICONV openssl curl" PKG_PRIORITY="optional" PKG_SECTION="service/multimedia" PKG_SHORTDESC="tvheadend (Version: $PKG_VERSION): a TV streaming server for Linux supporting DVB-S, DVB-S2, DVB-C, DVB-T, ATSC, IPTV, and Analog video (V4L) as input sources." From 5ce4c9b9be2a27deec7479c45f227e73632ba461 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Sat, 9 Mar 2013 17:27:15 +0100 Subject: [PATCH 03/14] Move syslogd after network so we can log kernel messages to remote server Since syslogd was started before the network was up, all syslog messages before the network was up were discarded and not send to the remoe syslog server. By moving the syslogd startup until after the network, the kernel boot messages are available on the central syslog. --- packages/sysutils/busybox/init.d/{08_syslogd => 23_syslogd} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/sysutils/busybox/init.d/{08_syslogd => 23_syslogd} (94%) diff --git a/packages/sysutils/busybox/init.d/08_syslogd b/packages/sysutils/busybox/init.d/23_syslogd similarity index 94% rename from packages/sysutils/busybox/init.d/08_syslogd rename to packages/sysutils/busybox/init.d/23_syslogd index d3cf2e3242..3eb91fe548 100644 --- a/packages/sysutils/busybox/init.d/08_syslogd +++ b/packages/sysutils/busybox/init.d/23_syslogd @@ -28,10 +28,10 @@ source /var/config/settings.conf - SYSLOGD_OPTIONS="-L" + SYSLOGD_OPTIONS="-L -D" if [ "$SYSLOG_REMOTE" == "true" -a "$SYSLOG_SERVER" ]; then - SYSLOGD_OPTIONS="$SYSLOGD_OPTIONS -R $SYSLOG_SERVER" + SYSLOGD_OPTIONS="-R $SYSLOG_SERVER $SYSLOGD_OPTIONS" fi if [ -f /storage/.config/syslog.conf ]; then From fc350227e8d39404136ce5a2a91c70d4db84b6d2 Mon Sep 17 00:00:00 2001 From: Sascha Hofmann Date: Sat, 9 Mar 2013 17:52:51 +0100 Subject: [PATCH 04/14] libcec: update to libcec-2.1.1 This fixes issue https://github.com/OpenELEC/OpenELEC.tv/issues/2007 --- packages/devel/libcec/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devel/libcec/meta b/packages/devel/libcec/meta index 6734963e2c..7f94bdf2d8 100644 --- a/packages/devel/libcec/meta +++ b/packages/devel/libcec/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="libcec" -PKG_VERSION="2.1.0" +PKG_VERSION="2.1.1" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" From 24a9b86e53dbd10290719b5bf789b2d40a3dfb8d Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sat, 9 Mar 2013 19:32:36 +0100 Subject: [PATCH 05/14] eglibc: fix buildscript, thanks to seo Signed-off-by: Stephan Raue --- packages/toolchain/devel/eglibc/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/toolchain/devel/eglibc/build b/packages/toolchain/devel/eglibc/build index 1bb6880f9e..997d15d92c 100755 --- a/packages/toolchain/devel/eglibc/build +++ b/packages/toolchain/devel/eglibc/build @@ -142,7 +142,7 @@ EOF --without-gd \ --enable-obsolete-rpc \ --disable-build-nscd \ -        --disable-nscd \ + --disable-nscd \ $DEBUG_CONFIG \ make From bb68944a2fb803498eaae0ea0c8edeaf596a51d5 Mon Sep 17 00:00:00 2001 From: vpeter4 Date: Sat, 9 Mar 2013 22:38:26 +0100 Subject: [PATCH 06/14] busybox-initramfs: enable 64-bit math support in the shell which will allow computation with very large numbers This closes #2019. --- .../sysutils/busybox-initramfs/config/busybox-initramfs.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/initramfs/sysutils/busybox-initramfs/config/busybox-initramfs.conf b/packages/initramfs/sysutils/busybox-initramfs/config/busybox-initramfs.conf index 05322796d6..8f59686f18 100644 --- a/packages/initramfs/sysutils/busybox-initramfs/config/busybox-initramfs.conf +++ b/packages/initramfs/sysutils/busybox-initramfs/config/busybox-initramfs.conf @@ -997,7 +997,7 @@ CONFIG_FEATURE_BASH_IS_ASH=y # CONFIG_FEATURE_BASH_IS_HUSH is not set # CONFIG_FEATURE_BASH_IS_NONE is not set CONFIG_SH_MATH_SUPPORT=y -# CONFIG_SH_MATH_SUPPORT_64 is not set +CONFIG_SH_MATH_SUPPORT_64=y CONFIG_FEATURE_SH_EXTRA_QUIET=y CONFIG_FEATURE_SH_STANDALONE=y # CONFIG_FEATURE_SH_NOFORK is not set From aed76dd14b0ae6fb2d1172b4141cd3ae567f344c Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Sat, 9 Mar 2013 22:58:11 +0100 Subject: [PATCH 07/14] Add hostname to shell prompt (so you know what system you're logged on) --- packages/sysutils/bash/profile.d/shell.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sysutils/bash/profile.d/shell.conf b/packages/sysutils/bash/profile.d/shell.conf index 5081c35522..652518d396 100644 --- a/packages/sysutils/bash/profile.d/shell.conf +++ b/packages/sysutils/bash/profile.d/shell.conf @@ -23,7 +23,7 @@ # evironment variables that are not user defined. ################################################################################ -PS1='\[\e[0;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] ' +PS1='\[\e[0;32m\]\u\e[1;30m@\e[1;32m\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] ' export PS1 case "$TERM" in From fe22f229a3df1a0cf0d8ec7fb2a479cc5de464cd Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 13:25:39 +0100 Subject: [PATCH 08/14] xbmc: move x86 patches again back to common patches folder Signed-off-by: Stephan Raue --- .../xbmc-995.01-xvba_support-912b6ed.patch | 0 .../xbmc-995.10-disable-alt-tab.patch | 0 packages/mediacenter/xbmc/unpack | 32 ------------------- 3 files changed, 32 deletions(-) rename packages/mediacenter/xbmc/{patches.x86 => patches}/xbmc-995.01-xvba_support-912b6ed.patch (100%) rename packages/mediacenter/xbmc/{patches.x86 => patches}/xbmc-995.10-disable-alt-tab.patch (100%) delete mode 100755 packages/mediacenter/xbmc/unpack diff --git a/packages/mediacenter/xbmc/patches.x86/xbmc-995.01-xvba_support-912b6ed.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-912b6ed.patch similarity index 100% rename from packages/mediacenter/xbmc/patches.x86/xbmc-995.01-xvba_support-912b6ed.patch rename to packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-912b6ed.patch diff --git a/packages/mediacenter/xbmc/patches.x86/xbmc-995.10-disable-alt-tab.patch b/packages/mediacenter/xbmc/patches/xbmc-995.10-disable-alt-tab.patch similarity index 100% rename from packages/mediacenter/xbmc/patches.x86/xbmc-995.10-disable-alt-tab.patch rename to packages/mediacenter/xbmc/patches/xbmc-995.10-disable-alt-tab.patch diff --git a/packages/mediacenter/xbmc/unpack b/packages/mediacenter/xbmc/unpack deleted file mode 100755 index f21b1bc057..0000000000 --- a/packages/mediacenter/xbmc/unpack +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -################################################################################ -# This file is part of OpenELEC - http://www.openelec.tv -# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) -# -# 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 OpenELEC.tv; see the file COPYING. If not, write to -# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. -# http://www.gnu.org/copyleft/gpl.html -################################################################################ - -. config/options $1 - -echo "### Applying architecture based patches ###" - -if [ ! $TARGET_ARCH = arm ]; then - for patch in `ls $PKG_DIR/patches.x86`; do - cat $PKG_DIR/patches.x86/$patch | patch -d \ - `echo $PKG_BUILD | cut -f1 -d\ ` -p1 - done -fi From 9cd1ba2ff450bc9cc5f8fe140a0f02348ef6ac6a Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 13:26:39 +0100 Subject: [PATCH 09/14] xbmc: update XVBA/VDPAU patch Signed-off-by: Stephan Raue --- ...=> xbmc-995.01-xvba_support-1f1e576.patch} | 4928 +++++++++++------ 1 file changed, 3375 insertions(+), 1553 deletions(-) rename packages/mediacenter/xbmc/patches/{xbmc-995.01-xvba_support-912b6ed.patch => xbmc-995.01-xvba_support-1f1e576.patch} (86%) diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-912b6ed.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch similarity index 86% rename from packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-912b6ed.patch rename to packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch index 159eaa0f4c..45a76f534a 100644 --- a/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-912b6ed.patch +++ b/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch @@ -1,77 +1,29 @@ -From c111752701bb2447a833ef1768e912c87d9bbf65 Mon Sep 17 00:00:00 2001 -From: wsnipex -Date: Sun, 4 Nov 2012 14:05:52 +0100 -Subject: [PATCH 01/73] configure: add --enable-pvraddons-with-dependencies - switch for intree building of PVR Addons - ---- - configure.in | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/configure.in b/configure.in -index 4769315..350d960 100644 ---- a/configure.in -+++ b/configure.in -@@ -521,6 +521,14 @@ AC_ARG_ENABLE([external-ffmpeg], - [use_external_ffmpeg=$use_external_libraries]) - - ### End of external library options -+### PVR addons specific -+AC_ARG_ENABLE([pvraddons-with-dependencies], -+ [AS_HELP_STRING([--enable-pvraddons-with-dependencies], -+ [enable build of pvr addons with dependencies (default is no) 'Linux only'])], -+ [use_pvraddons_with_deps=$enableval], -+ [use_pvraddons_with_deps=no]) -+ -+### End PVR addons specific - - if test "x$host_vendor" != "xapple"; then - DEFAULT_COMPILE_FLAGS="-fPIC -DPIC -D_REENTRANT" -@@ -2770,12 +2778,16 @@ XB_CONFIG_MODULE([pvr-addons], [ - if test "$USE_EXTERNAL_FFMPEG" = 1; then - PVR_EXT_FFMPEG="--enable-external-ffmpeg" - fi -+ if test "$use_pvraddons_with_deps" = "yes"; then -+ ADDONS_WITH_DEPS="--enable-addons-with-dependencies" -+ fi - ./configure \ - --prefix="${prefix}" \ - --host=$host_alias \ - --build=$build_alias \ - --target=$target_alias \ - $PVR_EXT_FFMPEG \ -+ $ADDONS_WITH_DEPS \ - CC="$CC" \ - CXX="$CXX" \ - CFLAGS="$CFLAGS" \ --- -1.7.10 - - -From 86fb17f786cf9efacaa84f64188975312ef4ec6a Mon Sep 17 00:00:00 2001 +From 7a1298aa773b8a098ca2589dcccebdda46b4995f Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:03:31 +0200 -Subject: [PATCH 02/73] VideoRenerers: add buffering +Subject: [PATCH 01/88] VideoRenerers: add buffering --- xbmc/Application.cpp | 3 + + xbmc/cores/IPlayer.h | 2 + xbmc/cores/VideoRenderers/BaseRenderer.h | 5 +- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 41 ++-- xbmc/cores/VideoRenderers/LinuxRendererGL.h | 13 +- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 8 +- xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 4 +- - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 19 +- - xbmc/cores/VideoRenderers/OverlayRenderer.h | 6 +- - xbmc/cores/VideoRenderers/RenderManager.cpp | 296 +++++++++++++++++++---- - xbmc/cores/VideoRenderers/RenderManager.h | 48 +++- + xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 24 +- + xbmc/cores/VideoRenderers/OverlayRenderer.h | 9 +- + xbmc/cores/VideoRenderers/RenderManager.cpp | 294 +++++++++++++++++++---- + xbmc/cores/VideoRenderers/RenderManager.h | 63 ++++- xbmc/cores/VideoRenderers/WinRenderer.cpp | 8 +- xbmc/cores/VideoRenderers/WinRenderer.h | 2 +- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 +- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 18 +- - 14 files changed, 380 insertions(+), 93 deletions(-) + xbmc/cores/dvdplayer/DVDPlayer.cpp | 5 + + xbmc/cores/dvdplayer/DVDPlayer.h | 2 + + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 34 ++- + 16 files changed, 417 insertions(+), 100 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 15f1233..7ed09ee 100644 +index 46b2fde..efb3ac0 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2371,7 +2371,10 @@ void CApplication::Render() @@ -85,8 +37,21 @@ index 15f1233..7ed09ee 100644 CTimeUtils::UpdateFrameTime(flip); g_TextureManager.FreeUnusedTextures(); +diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h +index f2aa227..eb654ec 100644 +--- a/xbmc/cores/IPlayer.h ++++ b/xbmc/cores/IPlayer.h +@@ -229,6 +229,8 @@ class IPlayer + */ + virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; + ++ virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; ++ + protected: + IPlayerCallback& m_callback; + }; diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index 81d21d8..b02d536 100644 +index 81d21d8..aa1e4ae 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.h +++ b/xbmc/cores/VideoRenderers/BaseRenderer.h @@ -80,10 +80,13 @@ class CBaseRenderer @@ -98,8 +63,8 @@ index 81d21d8..b02d536 100644 virtual void Flush() {}; virtual unsigned int GetProcessorSize() { return 0; } -+ virtual unsigned int GetMaxProcessorSize() { return 0; } -+ virtual void SetProcessorSize(int numBuffers) { } ++ virtual unsigned int GetMaxBufferSize() { return 0; } ++ virtual void SetBufferSize(int numBuffers) { } + virtual void ReleaseBuffer(int idx) { } virtual bool Supports(ERENDERFEATURE feature) { return false; } @@ -212,7 +177,7 @@ index 1cf52d3..b32a7ea 100644 CVBufferRelease(buf.cvBufferRef); buf.cvBufferRef = cvBufferRef; diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index acebfe0..9f55fcb 100644 +index acebfe0..7c9fcae 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h @@ -44,7 +44,7 @@ @@ -229,8 +194,8 @@ index acebfe0..9f55fcb 100644 virtual void Reset(); /* resets renderer after seek for example */ virtual void Flush(); + virtual void ReleaseBuffer(int idx); -+ virtual void SetProcessorSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } -+ virtual unsigned int GetMaxProcessorSize() { return NUM_BUFFERS; } ++ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } + virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } #ifdef HAVE_LIBVDPAU @@ -298,10 +263,10 @@ index 76b5437..c6b69db 100644 protected: diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index 19d2d7d..94aaaf5 100644 +index 19d2d7d..f7f74ce 100644 --- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -89,7 +89,6 @@ long COverlayMainThread::Release() +@@ -89,29 +89,32 @@ long COverlayMainThread::Release() CRenderer::CRenderer() { m_render = 0; @@ -309,7 +274,36 @@ index 19d2d7d..94aaaf5 100644 } CRenderer::~CRenderer() -@@ -151,20 +150,30 @@ void CRenderer::Flush() + { +- for(int i = 0; i < 2; i++) ++ for(int i = 0; i < 10; i++) + Release(m_buffers[i]); + } + +-void CRenderer::AddOverlay(CDVDOverlay* o, double pts) ++void CRenderer::AddOverlay(CDVDOverlay* o, double pts, int index) + { + CSingleLock lock(m_section); + ++ m_decode = index; ++ + SElement e; + e.pts = pts; + e.overlay_dvd = o->Acquire(); + m_buffers[m_decode].push_back(e); + } + +-void CRenderer::AddOverlay(COverlay* o, double pts) ++void CRenderer::AddOverlay(COverlay* o, double pts, int index) + { + CSingleLock lock(m_section); + ++ m_decode = index; ++ + SElement e; + e.pts = pts; + e.overlay = o->Acquire(); +@@ -151,20 +154,23 @@ void CRenderer::Flush() { CSingleLock lock(m_section); @@ -329,13 +323,7 @@ index 19d2d7d..94aaaf5 100644 - m_render = m_decode; - m_decode =(m_decode + 1) % 2; -+void CRenderer::SetBuffer(int idx) -+{ -+ CSingleLock lock(m_section); -+ Release(m_buffers[idx]); -+ m_decode = idx; -+} - +- - Release(m_buffers[m_decode]); +void CRenderer::ReleaseBuffer(int idx) +{ @@ -345,20 +333,27 @@ index 19d2d7d..94aaaf5 100644 void CRenderer::Render() diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index d2175d8..c6740a5 100644 +index d2175d8..0921fc5 100644 --- a/xbmc/cores/VideoRenderers/OverlayRenderer.h +++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -98,6 +98,9 @@ +@@ -92,12 +92,14 @@ + CRenderer(); + ~CRenderer(); + +- void AddOverlay(CDVDOverlay* o, double pts); +- void AddOverlay(COverlay* o, double pts); ++ void AddOverlay(CDVDOverlay* o, double pts, int index); ++ void AddOverlay(COverlay* o, double pts, int index); + void AddCleanup(COverlay* o); void Flip(); void Render(); void Flush(); + void SetNumBuffers(int numBuffers) { m_iNumBuffers = numBuffers; } -+ void SetBuffer(int idx); + void ReleaseBuffer(int idx); protected: -@@ -124,7 +127,8 @@ +@@ -124,7 +126,8 @@ void Release(SElementV& list); CCriticalSection m_section; @@ -369,7 +364,7 @@ index d2175d8..c6740a5 100644 int m_render; diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index d22287d..eeb6c6f 100644 +index d22287d..c13f83d 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -28,6 +28,7 @@ @@ -380,19 +375,26 @@ index d22287d..eeb6c6f 100644 #include "Application.h" #include "ApplicationMessenger.h" -@@ -247,6 +248,11 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi +@@ -227,7 +228,7 @@ CStdString CXBMCRenderManager::GetVSyncState() + return state; + } + +-bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation) ++bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering) + { + /* make sure any queued frame was fully presented */ + double timeout = m_presenttime + 0.1; +@@ -247,6 +248,9 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi return false; } -+ // check if decoder supports buffering -+ m_bCodecSupportsBuffering = false; -+// if (format == RENDER_FMT_VDPAU) -+// m_bCodecSupportsBuffering = true; ++ // set buffering ++ m_bCodecSupportsBuffering = buffering; + bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation); if(result) { -@@ -261,6 +267,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi +@@ -261,6 +265,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi m_bReconfigured = true; m_presentstep = PRESENT_IDLE; m_presentevent.Set(); @@ -400,7 +402,7 @@ index d22287d..eeb6c6f 100644 } return result; -@@ -292,8 +299,12 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) +@@ -292,8 +297,12 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) if (!m_pRenderer) return; @@ -413,24 +415,7 @@ index d22287d..eeb6c6f 100644 m_overlays.Flip(); m_pRenderer->FlipPage(m_presentsource); m_presentstep = PRESENT_FRAME; -@@ -312,7 +323,7 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - m_presentevent.Set(); - } - --unsigned int CXBMCRenderManager::PreInit() -+unsigned int CXBMCRenderManager::PreInit(CDVDClock *pClock) - { - CRetakeLock lock(m_sharedSection); - -@@ -320,6 +331,7 @@ unsigned int CXBMCRenderManager::PreInit() - m_presenterr = 0.0; - m_errorindex = 0; - memset(m_errorbuff, 0, sizeof(m_errorbuff)); -+ m_pClock = pClock; - - m_bIsStarted = false; - m_bPauseDrawing = false; -@@ -338,6 +350,10 @@ unsigned int CXBMCRenderManager::PreInit() +@@ -338,6 +347,10 @@ unsigned int CXBMCRenderManager::PreInit() UpdateDisplayLatency(); @@ -441,7 +426,7 @@ index d22287d..eeb6c6f 100644 return m_pRenderer->PreInit(); } -@@ -366,7 +382,9 @@ bool CXBMCRenderManager::Flush() +@@ -366,7 +379,9 @@ bool CXBMCRenderManager::Flush() CRetakeLock lock(m_sharedSection); m_pRenderer->Flush(); @@ -451,12 +436,12 @@ index d22287d..eeb6c6f 100644 } else { -@@ -534,25 +552,21 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) +@@ -534,25 +549,21 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) m_pRenderer->SetViewMode(iViewMode); } -void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) -+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/, int speed /*= 0*/) ++void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/, int speed /*= 1000*/) { - if(timestamp - GetPresentTime() > MAXPRESENTDELAY) - timestamp = GetPresentTime() + MAXPRESENTDELAY; @@ -488,7 +473,7 @@ index d22287d..eeb6c6f 100644 if(bStop) return; -@@ -560,58 +574,67 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L +@@ -560,58 +571,67 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L { CRetakeLock lock(m_sharedSection); if(!m_pRenderer) return; @@ -582,7 +567,7 @@ index d22287d..eeb6c6f 100644 } } } -@@ -675,8 +698,12 @@ void CXBMCRenderManager::Present() +@@ -675,8 +695,12 @@ void CXBMCRenderManager::Present() if (!m_pRenderer) return; @@ -595,7 +580,7 @@ index d22287d..eeb6c6f 100644 m_overlays.Flip(); m_pRenderer->FlipPage(m_presentsource); m_presentstep = PRESENT_FRAME; -@@ -800,11 +827,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) +@@ -800,11 +824,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) if (!m_pRenderer) return -1; @@ -609,7 +594,7 @@ index d22287d..eeb6c6f 100644 if(index < 0) return index; -@@ -830,19 +857,19 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) +@@ -830,19 +854,19 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) } #ifdef HAVE_LIBVDPAU else if(pic.format == RENDER_FMT_VDPAU) @@ -633,36 +618,32 @@ index d22287d..eeb6c6f 100644 #endif m_pRenderer->ReleaseImage(index, false); -@@ -904,3 +931,176 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO +@@ -904,3 +928,177 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO return mInt; } + -+int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop) ++int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) +{ + CSharedLock lock(m_sharedSection); + if (!m_pRenderer) + return -1; + -+ //wait up to a second as this is our slowest allowed output rate -+ double timeout = GetPresentTime() + 0.1; ++ double maxwait = GetPresentTime() + (float)timeout/1000; + while(!HasFreeBuffer() && !bStop) + { + lock.Leave(); -+ m_flipEvent.WaitMSec(50); -+ if(GetPresentTime() > timeout && !bStop) ++ m_flipEvent.WaitMSec(std::min(50, timeout)); ++ if(GetPresentTime() > maxwait && !bStop) + { -+ CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); ++ if (timeout != 0) ++ CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); + return -1; + } + lock.Enter(); + } + lock.Leave(); + -+ { CRetakeLock lock(m_sharedSection); -+ m_overlays.SetBuffer((m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); -+ } -+ + if (bStop) + return -1; + @@ -712,7 +693,7 @@ index d22287d..eeb6c6f 100644 + +void CXBMCRenderManager::ResetRenderBuffer() +{ -+ m_iNumRenderBuffers = m_pRenderer->GetMaxProcessorSize(); ++ m_iNumRenderBuffers = m_pRenderer->GetMaxBufferSize(); + m_iNumRenderBuffers = std::min(5, m_iNumRenderBuffers); + m_iNumRenderBuffers = std::max(2, m_iNumRenderBuffers); + @@ -721,7 +702,7 @@ index d22287d..eeb6c6f 100644 + + CLog::Log(LOGNOTICE,"CXBMCRenderManager::ResetRenderBuffer - using %d render buffers", m_iNumRenderBuffers); + m_overlays.SetNumBuffers(m_iNumRenderBuffers); -+ m_pRenderer->SetProcessorSize(m_iNumRenderBuffers); ++ m_pRenderer->SetBufferSize(m_iNumRenderBuffers); + + m_iCurrentRenderBuffer = 0; + m_iOutputRenderBuffer = 0; @@ -744,7 +725,11 @@ index d22287d..eeb6c6f 100644 + } + + double iClockSleep, iPlayingClock, iCurrentClock; -+ iPlayingClock = m_pClock->GetClock(iCurrentClock, false); ++ if (g_application.m_pPlayer) ++ iPlayingClock = g_application.m_pPlayer->GetClock(iCurrentClock, false); ++ else ++ iPlayingClock = iCurrentClock = 0; ++ + iClockSleep = m_renderBuffers[idx].pts - iPlayingClock; + + if (m_speed) @@ -756,8 +741,9 @@ index d22287d..eeb6c6f 100644 + presenttime = clocktime + MAXPRESENTDELAY; + + m_sleeptime = presenttime - clocktime; ++ double frametime = 1 / g_graphicsContext.GetFPS(); + -+ if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime+0.01) ++ if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) + { + m_presentPts = m_renderBuffers[idx].pts; + m_presenttime = presenttime; @@ -794,24 +780,24 @@ index d22287d..eeb6c6f 100644 + if (!m_pRenderer) + return; + -+ if (m_iNumRenderBuffers < 3) -+ return; -+ -+ int last = m_iDisplayedRenderBuffer; -+ m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; -+ -+ if (last != m_iDisplayedRenderBuffer -+ && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) ++ if (m_iNumRenderBuffers >= 3) + { -+ m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -+ m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); ++ int last = m_iDisplayedRenderBuffer; ++ m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; ++ ++ if (last != m_iDisplayedRenderBuffer ++ && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) ++ { ++ m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); ++ m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); ++ } + } + + lock.Leave(); + m_flipEvent.Set(); +} diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 7fe6bb2..34ff8d0 100644 +index 7fe6bb2..96ab53f 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h @@ -31,6 +31,7 @@ @@ -822,29 +808,56 @@ index 7fe6bb2..34ff8d0 100644 namespace DXVA { class CProcessor; } namespace VAAPI { class CSurfaceHolder; } -@@ -70,8 +71,8 @@ class CXBMCRenderManager +@@ -65,12 +66,12 @@ class CXBMCRenderManager + void SetViewMode(int iViewMode); + + // Functions called from mplayer +- bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation); ++ bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering = false); + bool IsConfigured(); int AddVideoPicture(DVDVideoPicture& picture); - void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); -- unsigned int PreInit(); -+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 0); -+ unsigned int PreInit(CDVDClock *pClock); ++ void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); + unsigned int PreInit(); void UnInit(); bool Flush(); +@@ -78,7 +79,7 @@ class CXBMCRenderManager + void AddOverlay(CDVDOverlay* o, double pts) + { + CSharedLock lock(m_sharedSection); +- m_overlays.AddOverlay(o, pts); ++ m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); + } -@@ -131,6 +132,10 @@ class CXBMCRenderManager - CSharedSection& GetSection() { return m_sharedSection; }; + void AddCleanup(OVERLAY::COverlay* o) +@@ -132,6 +133,24 @@ class CXBMCRenderManager void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn); -+ int WaitForBuffer(volatile bool& bStop); + ++ /** ++ * If player uses buffering it has to wait for a buffer before it calls ++ * AddVideoPicture and AddOverlay. It waits for max 50 ms before it returns -1 ++ * in case no buffer is available. Player may call this in a loop and decides ++ * by itself when it wants to drop a frame. ++ * If no buffering is requested in Configure, player does not need to call this, ++ * because FlipPage will block. ++ */ ++ int WaitForBuffer(volatile bool& bStop, int timeout = 100); ++ ++ /** ++ * Called by application right after flip. The buffer which has been rendered to ++ * display becomes available for player to deliver a new frame. ++ */ + void NotifyDisplayFlip(); + void EnableBuffering(bool enable); + void DiscardBuffer(); - ++ protected: void Render(bool clear, DWORD flags, DWORD alpha); -@@ -139,6 +144,13 @@ class CXBMCRenderManager + +@@ -139,6 +158,13 @@ class CXBMCRenderManager void PresentFields(bool clear, DWORD flags, DWORD alpha); void PresentBlend(bool clear, DWORD flags, DWORD alpha); @@ -858,7 +871,7 @@ index 7fe6bb2..34ff8d0 100644 EINTERLACEMETHOD AutoInterlaceMethodInternal(EINTERLACEMETHOD mInt); bool m_bPauseDrawing; // true if we should pause rendering -@@ -169,6 +181,37 @@ class CXBMCRenderManager +@@ -169,6 +195,37 @@ class CXBMCRenderManager double m_displayLatency; void UpdateDisplayLatency(); @@ -896,14 +909,6 @@ index 7fe6bb2..34ff8d0 100644 double m_presenttime; double m_presentcorr; double m_presenterr; -@@ -180,6 +223,7 @@ class CXBMCRenderManager - int m_presentsource; - CEvent m_presentevent; - CEvent m_flushEvent; -+ CDVDClock *m_pClock; - - - OVERLAY::CRenderer m_overlays; diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp index f1d0768..f0f5b2d 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.cpp @@ -947,20 +952,33 @@ index 2ab5684..f493ba7 100644 virtual unsigned int PreInit(); virtual void UnInit(); diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 0cd2510..315d64a 100644 +index 0cd2510..dfb317f 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -463,7 +463,7 @@ bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options) - m_ready.Reset(); +@@ -4075,3 +4075,8 @@ bool CDVDPlayer::CachePVRStream(void) const + !g_PVRManager.IsPlayingRecording() && + g_advancedSettings.m_bPVRCacheInDvdPlayer; + } ++ ++double CDVDPlayer::GetClock(double& absolute, bool interpolated) ++{ ++ return m_clock.GetClock(absolute, interpolated); ++} +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h +index d3c201e..093318e 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.h ++++ b/xbmc/cores/dvdplayer/DVDPlayer.h +@@ -252,6 +252,8 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer + virtual bool SwitchChannel(const PVR::CPVRChannel &channel); + virtual bool CachePVRStream(void) const; - #if defined(HAS_VIDEO_PLAYBACK) -- g_renderManager.PreInit(); -+ g_renderManager.PreInit(&m_clock); - #endif - - Create(); ++ virtual double GetClock(double& absolute, bool interpolated = true); ++ + enum ECacheState + { CACHESTATE_DONE = 0 + , CACHESTATE_FULL // player is filling up the demux queue diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 3008c25..a4bb1ba 100644 +index 3008c25..19496a7 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -261,6 +261,7 @@ void CDVDPlayerVideo::OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec) @@ -1004,7 +1022,78 @@ index 3008c25..a4bb1ba 100644 } // guess next frame pts. iDuration is always valid -@@ -1317,6 +1323,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1088,47 +1094,61 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + } + + CStdString formatstr; ++ bool buffering; + + switch(pPicture->format) + { + case RENDER_FMT_YUV420P: + formatstr = "YV12"; ++ buffering = true; + break; + case RENDER_FMT_YUV420P16: + formatstr = "YV12P16"; ++ buffering = true; + break; + case RENDER_FMT_YUV420P10: + formatstr = "YV12P10"; ++ buffering = true; + break; + case RENDER_FMT_NV12: + formatstr = "NV12"; ++ buffering = true; + break; + case RENDER_FMT_UYVY422: + formatstr = "UYVY"; ++ buffering = true; + break; + case RENDER_FMT_YUYV422: + formatstr = "YUY2"; ++ buffering = true; + break; + case RENDER_FMT_VDPAU: + formatstr = "VDPAU"; ++ buffering = true; + break; + case RENDER_FMT_DXVA: + formatstr = "DXVA"; ++ buffering = false; + break; + case RENDER_FMT_VAAPI: + formatstr = "VAAPI"; ++ buffering = false; + break; + case RENDER_FMT_OMXEGL: + formatstr = "OMXEGL"; ++ buffering = false; + break; + case RENDER_FMT_CVBREF: + formatstr = "BGRA"; ++ buffering = false; + break; + case RENDER_FMT_BYPASS: + formatstr = "BYPASS"; ++ buffering = false; + break; + case RENDER_FMT_NONE: + formatstr = "NONE"; ++ buffering = false; + break; + } + +@@ -1139,7 +1159,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + } + + CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str()); +- if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation)) ++ if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation, buffering)) + { + CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); + return EOS_ABORT; +@@ -1317,6 +1337,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) mDisplayField = FS_BOT; } @@ -1021,7 +1110,7 @@ index 3008c25..a4bb1ba 100644 ProcessOverlays(pPicture, pts); AutoCrop(pPicture); -@@ -1333,7 +1349,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1333,7 +1363,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) if (index < 0) return EOS_DROPPED; @@ -1034,10 +1123,206 @@ index 3008c25..a4bb1ba 100644 1.7.10 -From efb0e5d9a372d2c4a6c7fcb9bd74369a8a910cd0 Mon Sep 17 00:00:00 2001 +From 383daa67f101ff6cc75f0fde39c8bca69a7789ae Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 16 Feb 2013 08:32:18 +0100 +Subject: [PATCH 02/88] add buffering for GLES + +--- + xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 10 ---------- + xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 6 ++++-- + 2 files changed, 4 insertions(+), 12 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +index 2a59e2b..1bf2f3b 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +@@ -135,13 +135,6 @@ + delete m_dllSwScale; + } + +-void CLinuxRendererGLES::ManageTextures() +-{ +- m_NumYV12Buffers = 2; +- //m_iYV12RenderBuffer = 0; +- return; +-} +- + bool CLinuxRendererGLES::ValidateRenderTarget() + { + if (!m_bValidated) +@@ -395,7 +388,6 @@ void CLinuxRendererGLES::Update(bool bPauseDrawing) + { + if (!m_bConfigured) return; + ManageDisplay(); +- ManageTextures(); + } + + void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) +@@ -409,7 +401,6 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) + if (m_renderMethod & RENDER_BYPASS) + { + ManageDisplay(); +- ManageTextures(); + // 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) +@@ -449,7 +440,6 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) + return; + + ManageDisplay(); +- ManageTextures(); + + g_graphicsContext.BeginPaint(); + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +index c6b69db..5bae10d 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +@@ -41,7 +41,7 @@ + class COpenMaxVideo; + typedef std::vector Features; + +-#define NUM_BUFFERS 3 ++#define NUM_BUFFERS 10 + + + #undef ALIGN +@@ -138,6 +138,9 @@ class CLinuxRendererGLES : public CBaseRenderer + virtual void UnInit(); + virtual void Reset(); /* resets renderer after seek for example */ + virtual void ReorderDrawPoints(); ++ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } ++ virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } + + virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); + +@@ -162,7 +165,6 @@ class CLinuxRendererGLES : public CBaseRenderer + protected: + virtual void Render(DWORD flags, int index); + +- virtual void ManageTextures(); + int NextYV12Texture(); + virtual bool ValidateRenderTarget(); + virtual void LoadShaders(int field=FIELD_FULL); +-- +1.7.10 + + +From 41ee337f40e25843a134c3f1e02d66db733555d0 Mon Sep 17 00:00:00 2001 +From: unknown +Date: Sat, 16 Feb 2013 11:17:02 +0100 +Subject: [PATCH 03/88] WinRenderer: add buffering + +--- + xbmc/cores/VideoRenderers/WinRenderer.cpp | 14 ++++++-------- + xbmc/cores/VideoRenderers/WinRenderer.h | 12 +++++------- + 2 files changed, 11 insertions(+), 15 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp +index f0f5b2d..b6279f2 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp +@@ -103,21 +103,19 @@ static enum PixelFormat PixelFormatFromFormat(ERenderFormat format) + + void CWinRenderer::ManageTextures() + { +- int neededbuffers = 2; +- +- if( m_NumYV12Buffers < neededbuffers ) ++ if( m_NumYV12Buffers < m_neededBuffers ) + { +- for(int i = m_NumYV12Buffers; i neededbuffers ) ++ else if( m_NumYV12Buffers > m_neededBuffers ) + { +- m_NumYV12Buffers = neededbuffers; ++ m_NumYV12Buffers = m_neededBuffers; + m_iYV12RenderBuffer = m_iYV12RenderBuffer % m_NumYV12Buffers; + +- for(int i = m_NumYV12Buffers-1; i>=neededbuffers;i--) ++ for(int i = m_NumYV12Buffers-1; i>=m_neededBuffers;i--) + DeleteYV12Texture(i); + } + } +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h +index f493ba7..b3448ed 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.h ++++ b/xbmc/cores/VideoRenderers/WinRenderer.h +@@ -32,13 +32,7 @@ + #include "cores/VideoRenderers/RenderFlags.h" + #include "cores/VideoRenderers/RenderFormats.h" + +-//#define MP_DIRECTRENDERING +- +-#ifdef MP_DIRECTRENDERING +-#define NUM_BUFFERS 3 +-#else +-#define NUM_BUFFERS 2 +-#endif ++#define NUM_BUFFERS 10 + + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) + #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) +@@ -176,6 +170,8 @@ class CWinRenderer : public CBaseRenderer + void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); + + virtual unsigned int GetProcessorSize() { return m_processor.Size(); } ++ virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } + + protected: + virtual void Render(DWORD flags); +@@ -245,6 +241,8 @@ class CWinRenderer : public CBaseRenderer + // the separable HQ scalers need this info, but could the m_destRect be used instead? + unsigned int m_destWidth; + unsigned int m_destHeight; ++ ++ int m_neededBuffers; + }; + + #else +-- +1.7.10 + + +From b0d133ededb6849b4313a65204ee9716cd0aae9f Mon Sep 17 00:00:00 2001 +From: unknown +Date: Sat, 16 Feb 2013 11:17:32 +0100 +Subject: [PATCH 04/88] DXVA: activate buffering in renderer + +--- + 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 19496a7..3bfe180 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1128,7 +1128,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + break; + case RENDER_FMT_DXVA: + formatstr = "DXVA"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_VAAPI: + formatstr = "VAAPI"; +-- +1.7.10 + + +From bcbb88a9c2c822bf40c1f4d862cd10b9baccfd02 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 2 Oct 2012 10:49:09 +0200 -Subject: [PATCH 03/73] linuxrenderer: delete all textures on reconfigure +Subject: [PATCH 05/88] linuxrenderer: delete all textures on reconfigure --- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 2 +- @@ -1060,10 +1345,10 @@ index b32a7ea..a2dc2be 100644 1.7.10 -From 140768ac0a1b909ed0c0821a1dfdf6df8717a64b Mon Sep 17 00:00:00 2001 +From 3d37fe3c9eca279b4ed2e0977651834b858f3682 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:17:33 +0200 -Subject: [PATCH 04/73] drop frame counter in application, ask render manager +Subject: [PATCH 06/88] drop frame counter in application, ask render manager instead --- @@ -1074,7 +1359,7 @@ Subject: [PATCH 04/73] drop frame counter in application, ask render manager 4 files changed, 23 insertions(+), 45 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 7ed09ee..b623250 100644 +index efb3ac0..5c7017c 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -419,8 +419,6 @@ @@ -1169,7 +1454,7 @@ index 7ed09ee..b623250 100644 } void CApplication::SetStandAlone(bool value) -@@ -5646,12 +5621,6 @@ bool CApplication::SwitchToFullScreen() +@@ -5633,12 +5608,6 @@ bool CApplication::SwitchToFullScreen() // See if we're playing a video, and are in GUI mode if ( IsPlayingVideo() && g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO) { @@ -1182,7 +1467,7 @@ index 7ed09ee..b623250 100644 // then switch to fullscreen mode g_windowManager.ActivateWindow(WINDOW_FULLSCREEN_VIDEO); return true; -@@ -5884,7 +5853,6 @@ bool CApplication::IsCurrentThread() const +@@ -5871,7 +5840,6 @@ bool CApplication::IsCurrentThread() const bool CApplication::IsPresentFrame() { @@ -1208,10 +1493,10 @@ index 69609fa..6764a60 100644 VIDEO::CVideoInfoScanner *m_videoInfoScanner; MUSIC_INFO::CMusicInfoScanner *m_musicInfoScanner; diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index eeb6c6f..4b897da 100644 +index c13f83d..35aba7e 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1104,3 +1104,14 @@ void CXBMCRenderManager::NotifyDisplayFlip() +@@ -1102,3 +1102,14 @@ void CXBMCRenderManager::NotifyDisplayFlip() lock.Leave(); m_flipEvent.Set(); } @@ -1227,12 +1512,12 @@ index eeb6c6f..4b897da 100644 + return true; +} diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 34ff8d0..288175e 100644 +index 96ab53f..1e44233 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -134,6 +134,7 @@ class CXBMCRenderManager - void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn); - int WaitForBuffer(volatile bool& bStop); +@@ -148,6 +148,7 @@ class CXBMCRenderManager + * display becomes available for player to deliver a new frame. + */ void NotifyDisplayFlip(); + bool HasFrame(); void EnableBuffering(bool enable); @@ -1242,27 +1527,1290 @@ index 34ff8d0..288175e 100644 1.7.10 -From ba3a2cb07d319dc1e2fbb56c272744d0a7cbc772 Mon Sep 17 00:00:00 2001 +From 61ece20a4691e8d7f6203054bdc1a5fc5e9b84ab Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 11:02:29 +0200 +Subject: [PATCH 07/88] vaapi: adopt to buffering in renderer + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 3 ++- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 1 + + 3 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +index 8f81637..286fd67 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +@@ -106,7 +106,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx + && (avctx->codec_id != CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) + { + VAAPI::CDecoder* dec = new VAAPI::CDecoder(); +- if(dec->Open(avctx, *cur)) ++ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) + { + ctx->SetHardware(dec); + return *cur; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index 9f5a960..a2b9195 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -357,6 +357,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su + CHECK(vaCreateConfig(m_display->get(), profile, entrypoint, &attrib, 1, &m_hwaccel->config_id)) + m_config = m_hwaccel->config_id; + ++ m_renderbuffers_count = surfaces; + if (!EnsureContext(avctx)) + return false; + +@@ -388,7 +389,7 @@ bool CDecoder::EnsureContext(AVCodecContext *avctx) + else + m_refs = 2; + } +- return EnsureSurfaces(avctx, m_refs + 3); ++ return EnsureSurfaces(avctx, m_refs + m_renderbuffers_count + 1); + } + + bool CDecoder::EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +index 863edc4..417cbc0 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +@@ -122,6 +122,7 @@ class CDecoder + static const unsigned m_surfaces_max = 32; + unsigned m_surfaces_count; + VASurfaceID m_surfaces[m_surfaces_max]; ++ unsigned m_renderbuffers_count; + + int m_refs; + std::list m_surfaces_used; +-- +1.7.10 + + +From ab9b5a5d746f712a0d3e5332cc191d129fc3a175 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 16 Feb 2013 20:17:29 +0100 +Subject: [PATCH 08/88] add buffering - some documentation + +--- + xbmc/cores/IPlayer.h | 3 +++ + xbmc/cores/VideoRenderers/RenderManager.h | 40 +++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+) + +diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h +index eb654ec..cbf2faa 100644 +--- a/xbmc/cores/IPlayer.h ++++ b/xbmc/cores/IPlayer.h +@@ -229,6 +229,9 @@ class IPlayer + */ + virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; + ++ /*! ++ \brief called by RenderManager in order to schedule frames ++ */ + virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; + + protected: +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index 1e44233..49da2ed 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -66,11 +66,38 @@ class CXBMCRenderManager + void SetViewMode(int iViewMode); + + // Functions called from mplayer ++ /** ++ * Called by video player to configure renderer ++ * @param width width of decoded frame ++ * @param height height of decoded frame ++ * @param d_width displayed width of frame (aspect ratio) ++ * @param d_height displayed height of frame ++ * @param fps frames per second of video ++ * @param flags see RenderFlags.h ++ * @param format see RenderFormats.h ++ * @param extended_format used by DXVA ++ * @param orientation ++ * @param buffering enable buffering in renderer, defaults to false ++ */ + bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering = false); + bool IsConfigured(); + + int AddVideoPicture(DVDVideoPicture& picture); + ++ /** ++ * Called by video player to flip render buffers ++ * If buffering is enabled this method does not block. In case of disabled buffering ++ * this method blocks waiting for the render thread to pass by. ++ * When buffering is used there might be no free buffer available after the call to ++ * this method. Player has to call WaitForBuffer. A free buffer will become ++ * available after the main thread has flipped front / back buffers. ++ * ++ * @param bStop reference to stop flag of calling thread ++ * @param timestamp pts of frame delivered with AddVideoPicture ++ * @param source depreciated ++ * @param sync signals frame, top, or bottom field ++ * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind ++ */ + void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); + unsigned int PreInit(); + void UnInit(); +@@ -148,8 +175,21 @@ class CXBMCRenderManager + * display becomes available for player to deliver a new frame. + */ + void NotifyDisplayFlip(); ++ ++ /** ++ * Called by application (main thread) to query if there is any frame to render ++ */ + bool HasFrame(); ++ ++ /** ++ * Video player can dynamically enable/disable buffering. In situations like ++ * rewind buffering is not ideal. ++ */ + void EnableBuffering(bool enable); ++ ++ /** ++ * Video player call this on flush in oder to discard any queued frames ++ */ + void DiscardBuffer(); + + protected: +-- +1.7.10 + + +From 9d2f1cbcf647826f3449fb58c995a478bfd0697c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 18 Feb 2013 10:42:00 +0100 +Subject: [PATCH 09/88] RenderManager: only flip free buffer if player has + added something + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 29 +++++++++++++++++++++++---- + xbmc/cores/VideoRenderers/RenderManager.h | 7 ++----- + 2 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index 35aba7e..f5cc0f6 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -612,10 +612,12 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + } + } + +- FlipFreeBuffer(); +- m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; +- m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; +- m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; ++ if (FlipFreeBuffer() >= 0) ++ { ++ m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; ++ m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; ++ m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; ++ } + m_speed = speed; + } + +@@ -825,7 +827,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) + return -1; + + if(m_pRenderer->AddVideoPicture(&pic, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers)) ++ { ++ m_bRenderBufferUsed = true; + return 1; ++ } + + YV12Image image; + int index = m_pRenderer->GetImage(&image, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); +@@ -870,9 +875,17 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) + #endif + m_pRenderer->ReleaseImage(index, false); + ++ m_bRenderBufferUsed = true; + return index; + } + ++void CXBMCRenderManager::AddOverlay(CDVDOverlay* o, double pts) ++{ ++ CSharedLock lock(m_sharedSection); ++ m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); ++ m_bRenderBufferUsed = true; ++} ++ + bool CXBMCRenderManager::Supports(ERENDERFEATURE feature) + { + CSharedLock lock(m_sharedSection); +@@ -973,10 +986,17 @@ int CXBMCRenderManager::FlipFreeBuffer() + // See "Render Buffer State Description" in header for information. + if (HasFreeBuffer()) + { ++ if (!m_bRenderBufferUsed) ++ { ++ return -1; ++ } ++ m_bRenderBufferUsed = false; + m_bAllRenderBuffersDisplayed = false; + m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; + return m_iOutputRenderBuffer; + } ++ else ++ return -1; + } + + bool CXBMCRenderManager::HasFreeBuffer() +@@ -1017,6 +1037,7 @@ void CXBMCRenderManager::ResetRenderBuffer() + m_sleeptime = 1.0; + m_presentPts = DVD_NOPTS_VALUE; + m_speed = 0; ++ m_bRenderBufferUsed = false; + } + + void CXBMCRenderManager::PrepareNextRender() +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index 49da2ed..afb6b1f 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -103,11 +103,7 @@ class CXBMCRenderManager + void UnInit(); + bool Flush(); + +- void AddOverlay(CDVDOverlay* o, double pts) +- { +- CSharedLock lock(m_sharedSection); +- m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); +- } ++ void AddOverlay(CDVDOverlay* o, double pts); + + void AddCleanup(OVERLAY::COverlay* o) + { +@@ -255,6 +251,7 @@ class CXBMCRenderManager + bool m_bUseBuffering; + bool m_bCodecSupportsBuffering; + int m_speed; ++ bool m_bRenderBufferUsed; + CEvent m_flipEvent; + + struct +-- +1.7.10 + + +From d4d025be1cd04effdc90d6b6103097ce193067a0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 19 Feb 2013 09:06:22 +0100 +Subject: [PATCH 10/88] move NUM_BUFFERS up to BaseRenderer.h + +--- + xbmc/cores/VideoRenderers/BaseRenderer.h | 3 ++- + xbmc/cores/VideoRenderers/LinuxRendererGL.h | 2 -- + xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 2 -- + xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 2 +- + xbmc/cores/VideoRenderers/OverlayRenderer.h | 3 ++- + xbmc/cores/VideoRenderers/WinRenderer.h | 2 -- + 6 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h +index aa1e4ae..60b7197 100644 +--- a/xbmc/cores/VideoRenderers/BaseRenderer.h ++++ b/xbmc/cores/VideoRenderers/BaseRenderer.h +@@ -26,10 +26,11 @@ + + #define MAX_PLANES 3 + #define MAX_FIELDS 3 ++#define NUM_BUFFERS 10 + + typedef struct YV12Image + { +- BYTE * plane[MAX_PLANES]; ++ uint8_t* plane[MAX_PLANES]; + int planesize[MAX_PLANES]; + unsigned stride[MAX_PLANES]; + unsigned width; +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h +index 7c9fcae..a7b5886 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h +@@ -44,8 +44,6 @@ + namespace Shaders { class BaseVideoFilterShader; } + namespace VAAPI { struct CHolder; } + +-#define NUM_BUFFERS 10 +- + + #undef ALIGN + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +index 5bae10d..fe32eff 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +@@ -41,8 +41,6 @@ + class COpenMaxVideo; + typedef std::vector Features; + +-#define NUM_BUFFERS 10 +- + + #undef ALIGN + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +index f7f74ce..5236390 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +@@ -93,7 +93,7 @@ long COverlayMainThread::Release() + + CRenderer::~CRenderer() + { +- for(int i = 0; i < 10; i++) ++ for(int i = 0; i < NUM_BUFFERS; i++) + Release(m_buffers[i]); + } + +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h +index 0921fc5..66c592a 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.h ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h +@@ -23,6 +23,7 @@ + #pragma once + + #include "threads/CriticalSection.h" ++#include "BaseRenderer.h" + + #include + +@@ -126,7 +127,7 @@ + void Release(SElementV& list); + + CCriticalSection m_section; +- SElementV m_buffers[10]; ++ SElementV m_buffers[NUM_BUFFERS]; + int m_iNumBuffers; + int m_decode; + int m_render; +diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h +index b3448ed..b099697 100644 +--- a/xbmc/cores/VideoRenderers/WinRenderer.h ++++ b/xbmc/cores/VideoRenderers/WinRenderer.h +@@ -32,8 +32,6 @@ + #include "cores/VideoRenderers/RenderFlags.h" + #include "cores/VideoRenderers/RenderFormats.h" + +-#define NUM_BUFFERS 10 +- + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) + #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) + +-- +1.7.10 + + +From 08665778e71d52fa461150f596dd18de1035915f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 24 Feb 2013 09:55:00 +0100 +Subject: [PATCH 11/88] OverlayRenderer: align buffers with index in + renderManager + +--- + xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 26 ++++++++++++++++--------- + xbmc/cores/VideoRenderers/OverlayRenderer.h | 8 ++++---- + xbmc/cores/VideoRenderers/RenderManager.cpp | 11 +++++++---- + xbmc/cores/VideoRenderers/RenderManager.h | 1 + + 4 files changed, 29 insertions(+), 17 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +index 5236390..5592eca 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +@@ -127,27 +127,32 @@ void CRenderer::AddCleanup(COverlay* o) + m_cleanup.push_back(o->Acquire()); + } + +-void CRenderer::Release(SElementV& list) ++long CRenderer::Release(SElementV& list) + { + SElementV l = list; + list.clear(); + ++ long count = 0; + for(SElementV::iterator it = l.begin(); it != l.end(); it++) + { + if(it->overlay) +- it->overlay->Release(); ++ count += it->overlay->Release(); + if(it->overlay_dvd) +- it->overlay_dvd->Release(); ++ count += it->overlay_dvd->Release(); + } ++ return count; + } + +-void CRenderer::Release(COverlayV& list) ++long CRenderer::Release(COverlayV& list) + { + COverlayV l = list; + list.clear(); + ++ long count = 0; + for(COverlayV::iterator it = l.begin(); it != l.end(); it++) +- (*it)->Release(); ++ count += (*it)->Release(); ++ ++ return count; + } + + void CRenderer::Flush() +@@ -161,16 +166,19 @@ void CRenderer::Flush() + Release(m_cleanup); + } + +-void CRenderer::Flip() ++void CRenderer::Flip(int source) + { + CSingleLock lock(m_section); +- m_render = (m_render + 1) % m_iNumBuffers; ++ if( source >= 0 && source < m_iNumBuffers ) ++ m_render = source; ++ else ++ m_render = (m_render + 1) % m_iNumBuffers; + } + +-void CRenderer::ReleaseBuffer(int idx) ++long CRenderer::ReleaseBuffer(int idx) + { + CSingleLock lock(m_section); +- Release(m_buffers[idx]); ++ return Release(m_buffers[idx]); + } + + void CRenderer::Render() +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h +index 66c592a..627dd9f 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.h ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h +@@ -96,11 +96,11 @@ + void AddOverlay(CDVDOverlay* o, double pts, int index); + void AddOverlay(COverlay* o, double pts, int index); + void AddCleanup(COverlay* o); +- void Flip(); ++ void Flip(int source); + void Render(); + void Flush(); + void SetNumBuffers(int numBuffers) { m_iNumBuffers = numBuffers; } +- void ReleaseBuffer(int idx); ++ long ReleaseBuffer(int idx); + + protected: + +@@ -123,8 +123,8 @@ + COverlay* Convert(CDVDOverlay* o, double pts); + COverlay* Convert(CDVDOverlaySSA* o, double pts); + +- void Release(COverlayV& list); +- void Release(SElementV& list); ++ long Release(COverlayV& list); ++ long Release(SElementV& list); + + CCriticalSection m_section; + SElementV m_buffers[NUM_BUFFERS]; +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index f5cc0f6..e887313 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -303,7 +303,7 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) + if(m_presentstep == PRESENT_FLIP) + { + FlipRenderBuffer(); +- m_overlays.Flip(); ++ m_overlays.Flip(m_presentsource); + m_pRenderer->FlipPage(m_presentsource); + m_presentstep = PRESENT_FRAME; + m_presentevent.Set(); +@@ -703,7 +703,7 @@ void CXBMCRenderManager::Present() + if(m_presentstep == PRESENT_FLIP) + { + FlipRenderBuffer(); +- m_overlays.Flip(); ++ m_overlays.Flip(m_presentsource); + m_pRenderer->FlipPage(m_presentsource); + m_presentstep = PRESENT_FRAME; + m_presentevent.Set(); +@@ -986,11 +986,12 @@ int CXBMCRenderManager::FlipFreeBuffer() + // See "Render Buffer State Description" in header for information. + if (HasFreeBuffer()) + { +- if (!m_bRenderBufferUsed) ++ if (!m_bRenderBufferUsed && !m_bOverlayReleased) + { + return -1; + } + m_bRenderBufferUsed = false; ++ m_bOverlayReleased = false; + m_bAllRenderBuffersDisplayed = false; + m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; + return m_iOutputRenderBuffer; +@@ -1038,6 +1039,7 @@ void CXBMCRenderManager::ResetRenderBuffer() + m_presentPts = DVD_NOPTS_VALUE; + m_speed = 0; + m_bRenderBufferUsed = false; ++ m_bOverlayReleased = false; + } + + void CXBMCRenderManager::PrepareNextRender() +@@ -1116,7 +1118,8 @@ void CXBMCRenderManager::NotifyDisplayFlip() + && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) + { + m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); +- m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); ++ if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer) > 0) ++ m_bOverlayReleased = true; + } + } + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index afb6b1f..3f95793 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -252,6 +252,7 @@ class CXBMCRenderManager + bool m_bCodecSupportsBuffering; + int m_speed; + bool m_bRenderBufferUsed; ++ bool m_bOverlayReleased; + CEvent m_flipEvent; + + struct +-- +1.7.10 + + +From a0838293cf956be846f298e4bc5b6211e80f535a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 26 Feb 2013 09:00:21 +0100 +Subject: [PATCH 12/88] add buffering - submit absolute time to render buffers + +--- + xbmc/cores/IPlayer.h | 5 ----- + xbmc/cores/VideoRenderers/RenderManager.cpp | 20 +++----------------- + xbmc/cores/VideoRenderers/RenderManager.h | 5 ++--- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 5 ----- + xbmc/cores/dvdplayer/DVDPlayer.h | 2 -- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 6 files changed, 6 insertions(+), 33 deletions(-) + +diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h +index cbf2faa..f2aa227 100644 +--- a/xbmc/cores/IPlayer.h ++++ b/xbmc/cores/IPlayer.h +@@ -229,11 +229,6 @@ class IPlayer + */ + virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; + +- /*! +- \brief called by RenderManager in order to schedule frames +- */ +- virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; +- + protected: + IPlayerCallback& m_callback; + }; +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index e887313..a2001c0 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -571,7 +571,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + { CRetakeLock lock(m_sharedSection); + if(!m_pRenderer) return; + +- double presenttime = timestamp; + EFIELDSYNC presentfield = sync; + EPRESENTMETHOD presentmethod; + +@@ -614,7 +613,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + + if (FlipFreeBuffer() >= 0) + { +- m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; ++ m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; + m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; + m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; + } +@@ -1036,7 +1035,6 @@ void CXBMCRenderManager::ResetRenderBuffer() + m_iDisplayedRenderBuffer = 0; + m_bAllRenderBuffersDisplayed = true; + m_sleeptime = 1.0; +- m_presentPts = DVD_NOPTS_VALUE; + m_speed = 0; + m_bRenderBufferUsed = false; + m_bOverlayReleased = false; +@@ -1053,19 +1051,8 @@ void CXBMCRenderManager::PrepareNextRender() + return; + } + +- double iClockSleep, iPlayingClock, iCurrentClock; +- if (g_application.m_pPlayer) +- iPlayingClock = g_application.m_pPlayer->GetClock(iCurrentClock, false); +- else +- iPlayingClock = iCurrentClock = 0; +- +- iClockSleep = m_renderBuffers[idx].pts - iPlayingClock; +- +- if (m_speed) +- iClockSleep = iClockSleep * DVD_PLAYSPEED_NORMAL / m_speed; +- +- double presenttime = (iCurrentClock + iClockSleep) / DVD_TIME_BASE; +- double clocktime = iCurrentClock / DVD_TIME_BASE; ++ double presenttime = m_renderBuffers[idx].timestamp; ++ double clocktime = GetPresentTime(); + if(presenttime - clocktime > MAXPRESENTDELAY) + presenttime = clocktime + MAXPRESENTDELAY; + +@@ -1074,7 +1061,6 @@ void CXBMCRenderManager::PrepareNextRender() + + if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) + { +- m_presentPts = m_renderBuffers[idx].pts; + m_presenttime = presenttime; + m_presentmethod = m_renderBuffers[idx].presentmethod; + m_presentfield = m_renderBuffers[idx].presentfield; +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index 3f95793..858a547 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -93,7 +93,7 @@ class CXBMCRenderManager + * available after the main thread has flipped front / back buffers. + * + * @param bStop reference to stop flag of calling thread +- * @param timestamp pts of frame delivered with AddVideoPicture ++ * @param timestamp of frame delivered with AddVideoPicture + * @param source depreciated + * @param sync signals frame, top, or bottom field + * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind +@@ -257,13 +257,12 @@ class CXBMCRenderManager + + struct + { +- double pts; ++ double timestamp; + EFIELDSYNC presentfield; + EPRESENTMETHOD presentmethod; + }m_renderBuffers[5]; + + double m_sleeptime; +- double m_presentPts; + + double m_presenttime; + double m_presentcorr; +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index dfb317f..0cd2510 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -4075,8 +4075,3 @@ bool CDVDPlayer::CachePVRStream(void) const + !g_PVRManager.IsPlayingRecording() && + g_advancedSettings.m_bPVRCacheInDvdPlayer; + } +- +-double CDVDPlayer::GetClock(double& absolute, bool interpolated) +-{ +- return m_clock.GetClock(absolute, interpolated); +-} +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h +index 093318e..d3c201e 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.h ++++ b/xbmc/cores/dvdplayer/DVDPlayer.h +@@ -252,8 +252,6 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer + virtual bool SwitchChannel(const PVR::CPVRChannel &channel); + virtual bool CachePVRStream(void) const; + +- virtual double GetClock(double& absolute, bool interpolated = true); +- + enum ECacheState + { CACHESTATE_DONE = 0 + , CACHESTATE_FULL // player is filling up the demux queue +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 3bfe180..a90c141 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1363,7 +1363,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + if (index < 0) + return EOS_DROPPED; + +- g_renderManager.FlipPage(CThread::m_bStop, pts, -1, mDisplayField, m_speed); ++ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField, m_speed); + + return result; + #else +-- +1.7.10 + + +From aee70c4018b40358ff2e8a98727ccb55be65da63 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 1 Mar 2013 08:05:00 +0100 +Subject: [PATCH 13/88] RenderManager: some rework, squash add buffering + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index a2001c0..09daaef 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -616,6 +616,8 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; + m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; + m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; ++ if (!m_bUseBuffering) ++ PrepareNextRender(); + } + m_speed = speed; + } +@@ -825,17 +827,17 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) + if (!m_pRenderer) + return -1; + +- if(m_pRenderer->AddVideoPicture(&pic, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers)) ++ int index = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; ++ ++ if(m_pRenderer->AddVideoPicture(&pic, index)) + { + m_bRenderBufferUsed = true; + return 1; + } + + YV12Image image; +- int index = m_pRenderer->GetImage(&image, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); +- +- if(index < 0) +- return index; ++ if (m_pRenderer->GetImage(&image, index) < 0) ++ return -1; + + if(pic.format == RENDER_FMT_YUV420P + || pic.format == RENDER_FMT_YUV420P10 +@@ -947,14 +949,14 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) + if (!m_pRenderer) + return -1; + +- double maxwait = GetPresentTime() + (float)timeout/1000; ++ XbmcThreads::EndTime endtime(timeout); + while(!HasFreeBuffer() && !bStop) + { + lock.Leave(); + m_flipEvent.WaitMSec(std::min(50, timeout)); +- if(GetPresentTime() > maxwait && !bStop) ++ if(endtime.IsTimePast()) + { +- if (timeout != 0) ++ if (timeout != 0 && !bStop) + CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); + return -1; + } +-- +1.7.10 + + +From 927a0787cf8c8eb9d87e1c39f1abc4adc680235a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 1 Mar 2013 08:07:07 +0100 +Subject: [PATCH 14/88] dvdplayer: disable buffering unil dropping is improved + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index a90c141..c02bb96 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1100,35 +1100,35 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + { + case RENDER_FMT_YUV420P: + formatstr = "YV12"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_YUV420P16: + formatstr = "YV12P16"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_YUV420P10: + formatstr = "YV12P10"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_NV12: + formatstr = "NV12"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_UYVY422: + formatstr = "UYVY"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_YUYV422: + formatstr = "YUY2"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_VDPAU: + formatstr = "VDPAU"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_DXVA: + formatstr = "DXVA"; +- buffering = true; ++ buffering = false; + break; + case RENDER_FMT_VAAPI: + formatstr = "VAAPI"; +-- +1.7.10 + + +From b4dba473cb37652a888d8a47cb37d4f489ff8133 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 2 Mar 2013 12:00:51 +0100 +Subject: [PATCH 15/88] RenderManager: skip very late frames in render buffer + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index 09daaef..9897f1c 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -1053,13 +1053,30 @@ void CXBMCRenderManager::PrepareNextRender() + return; + } + +- double presenttime = m_renderBuffers[idx].timestamp; + double clocktime = GetPresentTime(); ++ double frametime = 1 / g_graphicsContext.GetFPS(); ++ ++ // look ahead in the queue ++ // if the next frame is already late, skip the one we are about to render ++ while (idx != m_iOutputRenderBuffer) ++ { ++ int idx_next = (idx + 1) % m_iNumRenderBuffers; ++ if (m_renderBuffers[idx_next].timestamp <= clocktime) ++ { ++ FlipRenderBuffer(); ++ idx = GetNextRenderBufferIndex(); ++ CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); ++ } ++ else ++ break; ++ } ++ ++ double presenttime = m_renderBuffers[idx].timestamp; ++ + if(presenttime - clocktime > MAXPRESENTDELAY) + presenttime = clocktime + MAXPRESENTDELAY; + + m_sleeptime = presenttime - clocktime; +- double frametime = 1 / g_graphicsContext.GetFPS(); + + if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) + { +-- +1.7.10 + + +From c77b0cded556ed2e5a83df8df37278cc40490123 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 2 Mar 2013 12:10:17 +0100 +Subject: [PATCH 16/88] renderbuffers: drop enable/disable in this iteration + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 4 ++++ + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 ---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index 9897f1c..e479adc 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -266,6 +266,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi + m_presentstep = PRESENT_IDLE; + m_presentevent.Set(); + ResetRenderBuffer(); ++ EnableBuffering(buffering); + } + + return result; +@@ -1093,7 +1094,10 @@ void CXBMCRenderManager::EnableBuffering(bool enable) + CRetakeLock lock(m_sharedSection); + + if (m_iNumRenderBuffers < 3) ++ { ++ m_bUseBuffering = false; + return; ++ } + + m_bUseBuffering = enable; + if (!m_bUseBuffering) +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index c02bb96..1d3c7e3 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -261,7 +261,6 @@ void CDVDPlayerVideo::OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec) + m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; + m_started = false; + m_codecname = m_pVideoCodec->GetName(); +- g_renderManager.EnableBuffering(false); + } + + void CDVDPlayerVideo::CloseStream(bool bWaitForBuffers) +@@ -437,7 +436,6 @@ void CDVDPlayerVideo::Process() + picture.iFlags &= ~DVP_FLAG_ALLOCATED; + m_packets.clear(); + m_started = false; +- g_renderManager.EnableBuffering(false); + } + else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) + { +@@ -450,7 +448,6 @@ void CDVDPlayerVideo::Process() + //we need to recalculate the framerate + //TODO: this needs to be set on a streamchange instead + ResetFrameRateCalc(); +- g_renderManager.EnableBuffering(false); + + m_stalled = true; + m_started = false; +@@ -705,7 +702,6 @@ void CDVDPlayerVideo::Process() + m_codecname = m_pVideoCodec->GetName(); + m_started = true; + m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO)); +- g_renderManager.EnableBuffering(true); + } + + // guess next frame pts. iDuration is always valid +-- +1.7.10 + + +From 094da266d519fd5385ca99866817f7b51944a0c0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 2 Mar 2013 12:31:11 +0100 +Subject: [PATCH 17/88] RenderManager: add method SetSpeed + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 10 +++++++--- + xbmc/cores/VideoRenderers/RenderManager.h | 8 ++++++-- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 3 ++- + 3 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index e479adc..dc984cf 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -550,7 +550,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) + m_pRenderer->SetViewMode(iViewMode); + } + +-void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/, int speed /*= 1000*/) ++void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) + { + if (!m_bUseBuffering) + { +@@ -620,7 +620,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + if (!m_bUseBuffering) + PrepareNextRender(); + } +- m_speed = speed; + } + + g_application.NewFrame(); +@@ -1038,7 +1037,7 @@ void CXBMCRenderManager::ResetRenderBuffer() + m_iDisplayedRenderBuffer = 0; + m_bAllRenderBuffersDisplayed = true; + m_sleeptime = 1.0; +- m_speed = 0; ++ m_speed = DVD_PLAYSPEED_NORMAL; + m_bRenderBufferUsed = false; + m_bOverlayReleased = false; + } +@@ -1112,6 +1111,11 @@ void CXBMCRenderManager::DiscardBuffer() + m_iOutputRenderBuffer = m_iCurrentRenderBuffer; + } + ++void CXBMCRenderManager::SetSpeed(int speed) ++{ ++ m_speed = speed; ++} ++ + void CXBMCRenderManager::NotifyDisplayFlip() + { + CRetakeLock lock(m_sharedSection); +diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h +index 858a547..c9edb64 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.h ++++ b/xbmc/cores/VideoRenderers/RenderManager.h +@@ -96,9 +96,8 @@ class CXBMCRenderManager + * @param timestamp of frame delivered with AddVideoPicture + * @param source depreciated + * @param sync signals frame, top, or bottom field +- * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind + */ +- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); ++ void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); + unsigned int PreInit(); + void UnInit(); + bool Flush(); +@@ -188,6 +187,11 @@ class CXBMCRenderManager + */ + void DiscardBuffer(); + ++ /** ++ * notify RenderManager about play speed ++ */ ++ void SetSpeed(int speed); ++ + protected: + void Render(bool clear, DWORD flags, DWORD alpha); + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 1d3c7e3..db4f7bd 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -465,6 +465,7 @@ void CDVDPlayerVideo::Process() + m_speed = static_cast(pMsg)->m_value; + if(m_speed == DVD_PLAYSPEED_PAUSE) + m_iNrOfPicturesNotToSkip = 0; ++ g_renderManager.SetSpeed(m_speed); + } + else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) + { +@@ -1359,7 +1360,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + if (index < 0) + return EOS_DROPPED; + +- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField, m_speed); ++ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); + + return result; + #else +-- +1.7.10 + + +From e46b7cb93cc01827dc03966dd8f0d3cbdbbc8f60 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 10 Feb 2013 18:40:30 +0100 +Subject: [PATCH 18/88] OMXPlayer: adapt to buffering + +--- + xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 25 ++++++++----------------- + 1 file changed, 8 insertions(+), 17 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +index 4d813db..8b1c06e 100644 +--- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +@@ -359,7 +359,7 @@ void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) + + if(!g_renderManager.Configure(m_hints.width, m_hints.height, + iDisplayWidth, iDisplayHeight, m_fps, flags, format, 0, +- m_hints.orientation)) ++ m_hints.orientation, true)) + { + CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); + return; +@@ -453,25 +453,16 @@ void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) + m_dropbase = 0.0f; + #endif + +- // DVDPlayer sleeps until m_iSleepEndTime here before calling FlipPage. +- // Video playback in asynchronous in OMXPlayer, so we don't want to do that here, as it prevents the video fifo from being kept full. +- // So, we keep track of when FlipPage would have been called on DVDPlayer and return early if it is not time. +- // m_iSleepEndTime == DVD_NOPTS_VALUE means we are not waiting to call FlipPage, otherwise it is the time we want to call FlipPage +- if (m_iSleepEndTime == DVD_NOPTS_VALUE) { +- m_iSleepEndTime = iCurrentClock + iSleepTime; +- } +- +- if (!CThread::m_bStop && m_av_clock->GetAbsoluteClock(false) < m_iSleepEndTime + DVD_MSEC_TO_TIME(500)) ++ int buffer = g_renderManager.WaitForBuffer(m_bStop, 0); ++ if (buffer < 0) + return; + +- double pts_media = m_av_clock->OMXMediaTime(false, false); +- ProcessOverlays(iGroupId, pts_media); +- +- g_renderManager.FlipPage(CThread::m_bStop, m_iSleepEndTime / DVD_TIME_BASE, -1, FS_NONE); +- +- m_iSleepEndTime = DVD_NOPTS_VALUE; ++ double pts_overlay = m_av_clock->OMXMediaTime(false, false) ++ + 2* (double)DVD_TIME_BASE / g_graphicsContext.GetFPS(); ++ ProcessOverlays(iGroupId, pts_overlay); + +- //m_av_clock->WaitAbsoluteClock((iCurrentClock + iSleepTime)); ++ double timestamp = CDVDClock::GetAbsoluteClock(false) + 2 / g_graphicsContext.GetFPS(); ++ g_renderManager.FlipPage(CThread::m_bStop, timestamp, -1, FS_NONE); + } + + void OMXPlayerVideo::Process() +-- +1.7.10 + + +From b4f1ed7fd41c48b9ec199cce6854d6f2e25f53c0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 2 Mar 2013 20:42:10 +0100 +Subject: [PATCH 19/88] overlays: squash to + b0b5c7c825b0265c5e7c888a48a76d11eb719246 + +--- + xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 19 +++++++++---------- + xbmc/cores/VideoRenderers/OverlayRenderer.h | 4 ++-- + xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +++- + 3 files changed, 14 insertions(+), 13 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +index 5592eca..8559720 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +@@ -127,32 +127,31 @@ void CRenderer::AddCleanup(COverlay* o) + m_cleanup.push_back(o->Acquire()); + } + +-long CRenderer::Release(SElementV& list) ++bool CRenderer::Release(SElementV& list) + { + SElementV l = list; + list.clear(); + +- long count = 0; ++ bool change = false; + for(SElementV::iterator it = l.begin(); it != l.end(); it++) + { + if(it->overlay) +- count += it->overlay->Release(); ++ it->overlay->Release(); + if(it->overlay_dvd) +- count += it->overlay_dvd->Release(); ++ it->overlay_dvd->Release(); ++ ++ change = true; + } +- return count; ++ return change; + } + +-long CRenderer::Release(COverlayV& list) ++void CRenderer::Release(COverlayV& list) + { + COverlayV l = list; + list.clear(); + +- long count = 0; + for(COverlayV::iterator it = l.begin(); it != l.end(); it++) +- count += (*it)->Release(); +- +- return count; ++ (*it)->Release(); + } + + void CRenderer::Flush() +diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h +index 627dd9f..e0c497d 100644 +--- a/xbmc/cores/VideoRenderers/OverlayRenderer.h ++++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h +@@ -123,8 +123,8 @@ + COverlay* Convert(CDVDOverlay* o, double pts); + COverlay* Convert(CDVDOverlaySSA* o, double pts); + +- long Release(COverlayV& list); +- long Release(SElementV& list); ++ void Release(COverlayV& list); ++ bool Release(SElementV& list); + + CCriticalSection m_section; + SElementV m_buffers[NUM_BUFFERS]; +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index dc984cf..1343a71 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -967,6 +967,8 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) + if (bStop) + return -1; + ++ // make sure overlay buffer is released, this won't happen on AddOverlay ++ m_overlays.ReleaseBuffer((m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); + return 1; + } + +@@ -1131,7 +1133,7 @@ void CXBMCRenderManager::NotifyDisplayFlip() + && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) + { + m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); +- if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer) > 0) ++ if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer)) + m_bOverlayReleased = true; + } + } +-- +1.7.10 + + +From 652203771888444899ae4b2655224d4022278c56 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 05/73] videoplayer: adopt lateness detection and dropping to +Subject: [PATCH 20/88] videoplayer: adapt lateness detection and dropping to buffering --- - xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++ - xbmc/cores/VideoRenderers/RenderManager.h | 1 + + xbmc/cores/VideoRenderers/RenderManager.cpp | 17 +- + xbmc/cores/VideoRenderers/RenderManager.h | 11 +- .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 14 ++ .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 31 +++ .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 + - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 224 ++++++++++++++++---- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 226 ++++++++++++++++---- xbmc/cores/dvdplayer/DVDPlayerVideo.h | 24 +++ - 7 files changed, 268 insertions(+), 45 deletions(-) + 7 files changed, 282 insertions(+), 48 deletions(-) diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 4b897da..f19797c 100644 +index 1343a71..c4ca57e 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1105,6 +1105,18 @@ void CXBMCRenderManager::NotifyDisplayFlip() +@@ -550,7 +550,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) + m_pRenderer->SetViewMode(iViewMode); + } + +-void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) ++void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) + { + if (!m_bUseBuffering) + { +@@ -614,6 +614,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L + + if (FlipFreeBuffer() >= 0) + { ++ m_renderBuffers[m_iOutputRenderBuffer].pts = pts; + m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; + m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; + m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; +@@ -1040,6 +1041,7 @@ void CXBMCRenderManager::ResetRenderBuffer() + m_bAllRenderBuffersDisplayed = true; + m_sleeptime = 1.0; + m_speed = DVD_PLAYSPEED_NORMAL; ++ m_presentPts = DVD_NOPTS_VALUE; + m_bRenderBufferUsed = false; + m_bOverlayReleased = false; + } +@@ -1082,6 +1084,7 @@ void CXBMCRenderManager::PrepareNextRender() + + if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) + { ++ m_presentPts = m_renderBuffers[idx].pts; + m_presenttime = presenttime; + m_presentmethod = m_renderBuffers[idx].presentmethod; + m_presentfield = m_renderBuffers[idx].presentfield; +@@ -1142,6 +1145,18 @@ void CXBMCRenderManager::NotifyDisplayFlip() m_flipEvent.Set(); } @@ -1282,17 +2830,50 @@ index 4b897da..f19797c 100644 { CSharedLock lock(m_sharedSection); diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 288175e..9342586 100644 +index c9edb64..b3e6547 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -134,6 +134,7 @@ class CXBMCRenderManager - void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn); - int WaitForBuffer(volatile bool& bStop); - void NotifyDisplayFlip(); -+ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); +@@ -94,10 +94,11 @@ class CXBMCRenderManager + * + * @param bStop reference to stop flag of calling thread + * @param timestamp of frame delivered with AddVideoPicture ++ * @param pts used for lateness detection + * @param source depreciated + * @param sync signals frame, top, or bottom field + */ +- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); ++ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); + unsigned int PreInit(); + void UnInit(); + bool Flush(); +@@ -177,6 +178,12 @@ class CXBMCRenderManager bool HasFrame(); - void EnableBuffering(bool enable); - void DiscardBuffer(); + + /** ++ * Can be called by player for lateness detection. This is done best by ++ * looking at the end of the queue. ++ */ ++ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); ++ ++ /** + * Video player can dynamically enable/disable buffering. In situations like + * rewind buffering is not ideal. + */ +@@ -261,12 +268,14 @@ class CXBMCRenderManager + + struct + { ++ double pts; + double timestamp; + EFIELDSYNC presentfield; + EPRESENTMETHOD presentmethod; + }m_renderBuffers[5]; + + double m_sleeptime; ++ double m_presentPts; + + double m_presenttime; + double m_presentcorr; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h index 1d8bad3..5001aac 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h @@ -1331,7 +2912,7 @@ index 1d8bad3..5001aac 100644 + virtual void SetCodecControl(int flags) {} }; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 8f81637..af706bd 100644 +index 286fd67..dae3b8e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -142,6 +142,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx @@ -1428,10 +3009,10 @@ index 61d0305..52e1113 100644 + int m_codecControlFlags; }; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index a4bb1ba..93908a7 100644 +index db4f7bd..5484073 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -326,8 +326,10 @@ void CDVDPlayerVideo::Process() +@@ -325,8 +325,10 @@ void CDVDPlayerVideo::Process() int iDropped = 0; //frames dropped in a row bool bRequestDrop = false; @@ -1442,31 +3023,31 @@ index a4bb1ba..93908a7 100644 while (!m_bStop) { -@@ -437,6 +439,7 @@ void CDVDPlayerVideo::Process() +@@ -436,6 +438,7 @@ void CDVDPlayerVideo::Process() picture.iFlags &= ~DVP_FLAG_ALLOCATED; m_packets.clear(); m_started = false; + m_droppingStats.Reset(); - g_renderManager.EnableBuffering(false); } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) -@@ -450,6 +453,7 @@ void CDVDPlayerVideo::Process() + { +@@ -448,6 +451,7 @@ void CDVDPlayerVideo::Process() //we need to recalculate the framerate //TODO: this needs to be set on a streamchange instead ResetFrameRateCalc(); + m_droppingStats.Reset(); - g_renderManager.EnableBuffering(false); m_stalled = true; -@@ -468,6 +472,7 @@ void CDVDPlayerVideo::Process() - m_speed = static_cast(pMsg)->m_value; + m_started = false; +@@ -466,6 +470,7 @@ void CDVDPlayerVideo::Process() if(m_speed == DVD_PLAYSPEED_PAUSE) m_iNrOfPicturesNotToSkip = 0; + g_renderManager.SetSpeed(m_speed); + m_droppingStats.Reset(); } else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) { -@@ -502,6 +507,28 @@ void CDVDPlayerVideo::Process() +@@ -500,6 +505,28 @@ void CDVDPlayerVideo::Process() m_iNrOfPicturesNotToSkip = 1; } @@ -1495,7 +3076,7 @@ index a4bb1ba..93908a7 100644 #ifdef PROFILE bRequestDrop = false; #else -@@ -511,6 +538,7 @@ void CDVDPlayerVideo::Process() +@@ -509,6 +536,7 @@ void CDVDPlayerVideo::Process() bRequestDrop = false; m_iDroppedRequest = 0; m_iLateFrames = 0; @@ -1503,7 +3084,7 @@ index a4bb1ba..93908a7 100644 } #endif -@@ -558,15 +586,8 @@ void CDVDPlayerVideo::Process() +@@ -556,15 +584,8 @@ void CDVDPlayerVideo::Process() } m_videoStats.AddSampleBytes(pPacket->iSize); @@ -1521,7 +3102,7 @@ index a4bb1ba..93908a7 100644 // loop while no error while (!m_bStop) -@@ -1244,50 +1265,30 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1255,50 +1276,30 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) m_FlipTimeStamp += max(0.0, iSleepTime); m_FlipTimeStamp += iFrameDuration; @@ -1588,7 +3169,16 @@ index a4bb1ba..93908a7 100644 { // calculate frame dropping pattern to render at this speed // we do that by deciding if this or next frame is closest -@@ -1648,3 +1649,136 @@ void CDVDPlayerVideo::CalcFrameRate() +@@ -1360,7 +1361,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + if (index < 0) + return EOS_DROPPED; + +- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); ++ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); + + return result; + #else +@@ -1659,3 +1660,136 @@ void CDVDPlayerVideo::CalcFrameRate() m_iFrameRateCount = 0; } } @@ -1784,104 +3374,10 @@ index fe7e12c..4913712 100644 1.7.10 -From 18bb11c657eca56a2454b15ec558b6e6b126a52b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 06/73] videoplayer: update frametime, it might change due to - fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 93908a7..4675556 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -721,6 +721,8 @@ void CDVDPlayerVideo::Process() - CDVDCodecUtils::FreePicture(pTempYUVPackedPicture); - #endif - -+ frametime = (double)DVD_TIME_BASE/m_fFrameRate; -+ - if(m_started == false) - { - m_codecname = m_pVideoCodec->GetName(); --- -1.7.10 - - -From 0f3e41aa9f5f61baad9558606ff9ccacf3ef5192 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 07/73] videoplayer: give streams with invalid fps a chance - for fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 4675556..2ef6358 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1595,7 +1595,7 @@ void CDVDPlayerVideo::CalcFrameRate() - double frameduration = m_pullupCorrection.GetFrameDuration(); - - if (frameduration == DVD_NOPTS_VALUE || -- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) -+ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) - { - //reset the stored framerates if no good framerate was detected - m_fStableFrameRate = 0.0; --- -1.7.10 - - -From 5ea05eef35600708fa58ba121e32245d09cd491e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 08/73] dvdplayer: allow rewinding at end of stream, do a seek - after rewind - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 315d64a..6fcb6b3 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1542,7 +1542,7 @@ void CDVDPlayer::HandlePlaySpeed() - - } - else if (m_CurrentVideo.id >= 0 -- && m_CurrentVideo.inited == true -+ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file - && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() - && m_SpeedState.lasttime != GetTime()) - { -@@ -2183,6 +2183,12 @@ void CDVDPlayer::HandleMessages() - pvrinputstream->Pause( speed == 0 ); - } - -+ // do a seek after rewind, clock is not in sync with current pts -+ if (m_playSpeed < 0 && speed >= 0) -+ { -+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ } -+ - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE - // audioplayer, stops outputing audio to audiorendere, but still tries to - // sleep an correct amount for each packet --- -1.7.10 - - -From d42b9a3ed15f855f9e4aecaae176f8aeeb4b8da2 Mon Sep 17 00:00:00 2001 +From cf731f6c3d24d7e53ed79402b01666aa6dae0991 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 09/73] video player: present correct pts to user for a/v sync +Subject: [PATCH 21/88] video player: present correct pts to user for a/v sync (after buffering in renderer) --- @@ -1890,10 +3386,10 @@ Subject: [PATCH 09/73] video player: present correct pts to user for a/v sync 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 2ef6358..10e2225 100644 +index 5484073..8ac5a32 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1251,22 +1251,6 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1260,22 +1260,6 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) else iSleepTime = iFrameSleep + (iClockSleep - iFrameSleep) / m_autosync; @@ -1916,7 +3412,7 @@ index 2ef6358..10e2225 100644 if ((m_droppingStats.m_requestOutputDrop && !(pPicture->iFlags & DVP_FLAG_NOSKIP)) || (pPicture->iFlags & DVP_FLAG_DROPPED)) { -@@ -1571,6 +1555,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc() +@@ -1580,6 +1564,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc() g_advancedSettings.m_videoFpsDetect == 0; } @@ -1939,7 +3435,7 @@ index 2ef6358..10e2225 100644 #define MAXFRAMERATEDIFF 0.01 #define MAXFRAMESERR 1000 -@@ -1689,6 +1689,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) +@@ -1698,6 +1698,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) else iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; @@ -1972,71 +3468,281 @@ index 4913712..509d5f7 100644 1.7.10 -From fba7871aacd8c0b7cac5eafdc4d3da5d3724cf79 Mon Sep 17 00:00:00 2001 +From 5e05def8121969dbf936848e2025e419e68335a5 Mon Sep 17 00:00:00 2001 From: xbmc -Date: Mon, 28 May 2012 11:02:29 +0200 -Subject: [PATCH 10/73] vaapi: adopt to buffering in renderer +Date: Sat, 16 Feb 2013 18:25:53 +0100 +Subject: [PATCH 22/88] videoplayer: some rework and documentation --- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 3 ++- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 1 + - 3 files changed, 4 insertions(+), 2 deletions(-) + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 29 ++++++++++++++++++-- + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 11 ++++++++ + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 4 files changed, 40 insertions(+), 4 deletions(-) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +index 5001aac..e84e65f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +@@ -132,7 +132,6 @@ struct DVDVideoUserData + #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data + #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again + #define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped +-#define VC_HURRY 0x00000040 + + class CDVDVideoCodec + { +@@ -245,10 +244,36 @@ class CDVDVideoCodec + return 0; + } + +- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) ++ /** ++ * For calculation of dropping requirements player asks for some information. ++ * ++ * - pts : right after decoder, used to detect gaps (dropped frames in decoder) ++ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle ++ * instead of dropping a full frame ++ * - interlaced : when detecting gaps in pts, player needs to know whether ++ * it's interlaced or not ++ * ++ * If codec does not implement this method, pts of decoded frame at input ++ * video player is used. In case coded does post-proc and de-interlacing there ++ * may be quite some frames queued up between exit decoder and entry player. ++ */ ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced) + { + return false; + } + ++ /** ++ * Codec can be informed by player with the following flags: ++ * ++ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off ++ * postprocessing and de-interlacing ++ * ++ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing. ++ * If video buffers in RenderManager are about to run dry, ++ * this is signaled to codec. Codec can wait for post-proc ++ * to be finished instead of returning empty and getting another ++ * packet. ++ * ++ */ + virtual void SetCodecControl(int flags) {} + }; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index af706bd..dae3b8e 100644 +index dae3b8e..2c2353d 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -106,7 +106,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - && (avctx->codec_id != CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) - { - VAAPI::CDecoder* dec = new VAAPI::CDecoder(); -- if(dec->Open(avctx, *cur)) -+ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) - { - ctx->SetHardware(dec); - return *cur; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 9f5a960..a2b9195 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -357,6 +357,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su - CHECK(vaCreateConfig(m_display->get(), profile, entrypoint, &attrib, 1, &m_hwaccel->config_id)) - m_config = m_hwaccel->config_id; - -+ m_renderbuffers_count = surfaces; - if (!EnsureContext(avctx)) - return false; - -@@ -388,7 +389,7 @@ bool CDecoder::EnsureContext(AVCodecContext *avctx) - else - m_refs = 2; - } -- return EnsureSurfaces(avctx, m_refs + 3); -+ return EnsureSurfaces(avctx, m_refs + m_renderbuffers_count + 1); +@@ -888,6 +888,17 @@ unsigned CDVDVideoCodecFFmpeg::GetConvergeCount() + return 0; } - bool CDecoder::EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index 863edc4..417cbc0 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -122,6 +122,7 @@ class CDecoder - static const unsigned m_surfaces_max = 32; - unsigned m_surfaces_count; - VASurfaceID m_surfaces[m_surfaces_max]; -+ unsigned m_renderbuffers_count; ++bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced) ++{ ++ pts = m_decoderPts; ++ skippedDeint = m_skippedDeint; ++ if (m_pFrame) ++ interlaced = m_pFrame->interlaced_frame; ++ else ++ interlaced = 0; ++ return true; ++} ++ + void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) + { + m_codecControlFlags = flags; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +index 52e1113..3631f7f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -61,7 +61,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec + virtual unsigned int SetFilters(unsigned int filters); + virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open + virtual unsigned GetConvergeCount(); +- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced); + virtual void SetCodecControl(int flags); - int m_refs; - std::list m_surfaces_used; + bool IsHardwareAllowed() { return !m_bSoftware; } +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 8ac5a32..12b08ac 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1675,7 +1675,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) + int iBufferLevel; + + // get decoder stats +- if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) ++ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) + iDecoderPts = pts; + if (iDecoderPts == DVD_NOPTS_VALUE) + iDecoderPts = pts; -- 1.7.10 -From b8f4a9b323ceea4950624525c88339fb2a23ebe7 Mon Sep 17 00:00:00 2001 +From 903e78e4320a8549eccd0a710eac7747032c18eb Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 1 Mar 2013 09:57:16 +0100 +Subject: [PATCH 23/88] Revert "dvdplayer: disable buffering unit dropping is + improves" + +This reverts commit de1caf5686c1fb53cb7ab11b356e6c22770740db. +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 12b08ac..3297513 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1118,35 +1118,35 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) + { + case RENDER_FMT_YUV420P: + formatstr = "YV12"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_YUV420P16: + formatstr = "YV12P16"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_YUV420P10: + formatstr = "YV12P10"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_NV12: + formatstr = "NV12"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_UYVY422: + formatstr = "UYVY"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_YUYV422: + formatstr = "YUY2"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_VDPAU: + formatstr = "VDPAU"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_DXVA: + formatstr = "DXVA"; +- buffering = false; ++ buffering = true; + break; + case RENDER_FMT_VAAPI: + formatstr = "VAAPI"; +-- +1.7.10 + + +From 82974290389d5caa2692079301b167cb80323491 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:41:31 +0200 +Subject: [PATCH 24/88] videoplayer: update frametime, it might change due to + fps detection + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 3297513..8eb2eda 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -719,6 +719,8 @@ void CDVDPlayerVideo::Process() + CDVDCodecUtils::FreePicture(pTempYUVPackedPicture); + #endif + ++ frametime = (double)DVD_TIME_BASE/m_fFrameRate; ++ + if(m_started == false) + { + m_codecname = m_pVideoCodec->GetName(); +-- +1.7.10 + + +From 5b62f34f8013302cd10c06944120032ec1f8d555 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:43:06 +0200 +Subject: [PATCH 25/88] videoplayer: give streams with invalid fps a chance + for fps detection + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index 8eb2eda..d004153 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1606,7 +1606,7 @@ void CDVDPlayerVideo::CalcFrameRate() + double frameduration = m_pullupCorrection.GetFrameDuration(); + + if (frameduration == DVD_NOPTS_VALUE || +- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) ++ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) + { + //reset the stored framerates if no good framerate was detected + m_fStableFrameRate = 0.0; +-- +1.7.10 + + +From 7493aa51685421085be83c56c62267709b22c65f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 28 May 2012 10:49:05 +0200 +Subject: [PATCH 26/88] dvdplayer: allow rewinding at end of stream, do a seek + after rewind + +--- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp +index 0cd2510..3737419 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp +@@ -1542,7 +1542,7 @@ void CDVDPlayer::HandlePlaySpeed() + + } + else if (m_CurrentVideo.id >= 0 +- && m_CurrentVideo.inited == true ++ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file + && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() + && m_SpeedState.lasttime != GetTime()) + { +@@ -2183,6 +2183,12 @@ void CDVDPlayer::HandleMessages() + pvrinputstream->Pause( speed == 0 ); + } + ++ // do a seek after rewind, clock is not in sync with current pts ++ if (m_playSpeed < 0 && speed >= 0) ++ { ++ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); ++ } ++ + // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE + // audioplayer, stops outputing audio to audiorendere, but still tries to + // sleep an correct amount for each packet +-- +1.7.10 + + +From 4ae2ba6880415872258c400fae19e58307ed4828 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 7 Apr 2012 09:19:00 +0200 -Subject: [PATCH 11/73] vdpau: redesign +Subject: [PATCH 27/88] vdpau: redesign --- language/English/strings.po | 12 +- @@ -2044,15 +3750,15 @@ Subject: [PATCH 11/73] vdpau: redesign xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 203 +- xbmc/cores/VideoRenderers/LinuxRendererGL.h | 13 +- xbmc/cores/VideoRenderers/RenderFormats.h | 1 + - xbmc/cores/VideoRenderers/RenderManager.cpp | 8 +- + xbmc/cores/VideoRenderers/RenderManager.cpp | 3 +- xbmc/cores/VideoRenderers/RenderManager.h | 2 +- .../VideoRenderers/VideoShaders/YUV2RGBShader.cpp | 2 + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 +- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 23 +- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 1 - - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 3798 +++++++++++++++----- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 3800 +++++++++++++++----- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 662 +++- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 3 + + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 + xbmc/settings/AdvancedSettings.cpp | 8 +- xbmc/settings/AdvancedSettings.h | 4 +- xbmc/settings/GUISettings.cpp | 2 + @@ -2062,7 +3768,7 @@ Subject: [PATCH 11/73] vdpau: redesign xbmc/utils/Makefile | 1 + xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 2 +- xbmc/windowing/X11/WinSystemX11.h | 1 + - 23 files changed, 3942 insertions(+), 1194 deletions(-) + 23 files changed, 3942 insertions(+), 1192 deletions(-) create mode 100644 xbmc/utils/ActorProtocol.cpp create mode 100644 xbmc/utils/ActorProtocol.h @@ -2425,10 +4131,10 @@ index a2dc2be..4ee50c1 100644 #endif diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 9f55fcb..3218cd5 100644 +index a7b5886..329ddee 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -38,15 +38,14 @@ +@@ -38,12 +38,11 @@ class CRenderCapture; @@ -2437,15 +4143,12 @@ index 9f55fcb..3218cd5 100644 namespace Shaders { class BaseYUV2RGBShader; } namespace Shaders { class BaseVideoFilterShader; } namespace VAAPI { struct CHolder; } +- +namespace VDPAU { class CVdpauRenderPicture; } - #define NUM_BUFFERS 10 - -- #undef ALIGN #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) - #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) -@@ -144,7 +143,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -142,7 +141,7 @@ class CLinuxRendererGL : public CBaseRenderer virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } #ifdef HAVE_LIBVDPAU @@ -2454,7 +4157,7 @@ index 9f55fcb..3218cd5 100644 #endif #ifdef HAVE_LIBVA virtual void AddProcessor(VAAPI::CHolder& holder, int index); -@@ -195,6 +194,10 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -193,6 +192,10 @@ class CLinuxRendererGL : public CBaseRenderer void DeleteVDPAUTexture(int index); bool CreateVDPAUTexture(int index); @@ -2465,7 +4168,7 @@ index 9f55fcb..3218cd5 100644 void UploadVAAPITexture(int index); void DeleteVAAPITexture(int index); bool CreateVAAPITexture(int index); -@@ -221,6 +224,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -219,6 +222,7 @@ class CLinuxRendererGL : public CBaseRenderer void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware @@ -2473,7 +4176,7 @@ index 9f55fcb..3218cd5 100644 void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware struct -@@ -281,7 +285,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -279,7 +283,7 @@ class CLinuxRendererGL : public CBaseRenderer GLuint pbo[MAX_PLANES]; #ifdef HAVE_LIBVDPAU @@ -2482,7 +4185,7 @@ index 9f55fcb..3218cd5 100644 #endif #ifdef HAVE_LIBVA VAAPI::CHolder& vaapi; -@@ -327,6 +331,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -325,6 +329,7 @@ class CLinuxRendererGL : public CBaseRenderer bool m_nonLinStretch; bool m_nonLinStretchGui; float m_pixelRatio; @@ -2503,22 +4206,10 @@ index 09f8f5d..0262c60 100644 RENDER_FMT_UYVY422, RENDER_FMT_YUYV422, diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index f19797c..a521680 100644 +index c4ca57e..b89ec67 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -250,8 +250,9 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - - // check if decoder supports buffering - m_bCodecSupportsBuffering = false; --// if (format == RENDER_FMT_VDPAU) --// m_bCodecSupportsBuffering = true; -+ if (format == RENDER_FMT_VDPAU || -+ format == RENDER_FMT_VDPAU_420) -+ m_bCodecSupportsBuffering = true; - - bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation); - if(result) -@@ -856,7 +857,8 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) +@@ -860,7 +860,8 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) CDVDCodecUtils::CopyDXVA2Picture(&image, &pic); } #ifdef HAVE_LIBVDPAU @@ -2529,7 +4220,7 @@ index f19797c..a521680 100644 #endif #ifdef HAVE_LIBOPENMAX diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 9342586..6746957 100644 +index b3e6547..e4bd614 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h @@ -35,7 +35,7 @@ @@ -2555,7 +4246,7 @@ index 58f26b0..50606eb 100644 CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 5001aac..98d8f89 100644 +index e84e65f..64c5f5f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h @@ -34,7 +34,7 @@ @@ -2577,7 +4268,7 @@ index 5001aac..98d8f89 100644 struct { VAAPI::CHolder* vaapi; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index dae3b8e..a6e42e5 100644 +index 2c2353d..e0c0f84 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -71,14 +71,14 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx @@ -2629,7 +4320,7 @@ index dae3b8e..a6e42e5 100644 m_pHardware = vdp; m_pCodecContext->codec_id = CODEC_ID_NONE; // ffmpeg will complain if this has been set diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 52e1113..bf4367c 100644 +index 3631f7f..17a12d0 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h @@ -28,7 +28,6 @@ @@ -2641,7 +4332,7 @@ index 52e1113..bf4367c 100644 class CDVDVideoCodecFFmpeg : public CDVDVideoCodec diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index f70a4f9..235f565 100644 +index f70a4f9..07cfc04 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp @@ -32,11 +32,16 @@ @@ -4513,7 +6204,7 @@ index f70a4f9..235f565 100644 if(m_DisplayState == VDPAU_OPEN) { -@@ -1671,4 +1081,2422 @@ bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line) +@@ -1671,4 +1081,2424 @@ bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line) return false; } @@ -5488,6 +7179,8 @@ index f70a4f9..235f565 100644 + m_outputSurfaces.pop(); + } + m_config.vdpProcs.vdp_video_mixer_destroy(m_videoMixer); ++ ++ delete [] m_BlackBar; +} + +void CMixer::Flush() @@ -7670,19 +9363,20 @@ index 2f53edf..4d1559c 100644 + +} diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 10e2225..15a39fa 100644 +index d004153..92f62bb 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1141,6 +1141,9 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - case RENDER_FMT_VDPAU: +@@ -1146,6 +1146,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) formatstr = "VDPAU"; + buffering = true; break; + case RENDER_FMT_VDPAU_420: + formatstr = "VDPAU_420"; ++ buffering = true; + break; case RENDER_FMT_DXVA: formatstr = "DXVA"; - break; + buffering = true; diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 16800b7..844f8e8 100644 --- a/xbmc/settings/AdvancedSettings.cpp @@ -8196,10 +9890,548 @@ index e7af3cb..2dd8a9f 100644 1.7.10 -From ee1ed2c835620021278e38a6e7be94cfde073a78 Mon Sep 17 00:00:00 2001 +From 999408daf66880f2efca154bf70bf2b778a5b67b Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 12 Dec 2012 09:52:17 +0100 +Subject: [PATCH 28/88] vdpau: make interop gl default and remove setting, + rename and intvert interop yuv + +--- + language/English/strings.po | 2 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 17 ++++++++++------- + xbmc/settings/GUISettings.cpp | 3 +-- + xbmc/settings/GUIWindowSettingsCategory.cpp | 23 +++-------------------- + 4 files changed, 15 insertions(+), 30 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 88292d3..4094fd0 100644 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -5119,7 +5119,7 @@ msgid "Allow Vdpau OpenGL interop" + msgstr "" + + msgctxt "#13436" +-msgid "Allow Vdpau OpenGL interop YUV" ++msgid "Prefer VDPAU Video Mixer" + msgstr "" + + #empty strings from id 13437 to 13499 +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 07cfc04..0381c44 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -365,12 +365,15 @@ bool CDecoder::Supports(EINTERLACEMETHOD method) + || method == VS_INTERLACEMETHOD_AUTO) + return true; + +- if (g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv")) ++ if (!m_vdpauConfig.usePixmaps) + { + if (method == VS_INTERLACEMETHOD_RENDER_BOB) + return true; + } + ++ if (method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE) ++ return false; ++ + for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) + { + if(p->method == method) +@@ -1847,7 +1850,7 @@ void CMixer::SetDeinterlacing() + + SetDeintSkipChroma(); + +- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); ++ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); + } + + void CMixer::SetDeintSkipChroma() +@@ -2039,7 +2042,7 @@ void CMixer::Init() + m_vdpError = false; + + m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; +- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); ++ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); + + CreateVdpauMixer(); + } +@@ -2149,11 +2152,12 @@ void CMixer::InitCycle() + DVP_FLAG_INTERLACED); + m_config.useInteropYuv = false; + } +- else if (method == VS_INTERLACEMETHOD_RENDER_BOB && m_config.useInteropYuv) ++ else if (method == VS_INTERLACEMETHOD_RENDER_BOB) + { + m_mixersteps = 1; + m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; + m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; ++ m_config.useInteropYuv = true; + } + else + { +@@ -3185,7 +3189,7 @@ bool COutput::GLInit() + glVDPAUGetSurfaceivNV = NULL; + #endif + +- m_config.usePixmaps = !g_guiSettings.GetBool("videoplayer.usevdpauinterop"); ++ m_config.usePixmaps = false; + + #ifdef GL_NV_vdpau_interop + if (glewIsSupported("GL_NV_vdpau_interop")) +@@ -3217,8 +3221,7 @@ bool COutput::GLInit() + #endif + { + m_config.usePixmaps = true; +- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); +- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); ++ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); + } + if (!glXBindTexImageEXT) + glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); +diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp +index 4cdb093..33467d9 100644 +--- a/xbmc/settings/GUISettings.cpp ++++ b/xbmc/settings/GUISettings.cpp +@@ -685,8 +685,7 @@ void CGUISettings::Initialize() + + #ifdef HAVE_LIBVDPAU + AddBool(vp, "videoplayer.usevdpau", 13425, true); +- AddBool(vp, "videoplayer.usevdpauinterop", 13435, true); +- AddBool(vp, "videoplayer.usevdpauinteropyuv", 13436, false); ++ AddBool(vp, "videoplayer.usevdpaumixer", 13436, true); + #endif + #ifdef HAVE_LIBVA + AddBool(vp, "videoplayer.usevaapi", 13426, true); +diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp +index d988598..2af9315 100644 +--- a/xbmc/settings/GUIWindowSettingsCategory.cpp ++++ b/xbmc/settings/GUIWindowSettingsCategory.cpp +@@ -596,9 +596,9 @@ void CGUIWindowSettingsCategory::UpdateSettings() + pControl->SetEnabled(true); + } + } +- else if (strSetting.Equals("videoplayer.usevdpauinteropyuv")) ++ else if (strSetting.Equals("videoplayer.usevdpaumixer")) + { +- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpauinterop"); ++ bool hasInterop = true; + #ifndef GL_NV_vdpau_interop + hasInterop = false; + #endif +@@ -610,24 +610,7 @@ void CGUIWindowSettingsCategory::UpdateSettings() + else + { + pControl->SetEnabled(false); +- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); +- } +- } +- else if (strSetting.Equals("videoplayer.usevdpauinterop")) +- { +- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpau"); +-#ifndef GL_NV_vdpau_interop +- hasInterop = false; +-#endif +- CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); +- if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) +- { +- pControl->SetEnabled(true); +- } +- else +- { +- pControl->SetEnabled(false); +- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); ++ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); + } + } + else +-- +1.7.10 + + +From 9a26e5a08777c1d928bc3e9e9f8cdb2bb9258917 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 12 Dec 2012 18:34:47 +0100 +Subject: [PATCH 29/88] vdpau: drop studio level conversion + +--- + language/English/strings.po | 6 +- + xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 4 +- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 94 +----------------------- + xbmc/settings/GUISettings.cpp | 1 - + 4 files changed, 7 insertions(+), 98 deletions(-) + +diff --git a/language/English/strings.po b/language/English/strings.po +index 4094fd0..c3ba92f 100644 +--- a/language/English/strings.po ++++ b/language/English/strings.po +@@ -4369,11 +4369,7 @@ msgctxt "#13121" + msgid "VDPAU HQ Upscaling level" + msgstr "" + +-msgctxt "#13122" +-msgid "VDPAU Studio level color conversion" +-msgstr "" +- +-#empty strings from id 13123 to 13129 ++#empty strings from id 13122 to 13129 + + msgctxt "#13130" + msgid "Blank other displays" +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +index 4ee50c1..d2ba962 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +@@ -3344,7 +3344,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) + { + if(feature == RENDERFEATURE_BRIGHTNESS) + { +- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) ++ if (m_renderMethod & RENDER_VDPAU) + return true; + + if (m_renderMethod & RENDER_VAAPI) +@@ -3357,7 +3357,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) + + if(feature == RENDERFEATURE_CONTRAST) + { +- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) ++ if (m_renderMethod & RENDER_VDPAU) + return true; + + if (m_renderMethod & RENDER_VAAPI) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 0381c44..15c58b8 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -57,15 +57,6 @@ + }; + const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); + +-//static float studioCSC[3][4] = +-//{ +-// { 1.0f, 0.0f, 1.57480000f,-0.78740000f}, +-// { 1.0f,-0.18737736f,-0.46813736f, 0.32775736f}, +-// { 1.0f, 1.85556000f, 0.0f,-0.92780000f} +-//}; +-static float studioCSCKCoeffs601[3] = {0.299, 0.587, 0.114}; //BT601 {Kr, Kg, Kb} +-static float studioCSCKCoeffs709[3] = {0.2126, 0.7152, 0.0722}; //BT709 {Kr, Kg, Kb} +- + static struct SInterlaceMapping + { + const EINTERLACEMETHOD method; +@@ -1614,74 +1605,6 @@ void CMixer::PostProcOff() + DisableHQScaling(); + } + +- +-bool CMixer::GenerateStudioCSCMatrix(VdpColorStandard colorStandard, VdpCSCMatrix &studioCSCMatrix) +-{ +- // instead use studioCSCKCoeffs601[3], studioCSCKCoeffs709[3] to generate float[3][4] matrix (float studioCSC[3][4]) +- // m00 = mRY = red: luma factor (contrast factor) (1.0) +- // m10 = mGY = green: luma factor (contrast factor) (1.0) +- // m20 = mBY = blue: luma factor (contrast factor) (1.0) +- // +- // m01 = mRB = red: blue color diff coeff (0.0) +- // m11 = mGB = green: blue color diff coeff (-2Kb(1-Kb)/(Kg)) +- // m21 = mBB = blue: blue color diff coeff ((1-Kb)/0.5) +- // +- // m02 = mRR = red: red color diff coeff ((1-Kr)/0.5) +- // m12 = mGR = green: red color diff coeff (-2Kr(1-Kr)/(Kg)) +- // m22 = mBR = blue: red color diff coeff (0.0) +- // +- // m03 = mRC = red: colour zero offset (brightness factor) (-(1-Kr)/0.5 * (128/255)) +- // m13 = mGC = green: colour zero offset (brightness factor) ((256/255) * (Kb(1-Kb) + Kr(1-Kr)) / Kg) +- // m23 = mBC = blue: colour zero offset (brightness factor) (-(1-Kb)/0.5 * (128/255)) +- +- // columns +- int Y = 0; +- int Cb = 1; +- int Cr = 2; +- int C = 3; +- // rows +- int R = 0; +- int G = 1; +- int B = 2; +- // colour standard coefficients for red, geen, blue +- double Kr, Kg, Kb; +- // colour diff zero position (use standard 8-bit coding precision) +- double CDZ = 128; //256*0.5 +- // range excursion (use standard 8-bit coding precision) +- double EXC = 255; //256-1 +- +- if (colorStandard == VDP_COLOR_STANDARD_ITUR_BT_601) +- { +- Kr = studioCSCKCoeffs601[0]; +- Kg = studioCSCKCoeffs601[1]; +- Kb = studioCSCKCoeffs601[2]; +- } +- else // assume VDP_COLOR_STANDARD_ITUR_BT_709 +- { +- Kr = studioCSCKCoeffs709[0]; +- Kg = studioCSCKCoeffs709[1]; +- Kb = studioCSCKCoeffs709[2]; +- } +- // we keep luma unscaled to retain the levels present in source so that 16-235 luma is converted to RGB 16-235 +- studioCSCMatrix[R][Y] = 1.0; +- studioCSCMatrix[G][Y] = 1.0; +- studioCSCMatrix[B][Y] = 1.0; +- +- studioCSCMatrix[R][Cb] = 0.0; +- studioCSCMatrix[G][Cb] = (double)-2 * Kb * (1 - Kb) / Kg; +- studioCSCMatrix[B][Cb] = (double)(1 - Kb) / 0.5; +- +- studioCSCMatrix[R][Cr] = (double)(1 - Kr) / 0.5; +- studioCSCMatrix[G][Cr] = (double)-2 * Kr * (1 - Kr) / Kg; +- studioCSCMatrix[B][Cr] = 0.0; +- +- studioCSCMatrix[R][C] = (double)-1 * studioCSCMatrix[R][Cr] * CDZ/EXC; +- studioCSCMatrix[G][C] = (double)-1 * (studioCSCMatrix[G][Cb] + studioCSCMatrix[G][Cr]) * CDZ/EXC; +- studioCSCMatrix[B][C] = (double)-1 * studioCSCMatrix[B][Cb] * CDZ/EXC; +- +- return true; +-} +- + void CMixer::SetColor() + { + VdpStatus vdp_st; +@@ -1701,19 +1624,10 @@ void CMixer::SetColor() + //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); + + VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; +- if (g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) +- { +- float studioCSC[3][4]; +- GenerateStudioCSCMatrix(colorStandard, studioCSC); +- void const * pm_CSCMatix[] = { &studioCSC }; +- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); +- } +- else +- { +- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); +- void const * pm_CSCMatix[] = { &m_CSCMatrix }; +- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); +- } ++ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); ++ void const * pm_CSCMatix[] = { &m_CSCMatrix }; ++ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); ++ + CheckStatus(vdp_st, __LINE__); + } + +diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp +index 33467d9..4cec1b3 100644 +--- a/xbmc/settings/GUISettings.cpp ++++ b/xbmc/settings/GUISettings.cpp +@@ -764,7 +764,6 @@ void CGUISettings::Initialize() + AddSeparator(vp, "videoplayer.sep1.5"); + #ifdef HAVE_LIBVDPAU + AddBool(NULL, "videoplayer.vdpauUpscalingLevel", 13121, false); +- AddBool(vp, "videoplayer.vdpaustudiolevel", 13122, false); + #endif + #endif + AddSeparator(vp, "videoplayer.sep5"); +-- +1.7.10 + + +From cf77997579bf3f5a46e17b6c1f9753f68ad49ce5 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 12 Dec 2012 20:28:49 +0100 +Subject: [PATCH 30/88] vdpau: observe ffmpeg tags for color space + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 38 ++++++++++++++++-------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 1 + + 2 files changed, 27 insertions(+), 12 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 15c58b8..34cc320 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -907,6 +907,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); + ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); + pic.render = render; ++ pic.DVDPic.color_matrix = avctx->colorspace; + m_bufferStats.IncDecoded(); + m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); + +@@ -1513,10 +1514,6 @@ void CMixer::InitCSCMatrix(int Width) + m_Procamp.contrast = 1.0; + m_Procamp.saturation = 1.0; + m_Procamp.hue = 0; +- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, +- (Width < 1000)? VDP_COLOR_STANDARD_ITUR_BT_601 : VDP_COLOR_STANDARD_ITUR_BT_709, +- &m_CSCMatrix); +- CheckStatus(vdp_st, __LINE__); + } + + void CMixer::CheckFeatures() +@@ -1527,11 +1524,13 @@ void CMixer::CheckFeatures() + m_Upscale = m_config.upscale; + } + if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness || +- m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) ++ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast || ++ m_ColorMatrix != m_mixerInput[1].DVDPic.color_matrix) + { + SetColor(); + m_Brightness = g_settings.m_currentVideoSettings.m_Brightness; + m_Contrast = g_settings.m_currentVideoSettings.m_Contrast; ++ m_ColorMatrix = m_mixerInput[1].DVDPic.color_matrix; + } + if (m_NoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) + { +@@ -1615,13 +1614,27 @@ void CMixer::SetColor() + m_Procamp.contrast = (float)((g_settings.m_currentVideoSettings.m_Contrast)+50) / 100; + + VdpColorStandard colorStandard; +-// if(vid_height >= 600 || vid_width > 1024) +- if(m_config.surfaceWidth > 1000) +- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; +- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); +- else +- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; +- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); ++ switch(m_mixerInput[1].DVDPic.color_matrix) ++ { ++ case AVCOL_SPC_BT709: ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; ++ break; ++ case AVCOL_SPC_BT470BG: ++ case AVCOL_SPC_SMPTE170M: ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; ++ break; ++ case AVCOL_SPC_SMPTE240M: ++ colorStandard = VDP_COLOR_STANDARD_SMPTE_240M; ++ break; ++ case AVCOL_SPC_FCC: ++ case AVCOL_SPC_UNSPECIFIED: ++ case AVCOL_SPC_RGB: ++ default: ++ if(m_config.surfaceWidth > 1000) ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; ++ else ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; ++ } + + VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; + vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); +@@ -1952,6 +1965,7 @@ void CMixer::Init() + m_Sharpness = 0.0; + m_DeintMode = 0; + m_Deint = 0; ++ m_ColorMatrix = 0; + m_PostProc = false; + m_vdpError = false; + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index 4d1559c..471ad68 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -334,6 +334,7 @@ class CMixer : private CThread + int m_DeintMode; + int m_Deint; + int m_Upscale; ++ unsigned int m_ColorMatrix : 4; + uint32_t *m_BlackBar; + VdpVideoMixerPictureStructure m_mixerfield; + int m_mixerstep; +-- +1.7.10 + + +From 4eef23adc7b4539fc8e1b87c7f2f6797b32b82ea Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 27 Jan 2013 12:10:19 +0100 +Subject: [PATCH 31/88] vdpau: switch off de-interlacing on ff + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 34cc320..5de75ab 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -2043,8 +2043,9 @@ void CMixer::InitCycle() + EINTERLACEMETHOD method = GetDeinterlacingMethod(); + bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; + +- if (mode == VS_DEINTERLACEMODE_FORCE || +- (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) ++ if (!(flags & DVP_FLAG_NO_POSTPROC) && ++ (mode == VS_DEINTERLACEMODE_FORCE || ++ (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) + { + if((method == VS_INTERLACEMETHOD_AUTO && interlaced) + || method == VS_INTERLACEMETHOD_VDPAU_BOB +-- +1.7.10 + + +From 96ef99611c9cd1740faf8dd02b09e4cbb5e9cdc0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 2 Feb 2013 13:17:09 +0100 +Subject: [PATCH 32/88] vdpau: fix mp4 part2 decoding, activate by default + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++------ + xbmc/settings/AdvancedSettings.cpp | 2 +- + 2 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 5de75ab..68cf36a 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -127,10 +127,9 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int + VdpDecoderProfile profile = 0; + if(avctx->codec_id == CODEC_ID_H264) + profile = VDP_DECODER_PROFILE_H264_HIGH; +-#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP + else if(avctx->codec_id == CODEC_ID_MPEG4) + profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; +-#endif ++ + if(profile) + { + if (!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width)) +@@ -530,13 +529,10 @@ void CDecoder::ReadFormatOf( PixelFormat fmt + vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; + vdp_chroma_type = VDP_CHROMA_TYPE_420; + break; +-#if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) && \ +- (defined VDP_DECODER_PROFILE_MP) + case PIX_FMT_VDPAU_MPEG4: +- vdp_decoder_profile = VDP_DECOPEG4_PART2_ASP; ++ vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; + vdp_chroma_type = VDP_CHROMA_TYPE_420; + break; +-#endif + default: + vdp_decoder_profile = 0; + vdp_chroma_type = 0; +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index 844f8e8..04a7c7c 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -102,7 +102,7 @@ void CAdvancedSettings::Initialize() + m_videoNonLinStretchRatio = 0.5f; + m_videoEnableHighQualityHwScalers = false; + m_videoAutoScaleMaxFps = 30.0f; +- m_videoAllowMpeg4VDPAU = false; ++ m_videoAllowMpeg4VDPAU = true; + m_videoAllowMpeg4VAAPI = false; + m_videoDisableBackgroundDeinterlace = false; + m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect +-- +1.7.10 + + +From 477502af4a70f4251652c955e6e048025bb32514 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 25 Sep 2012 12:14:15 +0200 -Subject: [PATCH 12/73] linuxrenderer: drop method RenderMultiPass +Subject: [PATCH 33/88] linuxrenderer: drop method RenderMultiPass --- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 9 ++------- @@ -8207,7 +10439,7 @@ Subject: [PATCH 12/73] linuxrenderer: drop method RenderMultiPass 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 4ee50c1..ea58c85 100644 +index d2ba962..62198f0 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -1205,7 +1205,8 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) @@ -8234,10 +10466,10 @@ index 4ee50c1..ea58c85 100644 { YUVPLANES &planes = m_buffers[index].fields[field]; diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 3218cd5..afc78c2 100644 +index 329ddee..08f8234 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -218,7 +218,6 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -216,7 +216,6 @@ class CLinuxRendererGL : public CBaseRenderer void CalculateTextureSourceRects(int source, int num_planes); // renderers @@ -8249,10 +10481,10 @@ index 3218cd5..afc78c2 100644 1.7.10 -From 267f61079ae6a4f77fb5c068eecb0d1aeddd0337 Mon Sep 17 00:00:00 2001 +From 48fb2351e755727506993d6fd0334c368fffbee6 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 25 Sep 2012 13:20:47 +0200 -Subject: [PATCH 13/73] linuxrenderer: implement progressive weave for vdpau +Subject: [PATCH 34/88] linuxrenderer: implement progressive weave for vdpau --- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 55 ++++++++++++++++++------- @@ -8260,7 +10492,7 @@ Subject: [PATCH 13/73] linuxrenderer: implement progressive weave for vdpau 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index ea58c85..b281ca7 100644 +index 62198f0..6e6d97e 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -689,18 +689,6 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) @@ -8358,10 +10590,10 @@ index ea58c85..b281ca7 100644 { #ifdef HAVE_LIBVDPAU diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index afc78c2..2fc34ae 100644 +index 08f8234..13217ce 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -218,12 +218,12 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -216,12 +216,12 @@ class CLinuxRendererGL : public CBaseRenderer void CalculateTextureSourceRects(int source, int num_planes); // renderers @@ -8380,10 +10612,10 @@ index afc78c2..2fc34ae 100644 1.7.10 -From 4c76478000f03a2460c407a66a779b2232c186c5 Mon Sep 17 00:00:00 2001 +From 46d819fbe6386640cee6bf94b3c6df8b78addaa5 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 14/73] X11: ditch SDL for video and window events +Subject: [PATCH 35/88] X11: ditch SDL for video and window events --- xbmc/Application.cpp | 2 +- @@ -8399,7 +10631,7 @@ Subject: [PATCH 14/73] X11: ditch SDL for video and window events create mode 100644 xbmc/windowing/WinEventsX11.h diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index b623250..3a1d6a1 100644 +index 5c7017c..8259eba 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -794,7 +794,7 @@ bool CApplication::CreateGUI() @@ -9867,10 +12099,10 @@ index 2dd8a9f..9616d17 100644 1.7.10 -From 9fc77631a47445e67b587d3c2d967c8415ef1601 Mon Sep 17 00:00:00 2001 +From 5a5787c6f51a9d92f69e95dea42175f3837777cb Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 15/73] X11: Add xbmc icon +Subject: [PATCH 36/88] X11: Add xbmc icon --- xbmc/windowing/X11/WinSystemX11.cpp | 126 ++++++++++++++++++++++++++++++++++- @@ -10059,10 +12291,10 @@ index 9616d17..debf714 100644 1.7.10 -From 86a25b3b4355259720f5f54f6fe5650710873911 Mon Sep 17 00:00:00 2001 +From e6ae1b597d479cb9d9ae2dfc8cf43cceac4a82f7 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 16/73] X11: add SDL joystick until we have a better solution +Subject: [PATCH 37/88] X11: add SDL joystick until we have a better solution --- xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++ @@ -10116,10 +12348,10 @@ index 24477ae..2ec86a8 100644 1.7.10 -From 992db82a2cc2d9e8af6388f67e8a2890c7742726 Mon Sep 17 00:00:00 2001 +From 22a59cd9df66e37394ac61b3d03d3ab6ac2f824f Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 17/73] X11: factor out code handling device reset +Subject: [PATCH 38/88] X11: factor out code handling device reset notification --- @@ -10183,10 +12415,10 @@ index debf714..8c28e3f 100644 1.7.10 -From d6f428a5369ef66336e3f7f07e2dedfc0d1d8f7f Mon Sep 17 00:00:00 2001 +From 6c8f71e86c88314ee94673ad58407a8122995049 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 18/73] X11: move xrandr events to WinEventsX11 +Subject: [PATCH 39/88] X11: move xrandr events to WinEventsX11 --- xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++ @@ -10330,10 +12562,10 @@ index 70557d0..1cce843 100644 1.7.10 -From daf0f02f96f6a640c06b50a0823e1f1858027c85 Mon Sep 17 00:00:00 2001 +From 9d24be16a3f9cc78ca26645ac2c7808e6e6b1e3e Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 19/73] xrandr: remove method RestoreState +Subject: [PATCH 40/88] xrandr: remove method RestoreState --- xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++-- @@ -10412,10 +12644,10 @@ index 2a269d0..5b64633 100644 1.7.10 -From e8b72dbf152bb1a2ff380d604e0fd9bbd7451994 Mon Sep 17 00:00:00 2001 +From b74182e365180b8f6bb413ad49ef17846cb6cf66 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 20/73] xrandr: observe orientation +Subject: [PATCH 41/88] xrandr: observe orientation --- xbmc/windowing/X11/WinSystemX11.cpp | 61 +++++++++++++++++++++++++++++++++-- @@ -10584,10 +12816,10 @@ index 5b64633..618bd68 100644 1.7.10 -From a89e12b3ac29d108c32a554e93cb94f1cb2afc75 Mon Sep 17 00:00:00 2001 +From 80ebbe1851f21ed959f6b30eac6374d3bbe9258e Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 21/73] xrandr: allow getting info for multiple screen's +Subject: [PATCH 42/88] xrandr: allow getting info for multiple screen's Refactored by: Joakim Plate --- @@ -10762,10 +12994,10 @@ index 618bd68..0824af5 100644 1.7.10 -From 748512b3692f1f4cec63082dd9dc4d996277d44a Mon Sep 17 00:00:00 2001 +From ec0fa66fe2322cf5cd47ec0b6b832f47e1ab7e1f Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 22/73] X11: fix multi-head setups +Subject: [PATCH 43/88] X11: fix multi-head setups --- language/English/strings.po | 4 +- @@ -10779,7 +13011,7 @@ Subject: [PATCH 22/73] X11: fix multi-head setups 8 files changed, 235 insertions(+), 115 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 88292d3..bba7284 100644 +index c3ba92f..f2abd3f 100644 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -895,7 +895,9 @@ msgctxt "#245" @@ -10806,7 +13038,7 @@ index efe5493..85d780d 100644 virtual void SetViewPort(CRect& viewPort); virtual void GetViewPort(CRect& viewPort); diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 4cdb093..0e320e1 100644 +index 4cec1b3..30b402d 100644 --- a/xbmc/settings/GUISettings.cpp +++ b/xbmc/settings/GUISettings.cpp @@ -392,11 +392,16 @@ void CGUISettings::Initialize() @@ -10827,7 +13059,7 @@ index 4cdb093..0e320e1 100644 // contains an index to the g_settings.m_ResInfo array. the only meaningful fields are iScreen, iWidth, iHeight. #if defined(TARGET_DARWIN) diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index d988598..3c19a06 100644 +index 2af9315..b9f18e4 100644 --- a/xbmc/settings/GUIWindowSettingsCategory.cpp +++ b/xbmc/settings/GUIWindowSettingsCategory.cpp @@ -528,6 +528,12 @@ void CGUIWindowSettingsCategory::CreateSettings() @@ -10843,7 +13075,7 @@ index d988598..3c19a06 100644 else if (strSetting.Equals("lookandfeel.skintheme")) { AddSetting(pSetting, group->GetWidth(), iControlID); -@@ -1494,6 +1500,20 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting +@@ -1477,6 +1483,20 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting // Cascade FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); } @@ -10864,7 +13096,7 @@ index d988598..3c19a06 100644 else if (strSetting.Equals("videoscreen.resolution")) { RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution"); -@@ -2430,11 +2450,15 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES +@@ -2413,11 +2433,15 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES if (g_advancedSettings.m_canWindowed) pControl->AddLabel(g_localizeStrings.Get(242), -1); @@ -10880,7 +13112,7 @@ index d988598..3c19a06 100644 pControl->SetValue(mode); g_guiSettings.SetInt("videoscreen.screen", mode); } -@@ -2442,6 +2466,36 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES +@@ -2425,6 +2449,36 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES return mode; } @@ -10917,7 +13149,7 @@ index d988598..3c19a06 100644 void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, DisplayMode mode, RESOLUTION res, bool UserChange) { BaseSettingControlPtr control = GetSetting(strSetting); -@@ -2570,13 +2624,15 @@ void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes) +@@ -2553,13 +2607,15 @@ void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes) RESOLUTION lastRes = g_graphicsContext.GetVideoResolution(); bool cancelled = false; @@ -11497,10 +13729,10 @@ index 93cf5db..71034fc 100644 1.7.10 -From fcc6a223fdca36b95327dab99758255e7be0e69e Mon Sep 17 00:00:00 2001 +From 89a7d265a0e2673b8076bde718690cbb02e59670 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 23/73] X11: remove all DefaultScreen and RootWindow macros +Subject: [PATCH 44/88] X11: remove all DefaultScreen and RootWindow macros --- xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- @@ -11568,10 +13800,10 @@ index f858f88..d192697 100644 1.7.10 -From 019079003538369000d57b26a534a68f61ad6256 Mon Sep 17 00:00:00 2001 +From ac87010f83e230caf6ed03e36c562a4fb0abb2ab Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 24/73] X11: remove all DefaultScreen and RootWindow macros +Subject: [PATCH 45/88] X11: remove all DefaultScreen and RootWindow macros (VideoRefClock) Note this is on a separate display connection. @@ -11643,10 +13875,10 @@ index 9785fe7..0004e07 100644 1.7.10 -From 770cdec440e330d23629cc70153a5a05c3ddf9b7 Mon Sep 17 00:00:00 2001 +From 5510c47704fc1156897abc1932151460e4c07569 Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 25/73] X11: recreate gl context after output has changed +Subject: [PATCH 46/88] X11: recreate gl context after output has changed --- xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++---------- @@ -11797,10 +14029,10 @@ index d192697..0f2d1d2 100644 1.7.10 -From 097d10727fc8e75a3976850782d3e8da74482140 Mon Sep 17 00:00:00 2001 +From 72196d5e8e45d884bf9ac03d7050d29ced2b3aeb Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 26/73] X11: hook video reference clock in windowing +Subject: [PATCH 47/88] X11: hook video reference clock in windowing --- xbmc/video/VideoReferenceClock.cpp | 71 ++++++++++++++++++++++++++---------- @@ -12005,10 +14237,10 @@ index dcc4f09..7eb6317 100644 1.7.10 -From 88e10ce5f4b4172129dd258b91ee4d7b6a6ecaec Mon Sep 17 00:00:00 2001 +From ee2f6f0a246b6b684192ee30cb2cd0e5ac1300cf Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 27/73] X11: fix video calibrations +Subject: [PATCH 48/88] X11: fix video calibrations --- xbmc/settings/Settings.cpp | 1 + @@ -12113,10 +14345,10 @@ index cc28f56..c046c86 100644 1.7.10 -From 96ccf3d52796fdba75d37a18e9b514814657f332 Mon Sep 17 00:00:00 2001 +From e4f883d19e247bde088178c96ab3dbb21b7be61d Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 28/73] X11: deactivate screen saver on startup +Subject: [PATCH 49/88] X11: deactivate screen saver on startup --- xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++ @@ -12186,10 +14418,10 @@ index c046c86..e953d2d 100644 1.7.10 -From 305cd979dbf8226fa8826f410172f3df8caa4811 Mon Sep 17 00:00:00 2001 +From 9143044b7d7469751143fda07a5d960403bac8f9 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 29/73] X11: change method of going full-screen +Subject: [PATCH 50/88] X11: change method of going full-screen --- xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- @@ -12233,10 +14465,10 @@ index b3e7ab5..91f92c1 100644 1.7.10 -From ded35a8abe03367f8b316106e2062c1d0a44fc02 Mon Sep 17 00:00:00 2001 +From e9c03d83ef43d874283b9dab8de57601fa610419 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 30/73] X11: reset key repeat and key modifier on focus lost +Subject: [PATCH 51/88] X11: reset key repeat and key modifier on focus lost and gain --- @@ -12268,10 +14500,10 @@ index 6c22358..d86205d 100644 1.7.10 -From ef601448e65346a8c7746cb1c470269a66f9afa0 Mon Sep 17 00:00:00 2001 +From b0fca2b5347e07513a16932875d5384d32eaae57 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 31/73] X11: replace custom utf8 to unicode with charset +Subject: [PATCH 52/88] X11: replace custom utf8 to unicode with charset convertor (squash to x11 events) --- @@ -12488,10 +14720,10 @@ index 6100933..72955ad 100644 1.7.10 -From 3d9931214dc45ed6442e39f2576175d90879e413 Mon Sep 17 00:00:00 2001 +From c93af676cf85551e3f4325808d17098da3bc6811 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 32/73] X11: fixed invalid usage of sizeof() (squash into x11 +Subject: [PATCH 53/88] X11: fixed invalid usage of sizeof() (squash into x11 changes) --- @@ -12555,10 +14787,10 @@ index 72955ad..102a076 100644 1.7.10 -From 8b292cf47d12a0e8e1c980e9187074f5da30582e Mon Sep 17 00:00:00 2001 +From 04106be4cdf381658ae92bf20bc468ccad12fb31 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 33/73] add missing keys to xbmc keytable +Subject: [PATCH 54/88] add missing keys to xbmc keytable --- xbmc/input/XBMC_keytable.cpp | 2 ++ @@ -12581,10 +14813,10 @@ index aaf65ba..9d7922f 100644 1.7.10 -From 285cb8393ff2c80aef5b0f8fd6f32cb24160fa66 Mon Sep 17 00:00:00 2001 +From fb35e45063cf476573ad09c3bed7459164d03066 Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 34/73] videorefclock: temp deactivate of nv settings +Subject: [PATCH 55/88] videorefclock: temp deactivate of nv settings --- xbmc/video/VideoReferenceClock.cpp | 2 +- @@ -12607,10 +14839,10 @@ index fa8e35a..85e36c7 100644 1.7.10 -From f9326bbe9799df7e48baedd4c29a5084cc7f291d Mon Sep 17 00:00:00 2001 +From 5e10bc67e7b0dffbbf9b7d8242fb78e8cef2403f Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 35/73] videorefclock: ask graphics context for refresh rate +Subject: [PATCH 56/88] videorefclock: ask graphics context for refresh rate --- xbmc/video/VideoReferenceClock.cpp | 3 ++- @@ -12641,10 +14873,10 @@ index 85e36c7..8209163 100644 1.7.10 -From 335cfdabc94f26144a021484bef565280fdb468c Mon Sep 17 00:00:00 2001 +From aed9e87986eb99f21a7cafc6a356a4044b41becc Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 36/73] X11: fix icon texture after +Subject: [PATCH 57/88] X11: fix icon texture after cc5ed3c2474084ebc0373a3046410e6f766e03f4 --- @@ -12752,10 +14984,10 @@ index 91f92c1..174ccef 100644 1.7.10 -From b88e65666f467ccd3ab90a2cdc9cf90f32676667 Mon Sep 17 00:00:00 2001 +From 7c4464b9114e5eba42c1cc1fce0cfe750ec44eba Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 37/73] X11: check for window manager +Subject: [PATCH 58/88] X11: check for window manager --- xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++- @@ -12876,10 +15108,10 @@ index e953d2d..0b7c10a 100644 1.7.10 -From d69db585a0877699a1b21701a024c5a02cea9084 Mon Sep 17 00:00:00 2001 +From d156746c8968312db2a60fbcbcbb48029ff0d60a Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 38/73] X11: dont set window on xrandr if no mode available +Subject: [PATCH 59/88] X11: dont set window on xrandr if no mode available --- xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++----- @@ -12916,10 +15148,10 @@ index 4f1ae26..c11ea89 100644 1.7.10 -From 9144abbbea8aeaae193fe5d35029d8796874093d Mon Sep 17 00:00:00 2001 +From 7da277793b15d9cbd5dcaf27dc7fee2fb3dde945 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 39/73] X11: fix crash after a resolution change on startup +Subject: [PATCH 60/88] X11: fix crash after a resolution change on startup --- xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- @@ -12943,10 +15175,10 @@ index c11ea89..0bd72d4 100644 1.7.10 -From f7b05be0696cbda0d145deb7155d409fe7f25932 Mon Sep 17 00:00:00 2001 +From 31d401e7052f2e3d03e4c78bccc05909d870e5a6 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 40/73] X11: lock graphics context in NotifyXRREvent +Subject: [PATCH 61/88] X11: lock graphics context in NotifyXRREvent --- xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ @@ -12969,10 +15201,10 @@ index 0bd72d4..ef83133 100644 1.7.10 -From bc501e4a04225ce1ac7eadb90fc926ba156e46f5 Mon Sep 17 00:00:00 2001 +From b2cd5ea5e38446dc54b73cf2f6a82072add474f1 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 8 Oct 2011 16:45:13 +0200 -Subject: [PATCH 41/73] ffmpeg: add xvba hwaccel +Subject: [PATCH 62/88] ffmpeg: add xvba hwaccel --- lib/ffmpeg/configure | 8 ++ @@ -12980,16 +15212,16 @@ Subject: [PATCH 41/73] ffmpeg: add xvba hwaccel lib/ffmpeg/libavcodec/allcodecs.c | 4 + lib/ffmpeg/libavcodec/h264.c | 1 + lib/ffmpeg/libavcodec/mpegvideo.c | 1 + - lib/ffmpeg/libavcodec/xvba.c | 66 ++++++++++++ + lib/ffmpeg/libavcodec/xvba.c | 66 +++++++++++ lib/ffmpeg/libavcodec/xvba.h | 71 ++++++++++++ - lib/ffmpeg/libavcodec/xvba_h264.c | 189 ++++++++++++++++++++++++++++++++ - lib/ffmpeg/libavcodec/xvba_internal.h | 24 +++++ + lib/ffmpeg/libavcodec/xvba_h264.c | 195 +++++++++++++++++++++++++++++++++ + lib/ffmpeg/libavcodec/xvba_internal.h | 24 ++++ lib/ffmpeg/libavcodec/xvba_mpeg2.c | 52 +++++++++ - lib/ffmpeg/libavcodec/xvba_vc1.c | 190 +++++++++++++++++++++++++++++++++ + lib/ffmpeg/libavcodec/xvba_vc1.c | 190 ++++++++++++++++++++++++++++++++ lib/ffmpeg/libavcodec/xvmc_internal.h | 4 +- - lib/ffmpeg/libavutil/pixdesc.c | 6 ++ + lib/ffmpeg/libavutil/pixdesc.c | 6 + lib/ffmpeg/libavutil/pixfmt.h | 1 + - 14 files changed, 622 insertions(+), 2 deletions(-) + 14 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 lib/ffmpeg/libavcodec/xvba.c create mode 100644 lib/ffmpeg/libavcodec/xvba.h create mode 100644 lib/ffmpeg/libavcodec/xvba_h264.c @@ -13316,10 +15548,10 @@ index 0000000..9f9ff0c +#endif /* AVCODEC_XVBA_H */ diff --git a/lib/ffmpeg/libavcodec/xvba_h264.c b/lib/ffmpeg/libavcodec/xvba_h264.c new file mode 100644 -index 0000000..a077442 +index 0000000..87af687 --- /dev/null +++ b/lib/ffmpeg/libavcodec/xvba_h264.c -@@ -0,0 +1,189 @@ +@@ -0,0 +1,195 @@ +/* + * H.264 HW decode acceleration through XVBA + * @@ -13424,10 +15656,16 @@ index 0000000..a077442 + pic_descriptor->avc_num_ref_frames = h->sps.ref_frame_count; + pic_descriptor->avc_reserved_8bit = 0; + -+ /* Set correct level */ -+ if (pic_descriptor->level == 41) { ++ /* Set a level that can decode stuff in every case without a lookup table ++ xvba seems to have problems only when the number of Reframes goes beyond ++ the max support number of Level4.1@High. So in praxis decoding a Level 3.0 ++ file that in deed has level4.1@High specs does not matter. We use this fact ++ and check if the ref_frames stay in the range Level4.1@high can decode if ++ not, we set Level5.1 */ ++ if (pic_descriptor->avc_num_ref_frames > 4) { + const unsigned int mbw = pic_descriptor->width_in_mb; + const unsigned int mbh = pic_descriptor->height_in_mb; ++ // this matches Level4.1@High stats to differ between <= 4.1 and 5.1 + const unsigned int max_ref_frames = 12288 * 1024 / (mbw * mbh * 384); + const unsigned int num_ref_frames = pic_descriptor->avc_num_ref_frames; + if (max_ref_frames < num_ref_frames) @@ -13839,33 +16077,33 @@ index f0d9c01..0f8cf7b 100644 1.7.10 -From 1502daa2e3432e56b5c7a156754fda9d1a804f91 Mon Sep 17 00:00:00 2001 +From bb93e835939fce784f8ad4b2364f174df4ee3978 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 12 Apr 2012 12:09:31 +0200 -Subject: [PATCH 42/73] xvba: add decoder +Subject: [PATCH 63/88] xvba: add decoder --- configure.in | 48 + language/English/strings.po | 12 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 218 +- + xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 216 +- xbmc/cores/VideoRenderers/LinuxRendererGL.h | 15 +- xbmc/cores/VideoRenderers/RenderFormats.h | 1 + - xbmc/cores/VideoRenderers/RenderManager.cpp | 9 +- + xbmc/cores/VideoRenderers/RenderManager.cpp | 4 + .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 16 + xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in | 4 + - xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 2354 ++++++++++++++++++++ + xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 2367 ++++++++++++++++++++ xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h | 382 ++++ - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 3 + + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 + xbmc/settings/GUISettings.cpp | 3 + xbmc/settings/VideoSettings.h | 2 + xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 1 + - 15 files changed, 3064 insertions(+), 8 deletions(-) + 15 files changed, 3073 insertions(+), 6 deletions(-) create mode 100644 xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp create mode 100644 xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h diff --git a/configure.in b/configure.in -index 350d960..3660fa4 100644 +index 4769315..23439fd 100644 --- a/configure.in +++ b/configure.in @@ -124,6 +124,8 @@ vaapi_not_found="== Could not find libva. VAAPI support disabled. ==" @@ -13890,7 +16128,7 @@ index 350d960..3660fa4 100644 AC_ARG_ENABLE([vdadecoder], [AS_HELP_STRING([--enable-vdadecoder], -@@ -1759,6 +1767,38 @@ else +@@ -1751,6 +1759,38 @@ else USE_CRYSTALHD=0 fi @@ -13929,7 +16167,7 @@ index 350d960..3660fa4 100644 # VDADecoder if test "x$use_vdadecoder" != "xno"; then if test "$host_vendor" = "apple" ; then -@@ -1970,6 +2010,12 @@ else +@@ -1962,6 +2002,12 @@ else final_message="$final_message\n CrystalHD:\tNo" fi @@ -13942,7 +16180,7 @@ index 350d960..3660fa4 100644 if test "x$use_vdadecoder" != "xno"; then final_message="$final_message\n VDADecoder:\tYes" else -@@ -2443,6 +2489,7 @@ AC_SUBST(USE_OPENGLES) +@@ -2435,6 +2481,7 @@ AC_SUBST(USE_OPENGLES) AC_SUBST(USE_VDPAU) AC_SUBST(USE_VAAPI) AC_SUBST(USE_CRYSTALHD) @@ -13950,7 +16188,7 @@ index 350d960..3660fa4 100644 AC_SUBST(USE_LIBSMBCLIENT) AC_SUBST(USE_LIBNFS) AC_SUBST(USE_LIBAFPCLIENT) -@@ -2626,6 +2673,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [ +@@ -2618,6 +2665,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [ `if test "x$use_vdpau" != "xno"; then echo --enable-vdpau; else echo --disable-vdpau; fi` \ `if test "x$use_vaapi" != "xno"; then echo --enable-vaapi; else echo --disable-vaapi; fi` \ `if test "$use_optimizations" != "no"; then echo --enable-optimizations; else echo --disable-optimizations; fi` \ @@ -13959,11 +16197,11 @@ index 350d960..3660fa4 100644 --enable-pthreads \ --enable-runtime-cpudetect \ diff --git a/language/English/strings.po b/language/English/strings.po -index bba7284..ede18b3 100644 +index f2abd3f..fc896b3 100644 --- a/language/English/strings.po +++ b/language/English/strings.po -@@ -5124,7 +5124,11 @@ msgctxt "#13436" - msgid "Allow Vdpau OpenGL interop YUV" +@@ -5120,7 +5120,11 @@ msgctxt "#13436" + msgid "Prefer VDPAU Video Mixer" msgstr "" -#empty strings from id 13437 to 13499 @@ -13975,7 +16213,7 @@ index bba7284..ede18b3 100644 msgctxt "#13500" msgid "A/V sync method" -@@ -6346,7 +6350,11 @@ msgctxt "#16325" +@@ -6342,7 +6346,11 @@ msgctxt "#16325" msgid "VDPAU - Bob" msgstr "" @@ -13989,7 +16227,7 @@ index bba7284..ede18b3 100644 msgctxt "#16400" msgid "Post-processing" diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index b281ca7..ec3606a 100644 +index 6e6d97e..0bb924b 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -63,6 +63,9 @@ @@ -14148,7 +16386,7 @@ index b281ca7..ec3606a 100644 void CLinuxRendererGL::RenderSoftware(int index, int field) { // used for textues uploaded from rgba or CVPixelBuffers. -@@ -2783,6 +2881,93 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) +@@ -2783,6 +2881,91 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) return true; } @@ -14195,16 +16433,14 @@ index b281ca7..ec3606a 100644 + YUVFIELDS &fields = m_buffers[index].fields; + YUVPLANE &plane = fields[0][1]; + -+ if (!xvba) ++ if (!xvba || !xvba->valid) + { -+ fields[0][1].id = fields[0][0].id; + m_eventTexturesDone[index]->Set(); -+ CLog::Log(LOGWARNING,"CLinuxRendererGL::UploadXVBATexture no xvba texture, index: %d", index); ++ m_skipRender = true; + return; + } -+// xvba->Transfer(); + -+ fields[0][1].id = xvba->texture; ++ plane.id = xvba->texture; + + im.height = xvba->texHeight; + im.width = xvba->texWidth; @@ -14242,7 +16478,7 @@ index b281ca7..ec3606a 100644 void CLinuxRendererGL::UploadYUV422PackedTexture(int source) { YUVBUFFER& buf = m_buffers[source]; -@@ -3368,6 +3553,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3368,6 +3551,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (m_renderMethod & RENDER_VAAPI) return false; @@ -14252,7 +16488,7 @@ index b281ca7..ec3606a 100644 return (m_renderMethod & RENDER_GLSL) || (m_renderMethod & RENDER_ARB) || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3381,6 +3569,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3381,6 +3567,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (m_renderMethod & RENDER_VAAPI) return false; @@ -14262,7 +16498,7 @@ index b281ca7..ec3606a 100644 return (m_renderMethod & RENDER_GLSL) || (m_renderMethod & RENDER_ARB) || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3404,7 +3595,8 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3404,7 +3593,8 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (feature == RENDERFEATURE_NONLINSTRETCH) { if (((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT)) || @@ -14272,7 +16508,7 @@ index b281ca7..ec3606a 100644 return true; } -@@ -3476,6 +3668,16 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) +@@ -3476,6 +3666,16 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) return false; } @@ -14289,7 +16525,7 @@ index b281ca7..ec3606a 100644 #ifdef TARGET_DARWIN // YADIF too slow for HD but we have no methods to fall back // to something that works so just turn it off. -@@ -3518,7 +3720,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) +@@ -3518,7 +3718,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) || method == VS_SCALINGMETHOD_LANCZOS3) { if ((glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL)) || @@ -14298,7 +16534,7 @@ index b281ca7..ec3606a 100644 { // spline36 and lanczos3 are only allowed through advancedsettings.xml if(method != VS_SCALINGMETHOD_SPLINE36 -@@ -3610,4 +3812,14 @@ void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) +@@ -3610,4 +3810,14 @@ void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) } #endif @@ -14314,7 +16550,7 @@ index b281ca7..ec3606a 100644 + #endif diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 2fc34ae..e76624b 100644 +index 13217ce..a189892 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h @@ -43,6 +43,8 @@ @@ -14324,9 +16560,9 @@ index 2fc34ae..e76624b 100644 +namespace XVBA { class CXvbaRenderPicture; } + - #define NUM_BUFFERS 10 - -@@ -90,6 +92,7 @@ enum RenderMethod + #undef ALIGN + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) +@@ -88,6 +90,7 @@ enum RenderMethod RENDER_POT=0x10, RENDER_VAAPI=0x20, RENDER_CVREF = 0x40, @@ -14334,7 +16570,7 @@ index 2fc34ae..e76624b 100644 }; enum RenderQuality -@@ -151,7 +154,9 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -149,7 +152,9 @@ class CLinuxRendererGL : public CBaseRenderer #ifdef TARGET_DARWIN virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); #endif @@ -14345,7 +16581,7 @@ index 2fc34ae..e76624b 100644 virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); // Feature support -@@ -210,6 +215,10 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -208,6 +213,10 @@ class CLinuxRendererGL : public CBaseRenderer void DeleteYUV422PackedTexture(int index); bool CreateYUV422PackedTexture(int index); @@ -14356,7 +16592,7 @@ index 2fc34ae..e76624b 100644 void UploadRGBTexture(int index); void ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsigned flipIndexBuf); void ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, unsigned flipIndexPlaneBot, unsigned flipIndexBuf); -@@ -225,6 +234,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -223,6 +232,7 @@ class CLinuxRendererGL : public CBaseRenderer void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware @@ -14364,7 +16600,7 @@ index 2fc34ae..e76624b 100644 struct { -@@ -292,6 +302,9 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -290,6 +300,9 @@ class CLinuxRendererGL : public CBaseRenderer #ifdef TARGET_DARWIN_OSX struct __CVBuffer *cvBufferRef; #endif @@ -14387,22 +16623,10 @@ index 0262c60..a727d94 100644 #endif diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index a521680..0506823 100644 +index b89ec67..c99a555 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -250,8 +250,9 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - - // check if decoder supports buffering - m_bCodecSupportsBuffering = false; -- if (format == RENDER_FMT_VDPAU || -- format == RENDER_FMT_VDPAU_420) -+ if (format == RENDER_FMT_VDPAU -+ || format == RENDER_FMT_VDPAU_420 -+ || format == RENDER_FMT_XVBA) - m_bCodecSupportsBuffering = true; - - bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation); -@@ -873,6 +874,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) +@@ -876,6 +876,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) else if(pic.format == RENDER_FMT_VAAPI) m_pRenderer->AddProcessor(*pic.vaapi, index); #endif @@ -14412,9 +16636,9 @@ index a521680..0506823 100644 +#endif m_pRenderer->ReleaseImage(index, false); - return index; + m_bRenderBufferUsed = true; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 98d8f89..76d3575 100644 +index 64c5f5f..5fa52c3 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h @@ -35,6 +35,7 @@ @@ -14436,7 +16660,7 @@ index 98d8f89..76d3575 100644 struct { COpenMax *openMax; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index a6e42e5..b3252ec 100644 +index e0c0f84..fc51dbf 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -56,6 +56,9 @@ @@ -14486,10 +16710,10 @@ index 176ceff..c58422b 100644 endif diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp new file mode 100644 -index 0000000..e8e376a +index 0000000..47ff25f --- /dev/null +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -@@ -0,0 +1,2354 @@ +@@ -0,0 +1,2367 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org @@ -14827,6 +17051,21 @@ index 0000000..e8e376a + return false; + } + ++ // Fixme: Revisit with new SDK ++ // Workaround for 0.74.01-AES-2 that does not signal if surfaces are too large ++ // it seems that xvba does not support anything > 2k ++ // return false, for files that are larger ++ // if you are unlucky, this would kill your decoder ++ // we limit to 2048x1536(+8) now - as this was tested working ++ int surfaceWidth = (avctx->coded_width+15) & ~15; ++ int surfaceHeight = (avctx->coded_height+15) & ~15; ++ if(surfaceHeight > 1544 || surfaceWidth > 2048) ++ { ++ CLog::Log(LOGERROR, "Surface too large, decoder skipped: surfaceWidth %u, surfaceHeight %u", ++ surfaceWidth, surfaceHeight); ++ return false; ++ } ++ + if (!m_dllAvUtil.Load()) + return false; + @@ -16426,8 +18665,6 @@ index 0000000..e8e376a + +bool COutput::IsDecodingFinished() +{ -+ return true; -+ + // check for decoding to be finished + CXvbaDecodedPicture decodedPic = m_decodedPics.front(); + @@ -17233,24 +19470,25 @@ index 0000000..f38444c + +} diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 15a39fa..e5e71f3 100644 +index 92f62bb..1e5d2ac5 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1162,6 +1162,9 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - case RENDER_FMT_NONE: +@@ -1174,6 +1174,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) formatstr = "NONE"; + buffering = false; break; + case RENDER_FMT_XVBA: + formatstr = "XVBA"; ++ buffering = true; + break; } if(m_bAllowFullscreen) diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 0e320e1..10ef779 100644 +index 30b402d..67aeec9 100644 --- a/xbmc/settings/GUISettings.cpp +++ b/xbmc/settings/GUISettings.cpp -@@ -696,6 +696,9 @@ void CGUISettings::Initialize() +@@ -695,6 +695,9 @@ void CGUISettings::Initialize() #ifdef HAVE_LIBVA AddBool(vp, "videoplayer.usevaapi", 13426, true); #endif @@ -17289,10 +19527,73 @@ index f25d10d..f6b1ea4 100644 1.7.10 -From 5b47c760839742a585f5e1aa3f6275eb283ae564 Mon Sep 17 00:00:00 2001 +From aa13bba48a76e32136814ab242c18646cd8744ec Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Sun, 4 Nov 2012 16:24:10 +0100 +Subject: [PATCH 64/88] xvba: add string for available decoders - we are + important so make sure we are there + +--- + xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +index 0cea7a9..6fb74b7 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +@@ -169,6 +169,11 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne + #elif defined(_LINUX) && !defined(TARGET_DARWIN) + hwSupport += "VAAPI:no "; + #endif ++#if defined(HAVE_LIBXVBA) && defined(TARGET_LINUX) ++ hwSupport += "XVBA:yes "; ++#elif defined(TARGET_LINUX) ++ hwSupport += "XVBA:no "; ++#endif + + CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); + +-- +1.7.10 + + +From 82ae5c8a538374f73dd2f728bcda7ff14efe532a Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 16 Jun 2012 12:46:30 +0200 +Subject: [PATCH 65/88] xvba: do not use vaapi if xvba is present + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +index a2b9195..43a05b3 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +@@ -261,6 +261,15 @@ void CDecoder::Close() + + bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces) + { ++#ifdef HAVE_LIBXVBA ++ std::string Vendor = g_Windowing.GetRenderVendor(); ++ std::transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); ++ if (Vendor.compare(0, 3, "ati") == 0) ++ { ++ return false; ++ } ++#endif ++ + VAEntrypoint entrypoint = VAEntrypointVLD; + VAProfile profile; + +-- +1.7.10 + + +From 1aabfca9ab8a0acd87b3593f97180946ba08e630 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 23 Aug 2012 19:39:49 +0200 -Subject: [PATCH 43/73] ffmpeg: add av_find_default_stream_index to interface +Subject: [PATCH 66/88] ffmpeg: add av_find_default_stream_index to interface --- lib/DllAvFormat.h | 4 ++++ @@ -17338,10 +19639,10 @@ index 9bda3f3..bf31fcb 100644 1.7.10 -From 2a600a0e3acac4f668f10f81a430f2b1d24d2243 Mon Sep 17 00:00:00 2001 +From 541d9c977d0c3d4ab7710085b7edc2386d76ae03 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 44/73] dvdplayer: observe pts counter overflow +Subject: [PATCH 67/88] dvdplayer: observe pts counter overflow --- .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 198 +++++++++++++++++++- @@ -17627,10 +19928,10 @@ index 2b5f2e8..e0acf29 100644 1.7.10 -From 64e55ac8d4fb589f337daba53ada52d6a8d3abf0 Mon Sep 17 00:00:00 2001 +From 30b4f0f57c63d3aca9a55e24714d4360edc761c6 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 45/73] dvdplayer: avoid short screen flicker caused by +Subject: [PATCH 68/88] dvdplayer: avoid short screen flicker caused by unnecessary reconfigure of renderer --- @@ -17638,10 +19939,10 @@ Subject: [PATCH 45/73] dvdplayer: avoid short screen flicker caused by 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index e5e71f3..8b02d81 100644 +index 1e5d2ac5..69f45d4 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1033,7 +1033,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1030,7 +1030,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) || m_output.height != pPicture->iHeight || m_output.dwidth != pPicture->iDisplayWidth || m_output.dheight != pPicture->iDisplayHeight @@ -17650,7 +19951,7 @@ index e5e71f3..8b02d81 100644 || m_output.color_format != (unsigned int)pPicture->format || m_output.extended_format != pPicture->extended_format || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified -@@ -1184,7 +1184,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1197,7 +1197,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) m_output.height = pPicture->iHeight; m_output.dwidth = pPicture->iDisplayWidth; m_output.dheight = pPicture->iDisplayHeight; @@ -17663,43 +19964,10 @@ index e5e71f3..8b02d81 100644 1.7.10 -From 3dff64b607a88901b4bad7439c39b9133b01ed00 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Jun 2012 12:46:30 +0200 -Subject: [PATCH 46/73] xvba: do not use vaapi if xvba is present - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index a2b9195..43a05b3 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -261,6 +261,15 @@ void CDecoder::Close() - - bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces) - { -+#ifdef HAVE_LIBXVBA -+ std::string Vendor = g_Windowing.GetRenderVendor(); -+ std::transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); -+ if (Vendor.compare(0, 3, "ati") == 0) -+ { -+ return false; -+ } -+#endif -+ - VAEntrypoint entrypoint = VAEntrypointVLD; - VAProfile profile; - --- -1.7.10 - - -From 3c5e2eb61270b516341c1846722f5df42ba27eec Mon Sep 17 00:00:00 2001 +From 545cfa0bee6159fc55dfcaf2969d7bc657502071 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 47/73] vdpau: advanced settings for auto deinterlacing +Subject: [PATCH 69/88] vdpau: advanced settings for auto deinterlacing --- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++---- @@ -17708,10 +19976,10 @@ Subject: [PATCH 47/73] vdpau: advanced settings for auto deinterlacing 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 235f565..d95797b 100644 +index 68cf36a..524efae 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1770,10 +1770,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) +@@ -1696,10 +1696,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) if (method == VS_INTERLACEMETHOD_AUTO) { int deint = -1; @@ -17727,7 +19995,7 @@ index 235f565..d95797b 100644 if (deint != -1) { diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 844f8e8..d913924 100644 +index 04a7c7c..0e68a80 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -106,6 +106,8 @@ void CAdvancedSettings::Initialize() @@ -17765,17 +20033,17 @@ index 72718e5..aaa4702 100644 1.7.10 -From 4ecb573a4578240c76d47edfa071a2872285c0ef Mon Sep 17 00:00:00 2001 +From ae14edafa313c667d22cf9a255effab6bcf1fc61 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 11 Oct 2012 13:01:08 +0200 -Subject: [PATCH 48/73] dvdplayer: correct determination if video is playing +Subject: [PATCH 70/88] dvdplayer: correct determination if video is playing --- xbmc/cores/dvdplayer/DVDPlayer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 6fcb6b3..f76691d 100644 +index 3737419..890d99e 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -2382,9 +2382,16 @@ bool CDVDPlayer::IsPaused() const @@ -17801,156 +20069,18 @@ index 6fcb6b3..f76691d 100644 1.7.10 -From 18112c69378d18c498e5f9e0a0ca2db262be6120 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 14 Oct 2012 13:46:54 +0200 -Subject: [PATCH 49/73] rendermanager: fix stuttering in non full-screen mode, - squash to add buffering - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 0506823..b141c80 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1057,8 +1057,9 @@ void CXBMCRenderManager::PrepareNextRender() - presenttime = clocktime + MAXPRESENTDELAY; - - m_sleeptime = presenttime - clocktime; -+ double frametime = 1 / g_graphicsContext.GetFPS(); - -- if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime+0.01) -+ if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) - { - m_presentPts = m_renderBuffers[idx].pts; - m_presenttime = presenttime; --- -1.7.10 - - -From 5488ba31ed2039da5186e4e6e26c16bfae6a7cb2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 14 Oct 2012 17:54:02 +0200 -Subject: [PATCH 50/73] rendermanager: forgot to set flip event if buffering - is not used - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index b141c80..9290f80 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1096,17 +1096,17 @@ void CXBMCRenderManager::NotifyDisplayFlip() - if (!m_pRenderer) - return; - -- if (m_iNumRenderBuffers < 3) -- return; -- -- int last = m_iDisplayedRenderBuffer; -- m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; -- -- if (last != m_iDisplayedRenderBuffer -- && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) -+ if (m_iNumRenderBuffers >= 3) - { -- m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -- m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); -+ int last = m_iDisplayedRenderBuffer; -+ m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; -+ -+ if (last != m_iDisplayedRenderBuffer -+ && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) -+ { -+ m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -+ m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); -+ } - } - - lock.Leave(); --- -1.7.10 - - -From 3ac9979f74f43b629ea9391243697ed4168b290b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 26 Oct 2012 15:30:22 +0200 -Subject: [PATCH 51/73] vdpau: fix small mem leak - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index d95797b..fec4b88 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2052,6 +2052,8 @@ void CMixer::Uninit() - m_outputSurfaces.pop(); - } - m_config.vdpProcs.vdp_video_mixer_destroy(m_videoMixer); -+ -+ delete [] m_BlackBar; - } - - void CMixer::Flush() --- -1.7.10 - - -From 5c6e31de5b357022878c46c94885f34e62ba9a66 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 29 Oct 2012 18:25:56 +0100 -Subject: [PATCH 52/73] xvba: do not render if there is no valid texture - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index ec3606a..7c3adcb 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -2924,16 +2924,14 @@ void CLinuxRendererGL::UploadXVBATexture(int index) - YUVFIELDS &fields = m_buffers[index].fields; - YUVPLANE &plane = fields[0][1]; - -- if (!xvba) -+ if (!xvba || !xvba->valid) - { -- fields[0][1].id = fields[0][0].id; - m_eventTexturesDone[index]->Set(); -- CLog::Log(LOGWARNING,"CLinuxRendererGL::UploadXVBATexture no xvba texture, index: %d", index); -+ m_skipRender = true; - return; - } --// xvba->Transfer(); - -- fields[0][1].id = xvba->texture; -+ plane.id = xvba->texture; - - im.height = xvba->texHeight; - im.width = xvba->texWidth; --- -1.7.10 - - -From 49267751b5b4d0315c0ff850c06c2c465cd0d2a5 Mon Sep 17 00:00:00 2001 +From 1999316cc983ec63d6f9fe05626a0f481d858119 Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 53/73] player: fix rewind +Subject: [PATCH 71/88] player: fix rewind --- xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 33 ++++++++++++++++++++----------- + xbmc/cores/dvdplayer/DVDPlayer.cpp | 30 +++++++++++++++++++----------- xbmc/cores/dvdplayer/DVDPlayer.h | 7 ++++--- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 10 ++++++---- xbmc/cores/dvdplayer/DVDPlayerVideo.h | 1 + - 5 files changed, 36 insertions(+), 20 deletions(-) + 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDMessage.h b/xbmc/cores/dvdplayer/DVDMessage.h index 30b2f5c..b9831d4 100644 @@ -17990,7 +20120,7 @@ index 30b2f5c..b9831d4 100644 class CDVDMsgPlayerSeekChapter : public CDVDMsg diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index f76691d..07df0d8 100644 +index 890d99e..d02f086 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -1543,11 +1543,13 @@ void CDVDPlayer::HandlePlaySpeed() @@ -18048,20 +20178,7 @@ index f76691d..07df0d8 100644 } // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE -@@ -2767,10 +2771,11 @@ int64_t CDVDPlayer::GetTime() - { - offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; - offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; -+ offset = DVD_TIME_TO_MSEC(offset); - if(offset > 1000) offset = 1000; - if(offset < -1000) offset = -1000; - } -- return llrint(m_State.time + DVD_TIME_TO_MSEC(offset)); -+ return llrint(m_State.time + offset); - } - - // return length in msec -@@ -3140,7 +3145,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) +@@ -3140,7 +3144,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) return true; } @@ -18070,7 +20187,7 @@ index f76691d..07df0d8 100644 { double startpts; if(accurate) -@@ -3152,19 +3157,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3152,19 +3156,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) if(startpts != DVD_NOPTS_VALUE) startpts -= m_offset_pts; @@ -18098,7 +20215,7 @@ index f76691d..07df0d8 100644 m_CurrentTeletext.dts = DVD_NOPTS_VALUE; m_CurrentTeletext.startpts = startpts; -@@ -3208,7 +3217,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3208,7 +3216,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) m_CurrentTeletext.started = false; } @@ -18133,10 +20250,10 @@ index d3c201e..70ecea9 100644 int m_errorCount; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 8b02d81..d26ab9c 100644 +index 69f45d4..0434cb9 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1268,13 +1268,13 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +@@ -1281,13 +1281,13 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) if( m_speed < 0 ) { @@ -18153,7 +20270,7 @@ index 8b02d81..d26ab9c 100644 } return result | EOS_DROPPED; } -@@ -1571,7 +1571,7 @@ double CDVDPlayerVideo::GetCurrentPts() +@@ -1584,7 +1584,7 @@ double CDVDPlayerVideo::GetCurrentPts() if( m_stalled ) iRenderPts = DVD_NOPTS_VALUE; @@ -18162,14 +20279,14 @@ index 8b02d81..d26ab9c 100644 iRenderPts = iRenderPts - max(0.0, iSleepTime); return iRenderPts; -@@ -1671,6 +1671,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) +@@ -1684,6 +1684,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) int iSkippedDeint = 0; int iBufferLevel; + m_droppingStats.m_lastPts = pts; + // get decoder stats - if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) + if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) iDecoderPts = pts; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h index 509d5f7..7cddda7 100644 @@ -18187,144 +20304,10 @@ index 509d5f7..7cddda7 100644 1.7.10 -From 42907b5fc097d5b1d9cbc3941fee44af7b5ad95a Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Fri, 2 Nov 2012 17:56:12 +0100 -Subject: [PATCH 54/73] xvba: do not create decoder for surfaces larger than - width 2048 or height 1536 - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -index e8e376a..b73c48a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -@@ -335,6 +335,21 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned - return false; - } - -+ // Fixme: Revisit with new SDK -+ // Workaround for 0.74.01-AES-2 that does not signal if surfaces are too large -+ // it seems that xvba does not support anything > 2k -+ // return false, for files that are larger -+ // if you are unlucky, this would kill your decoder -+ // we limit to 2048x1536(+8) now - as this was tested working -+ int surfaceWidth = (avctx->coded_width+15) & ~15; -+ int surfaceHeight = (avctx->coded_height+15) & ~15; -+ if(surfaceHeight > 1544 || surfaceWidth > 2048) -+ { -+ CLog::Log(LOGERROR, "Surface too large, decoder skipped: surfaceWidth %u, surfaceHeight %u", -+ surfaceWidth, surfaceHeight); -+ return false; -+ } -+ - if (!m_dllAvUtil.Load()) - return false; - --- -1.7.10 - - -From 8aacdb77cd98243077ecf2d3f7195233dcc38c15 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Sun, 4 Nov 2012 16:24:10 +0100 -Subject: [PATCH 55/73] xvba: add string for available decoders - we are - important so make sure we are there - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index 0cea7a9..6fb74b7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -169,6 +169,11 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - #elif defined(_LINUX) && !defined(TARGET_DARWIN) - hwSupport += "VAAPI:no "; - #endif -+#if defined(HAVE_LIBXVBA) && defined(TARGET_LINUX) -+ hwSupport += "XVBA:yes "; -+#elif defined(TARGET_LINUX) -+ hwSupport += "XVBA:no "; -+#endif - - CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); - --- -1.7.10 - - -From fe452b364c738733b949b3c7f09a6fb8fe228978 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Thu, 22 Nov 2012 21:32:21 +0100 -Subject: [PATCH 56/73] xvba: revisit Artefacts. There are more broken video - files out there - ---- - lib/ffmpeg/libavcodec/xvba_h264.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/lib/ffmpeg/libavcodec/xvba_h264.c b/lib/ffmpeg/libavcodec/xvba_h264.c -index a077442..87af687 100644 ---- a/lib/ffmpeg/libavcodec/xvba_h264.c -+++ b/lib/ffmpeg/libavcodec/xvba_h264.c -@@ -102,10 +102,16 @@ static int end_frame(AVCodecContext *avctx) - pic_descriptor->avc_num_ref_frames = h->sps.ref_frame_count; - pic_descriptor->avc_reserved_8bit = 0; - -- /* Set correct level */ -- if (pic_descriptor->level == 41) { -+ /* Set a level that can decode stuff in every case without a lookup table -+ xvba seems to have problems only when the number of Reframes goes beyond -+ the max support number of Level4.1@High. So in praxis decoding a Level 3.0 -+ file that in deed has level4.1@High specs does not matter. We use this fact -+ and check if the ref_frames stay in the range Level4.1@high can decode if -+ not, we set Level5.1 */ -+ if (pic_descriptor->avc_num_ref_frames > 4) { - const unsigned int mbw = pic_descriptor->width_in_mb; - const unsigned int mbh = pic_descriptor->height_in_mb; -+ // this matches Level4.1@High stats to differ between <= 4.1 and 5.1 - const unsigned int max_ref_frames = 12288 * 1024 / (mbw * mbh * 384); - const unsigned int num_ref_frames = pic_descriptor->avc_num_ref_frames; - if (max_ref_frames < num_ref_frames) --- -1.7.10 - - -From c7b995f8d10dc0171f80a4d604c5cbf0e6520a59 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 23 Nov 2012 09:42:02 +0100 -Subject: [PATCH 57/73] xvba: reactivate accidently disabled - IsDecodingFinished - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -index b73c48a..47ff25f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -@@ -1949,8 +1949,6 @@ void COutput::Flush() - - bool COutput::IsDecodingFinished() - { -- return true; -- - // check for decoding to be finished - CXvbaDecodedPicture decodedPic = m_decodedPics.front(); - --- -1.7.10 - - -From 2e4d9701752aa760c2cc5b8ca9b247ec476026e2 Mon Sep 17 00:00:00 2001 +From d4c4fafbcd0bce6f566e2e65e1f9009dc445f832 Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 58/73] xrandr: fix query for multiple screens +Subject: [PATCH 72/88] xrandr: fix query for multiple screens --- xbmc/windowing/X11/XRandR.cpp | 10 ++++++---- @@ -18365,10 +20348,10 @@ index cc933b9..533e03d 100644 1.7.10 -From c39f8e5141d6e176f1edb0eb510fa54976915654 Mon Sep 17 00:00:00 2001 +From a4d6cfe137f6a6a91443cdc3f464a7564efb49eb Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 2 Dec 2012 15:46:55 +0100 -Subject: [PATCH 59/73] X11: add debug log to print out refresh after xrr +Subject: [PATCH 73/88] X11: add debug log to print out refresh after xrr event --- @@ -18396,10 +20379,10 @@ index ef83133..76c6362 100644 1.7.10 -From 181697e9001e0568ff06098d0f2223fc4c0d8f51 Mon Sep 17 00:00:00 2001 +From ea768fa98309706665097abbf7d642ab9ee2ceae Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 60/73] X11: dont call XCloseDisplay on shutdown, it crashes +Subject: [PATCH 74/88] X11: dont call XCloseDisplay on shutdown, it crashes when powered doen by cec on ATI --- @@ -18424,354 +20407,10 @@ index 76c6362..e4e25b2 100644 1.7.10 -From 87d87db6cd67fc7f7f7afa88f089eafaac1b9605 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 09:52:17 +0100 -Subject: [PATCH 61/73] vdpau: make interop gl default and remove setting, - rename and intvert interop yuv - ---- - language/English/strings.po | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 17 ++++++++++------- - xbmc/settings/GUISettings.cpp | 3 +-- - xbmc/settings/GUIWindowSettingsCategory.cpp | 23 +++-------------------- - 4 files changed, 15 insertions(+), 30 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index ede18b3..281a8a1 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5121,7 +5121,7 @@ msgid "Allow Vdpau OpenGL interop" - msgstr "" - - msgctxt "#13436" --msgid "Allow Vdpau OpenGL interop YUV" -+msgid "Prefer VDPAU Video Mixer" - msgstr "" - - msgctxt "#13437" -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index fec4b88..ad140fb 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -365,12 +365,15 @@ bool CDecoder::Supports(EINTERLACEMETHOD method) - || method == VS_INTERLACEMETHOD_AUTO) - return true; - -- if (g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv")) -+ if (!m_vdpauConfig.usePixmaps) - { - if (method == VS_INTERLACEMETHOD_RENDER_BOB) - return true; - } - -+ if (method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE) -+ return false; -+ - for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) - { - if(p->method == method) -@@ -1847,7 +1850,7 @@ void CMixer::SetDeinterlacing() - - SetDeintSkipChroma(); - -- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); - } - - void CMixer::SetDeintSkipChroma() -@@ -2039,7 +2042,7 @@ void CMixer::Init() - m_vdpError = false; - - m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; -- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); - - CreateVdpauMixer(); - } -@@ -2149,11 +2152,12 @@ void CMixer::InitCycle() - DVP_FLAG_INTERLACED); - m_config.useInteropYuv = false; - } -- else if (method == VS_INTERLACEMETHOD_RENDER_BOB && m_config.useInteropYuv) -+ else if (method == VS_INTERLACEMETHOD_RENDER_BOB) - { - m_mixersteps = 1; - m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; - m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; -+ m_config.useInteropYuv = true; - } - else - { -@@ -3185,7 +3189,7 @@ bool COutput::GLInit() - glVDPAUGetSurfaceivNV = NULL; - #endif - -- m_config.usePixmaps = !g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+ m_config.usePixmaps = false; - - #ifdef GL_NV_vdpau_interop - if (glewIsSupported("GL_NV_vdpau_interop")) -@@ -3217,8 +3221,7 @@ bool COutput::GLInit() - #endif - { - m_config.usePixmaps = true; -- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -+ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); - } - if (!glXBindTexImageEXT) - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 10ef779..a4bd524 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -690,8 +690,7 @@ void CGUISettings::Initialize() - - #ifdef HAVE_LIBVDPAU - AddBool(vp, "videoplayer.usevdpau", 13425, true); -- AddBool(vp, "videoplayer.usevdpauinterop", 13435, true); -- AddBool(vp, "videoplayer.usevdpauinteropyuv", 13436, false); -+ AddBool(vp, "videoplayer.usevdpaumixer", 13436, true); - #endif - #ifdef HAVE_LIBVA - AddBool(vp, "videoplayer.usevaapi", 13426, true); -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index 3c19a06..b9f18e4 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -602,9 +602,9 @@ void CGUIWindowSettingsCategory::UpdateSettings() - pControl->SetEnabled(true); - } - } -- else if (strSetting.Equals("videoplayer.usevdpauinteropyuv")) -+ else if (strSetting.Equals("videoplayer.usevdpaumixer")) - { -- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+ bool hasInterop = true; - #ifndef GL_NV_vdpau_interop - hasInterop = false; - #endif -@@ -616,24 +616,7 @@ void CGUIWindowSettingsCategory::UpdateSettings() - else - { - pControl->SetEnabled(false); -- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -- } -- } -- else if (strSetting.Equals("videoplayer.usevdpauinterop")) -- { -- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpau"); --#ifndef GL_NV_vdpau_interop -- hasInterop = false; --#endif -- CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); -- if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) -- { -- pControl->SetEnabled(true); -- } -- else -- { -- pControl->SetEnabled(false); -- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -+ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); - } - } - else --- -1.7.10 - - -From d468e959e2d7d888e02db3848542b5a203e007c3 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 18:34:47 +0100 -Subject: [PATCH 62/73] vdpau: drop studio level conversion - ---- - language/English/strings.po | 6 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 4 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 94 +----------------------- - xbmc/settings/GUISettings.cpp | 1 - - 4 files changed, 7 insertions(+), 98 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 281a8a1..fc896b3 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -4371,11 +4371,7 @@ msgctxt "#13121" - msgid "VDPAU HQ Upscaling level" - msgstr "" - --msgctxt "#13122" --msgid "VDPAU Studio level color conversion" --msgstr "" -- --#empty strings from id 13123 to 13129 -+#empty strings from id 13122 to 13129 - - msgctxt "#13130" - msgid "Blank other displays" -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 7c3adcb..0bb924b 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -3545,7 +3545,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - { - if(feature == RENDERFEATURE_BRIGHTNESS) - { -- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -+ if (m_renderMethod & RENDER_VDPAU) - return true; - - if (m_renderMethod & RENDER_VAAPI) -@@ -3561,7 +3561,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - - if(feature == RENDERFEATURE_CONTRAST) - { -- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -+ if (m_renderMethod & RENDER_VDPAU) - return true; - - if (m_renderMethod & RENDER_VAAPI) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index ad140fb..5851e1a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -57,15 +57,6 @@ - }; - const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); - --//static float studioCSC[3][4] = --//{ --// { 1.0f, 0.0f, 1.57480000f,-0.78740000f}, --// { 1.0f,-0.18737736f,-0.46813736f, 0.32775736f}, --// { 1.0f, 1.85556000f, 0.0f,-0.92780000f} --//}; --static float studioCSCKCoeffs601[3] = {0.299, 0.587, 0.114}; //BT601 {Kr, Kg, Kb} --static float studioCSCKCoeffs709[3] = {0.2126, 0.7152, 0.0722}; //BT709 {Kr, Kg, Kb} -- - static struct SInterlaceMapping - { - const EINTERLACEMETHOD method; -@@ -1614,74 +1605,6 @@ void CMixer::PostProcOff() - DisableHQScaling(); - } - -- --bool CMixer::GenerateStudioCSCMatrix(VdpColorStandard colorStandard, VdpCSCMatrix &studioCSCMatrix) --{ -- // instead use studioCSCKCoeffs601[3], studioCSCKCoeffs709[3] to generate float[3][4] matrix (float studioCSC[3][4]) -- // m00 = mRY = red: luma factor (contrast factor) (1.0) -- // m10 = mGY = green: luma factor (contrast factor) (1.0) -- // m20 = mBY = blue: luma factor (contrast factor) (1.0) -- // -- // m01 = mRB = red: blue color diff coeff (0.0) -- // m11 = mGB = green: blue color diff coeff (-2Kb(1-Kb)/(Kg)) -- // m21 = mBB = blue: blue color diff coeff ((1-Kb)/0.5) -- // -- // m02 = mRR = red: red color diff coeff ((1-Kr)/0.5) -- // m12 = mGR = green: red color diff coeff (-2Kr(1-Kr)/(Kg)) -- // m22 = mBR = blue: red color diff coeff (0.0) -- // -- // m03 = mRC = red: colour zero offset (brightness factor) (-(1-Kr)/0.5 * (128/255)) -- // m13 = mGC = green: colour zero offset (brightness factor) ((256/255) * (Kb(1-Kb) + Kr(1-Kr)) / Kg) -- // m23 = mBC = blue: colour zero offset (brightness factor) (-(1-Kb)/0.5 * (128/255)) -- -- // columns -- int Y = 0; -- int Cb = 1; -- int Cr = 2; -- int C = 3; -- // rows -- int R = 0; -- int G = 1; -- int B = 2; -- // colour standard coefficients for red, geen, blue -- double Kr, Kg, Kb; -- // colour diff zero position (use standard 8-bit coding precision) -- double CDZ = 128; //256*0.5 -- // range excursion (use standard 8-bit coding precision) -- double EXC = 255; //256-1 -- -- if (colorStandard == VDP_COLOR_STANDARD_ITUR_BT_601) -- { -- Kr = studioCSCKCoeffs601[0]; -- Kg = studioCSCKCoeffs601[1]; -- Kb = studioCSCKCoeffs601[2]; -- } -- else // assume VDP_COLOR_STANDARD_ITUR_BT_709 -- { -- Kr = studioCSCKCoeffs709[0]; -- Kg = studioCSCKCoeffs709[1]; -- Kb = studioCSCKCoeffs709[2]; -- } -- // we keep luma unscaled to retain the levels present in source so that 16-235 luma is converted to RGB 16-235 -- studioCSCMatrix[R][Y] = 1.0; -- studioCSCMatrix[G][Y] = 1.0; -- studioCSCMatrix[B][Y] = 1.0; -- -- studioCSCMatrix[R][Cb] = 0.0; -- studioCSCMatrix[G][Cb] = (double)-2 * Kb * (1 - Kb) / Kg; -- studioCSCMatrix[B][Cb] = (double)(1 - Kb) / 0.5; -- -- studioCSCMatrix[R][Cr] = (double)(1 - Kr) / 0.5; -- studioCSCMatrix[G][Cr] = (double)-2 * Kr * (1 - Kr) / Kg; -- studioCSCMatrix[B][Cr] = 0.0; -- -- studioCSCMatrix[R][C] = (double)-1 * studioCSCMatrix[R][Cr] * CDZ/EXC; -- studioCSCMatrix[G][C] = (double)-1 * (studioCSCMatrix[G][Cb] + studioCSCMatrix[G][Cr]) * CDZ/EXC; -- studioCSCMatrix[B][C] = (double)-1 * studioCSCMatrix[B][Cb] * CDZ/EXC; -- -- return true; --} -- - void CMixer::SetColor() - { - VdpStatus vdp_st; -@@ -1701,19 +1624,10 @@ void CMixer::SetColor() - //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); - - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; -- if (g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -- { -- float studioCSC[3][4]; -- GenerateStudioCSCMatrix(colorStandard, studioCSC); -- void const * pm_CSCMatix[] = { &studioCSC }; -- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -- else -- { -- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -- void const * pm_CSCMatix[] = { &m_CSCMatrix }; -- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -+ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -+ void const * pm_CSCMatix[] = { &m_CSCMatrix }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -+ - CheckStatus(vdp_st, __LINE__); - } - -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index a4bd524..67aeec9 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -772,7 +772,6 @@ void CGUISettings::Initialize() - AddSeparator(vp, "videoplayer.sep1.5"); - #ifdef HAVE_LIBVDPAU - AddBool(NULL, "videoplayer.vdpauUpscalingLevel", 13121, false); -- AddBool(vp, "videoplayer.vdpaustudiolevel", 13122, false); - #endif - #endif - AddSeparator(vp, "videoplayer.sep5"); --- -1.7.10 - - -From 672e2f03b5b8d133ebfa87e0ebf20fd9f3fb0beb Mon Sep 17 00:00:00 2001 +From aaf6be8480620bed4631c9da17b62c15d260d298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Coutant?= Date: Wed, 12 Dec 2012 19:49:47 +0100 -Subject: [PATCH 63/73] x11: support for multiple x screens +Subject: [PATCH 75/88] x11: support for multiple x screens --- xbmc/windowing/X11/XRandR.cpp | 2 +- @@ -18794,117 +20433,10 @@ index 533e03d..7a16488 100644 1.7.10 -From c0f54dac42fba2a522ab4f43f3f20a11a3bace3b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 20:28:49 +0100 -Subject: [PATCH 64/73] vdpau: observe ffmpeg tags for color space - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 38 ++++++++++++++++-------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 1 + - 2 files changed, 27 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 5851e1a..8858614 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -907,6 +907,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) - memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); - ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); - pic.render = render; -+ pic.DVDPic.color_matrix = avctx->colorspace; - m_bufferStats.IncDecoded(); - m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - -@@ -1513,10 +1514,6 @@ void CMixer::InitCSCMatrix(int Width) - m_Procamp.contrast = 1.0; - m_Procamp.saturation = 1.0; - m_Procamp.hue = 0; -- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, -- (Width < 1000)? VDP_COLOR_STANDARD_ITUR_BT_601 : VDP_COLOR_STANDARD_ITUR_BT_709, -- &m_CSCMatrix); -- CheckStatus(vdp_st, __LINE__); - } - - void CMixer::CheckFeatures() -@@ -1527,11 +1524,13 @@ void CMixer::CheckFeatures() - m_Upscale = m_config.upscale; - } - if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness || -- m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) -+ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast || -+ m_ColorMatrix != m_mixerInput[1].DVDPic.color_matrix) - { - SetColor(); - m_Brightness = g_settings.m_currentVideoSettings.m_Brightness; - m_Contrast = g_settings.m_currentVideoSettings.m_Contrast; -+ m_ColorMatrix = m_mixerInput[1].DVDPic.color_matrix; - } - if (m_NoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) - { -@@ -1615,13 +1614,27 @@ void CMixer::SetColor() - m_Procamp.contrast = (float)((g_settings.m_currentVideoSettings.m_Contrast)+50) / 100; - - VdpColorStandard colorStandard; --// if(vid_height >= 600 || vid_width > 1024) -- if(m_config.surfaceWidth > 1000) -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); -- else -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); -+ switch(m_mixerInput[1].DVDPic.color_matrix) -+ { -+ case AVCOL_SPC_BT709: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ break; -+ case AVCOL_SPC_BT470BG: -+ case AVCOL_SPC_SMPTE170M: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ break; -+ case AVCOL_SPC_SMPTE240M: -+ colorStandard = VDP_COLOR_STANDARD_SMPTE_240M; -+ break; -+ case AVCOL_SPC_FCC: -+ case AVCOL_SPC_UNSPECIFIED: -+ case AVCOL_SPC_RGB: -+ default: -+ if(m_config.surfaceWidth > 1000) -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ else -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ } - - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; - vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -@@ -1952,6 +1965,7 @@ void CMixer::Init() - m_Sharpness = 0.0; - m_DeintMode = 0; - m_Deint = 0; -+ m_ColorMatrix = 0; - m_PostProc = false; - m_vdpError = false; - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index 4d1559c..471ad68 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -334,6 +334,7 @@ class CMixer : private CThread - int m_DeintMode; - int m_Deint; - int m_Upscale; -+ unsigned int m_ColorMatrix : 4; - uint32_t *m_BlackBar; - VdpVideoMixerPictureStructure m_mixerfield; - int m_mixerstep; --- -1.7.10 - - -From 82584e21f05fb275853f9baca72a65b6ff0672ff Mon Sep 17 00:00:00 2001 +From 5c8a99221143e88cc2d076516d78106e09ac2a60 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 20 Dec 2012 19:35:38 +0100 -Subject: [PATCH 65/73] fix compile error after recent change +Subject: [PATCH 76/88] fix compile error after recent change --- xbmc/settings/GUIWindowSettingsCategory.cpp | 2 +- @@ -18927,10 +20459,10 @@ index b9f18e4..cacb32a 100644 1.7.10 -From 514833b80006796c7985e37e414137e50a0c0d43 Mon Sep 17 00:00:00 2001 +From 9c3bd38c6e2f8da31d8627115f176f2c19e7504e Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 66/73] pvr: increase changes counter of stream on stream +Subject: [PATCH 77/88] pvr: increase changes counter of stream on stream change, cosmetics after dd307930d39d92f145a01a16600cd00e01ec39be @@ -18965,10 +20497,10 @@ index 8c984f6..034e545 100644 1.7.10 -From 118041f574fa106e74e7a8ef26243ea4225643b5 Mon Sep 17 00:00:00 2001 +From 8f0c31f9d2f2cb438c74e83185480dc1d6ff1f1a Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 67/73] X11: add keymapping for XF86XK_Sleep +Subject: [PATCH 78/88] X11: add keymapping for XF86XK_Sleep --- xbmc/windowing/WinEventsX11.cpp | 1 + @@ -18990,118 +20522,10 @@ index c31877e..ed31c04 100644 1.7.10 -From adce338a8fef2247a878e52c34c8a38d2788beb3 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Sat, 12 Jan 2013 13:03:50 +0100 -Subject: [PATCH 68/73] dvdplayer: Allow multithread decoding for hi10p - content by default - -This allows decoding of some hi10p material on e.g. AMD Fusion with -both cores at the max. This introduces a new advancedsetting named -disablehi10pmultithreading to disable hi10p decoded multithreaded. ---- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 18 ++++++++++++++++-- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 1 + - xbmc/settings/AdvancedSettings.cpp | 2 ++ - xbmc/settings/AdvancedSettings.h | 1 + - 4 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index b3252ec..3f8a6e8 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -154,6 +154,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - m_iScreenHeight = 0; - m_iOrientation = 0; - m_bSoftware = false; -+ m_isHi10p = false; - m_pHardware = NULL; - m_iLastKeyframe = 0; - m_dts = DVD_NOPTS_VALUE; -@@ -204,7 +205,10 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - case FF_PROFILE_H264_HIGH_444_PREDICTIVE: - case FF_PROFILE_H264_HIGH_444_INTRA: - case FF_PROFILE_H264_CAVLC_444: -+ // this is needed to not open the decoders - m_bSoftware = true; -+ // this we need to enable multithreading for hi10p via advancedsettings -+ m_isHi10p = true; - break; - } - } -@@ -277,8 +281,18 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - m_pCodecContext->codec_tag = hints.codec_tag; - /* Only allow slice threading, since frame threading is more - * sensitive to changes in frame sizes, and it causes crashes -- * during HW accell */ -- m_pCodecContext->thread_type = FF_THREAD_SLICE; -+ * during HW accell - so we unset it in this case. -+ * -+ * When we detect Hi10p and user did not disable hi10pmultithreading -+ * via advancedsettings.xml we keep the ffmpeg default thread type. -+ * */ -+ if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading) -+ { -+ CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d", -+ m_pCodecContext->thread_type); -+ } -+ else -+ m_pCodecContext->thread_type = FF_THREAD_SLICE; - - #if defined(TARGET_DARWIN_IOS) - // ffmpeg with enabled neon will crash and burn if this is enabled -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index bf4367c..db1d2b2 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -116,6 +116,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec - - std::string m_name; - bool m_bSoftware; -+ bool m_isHi10p; - IHardwareDecoder *m_pHardware; - int m_iLastKeyframe; - double m_dts; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index d913924..6a48309 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -116,6 +116,7 @@ void CAdvancedSettings::Initialize() - m_DXVANoDeintProcForProgressive = false; - m_videoFpsDetect = 1; - m_videoDefaultLatency = 0.0; -+ m_videoDisableHi10pMultithreading = false; - - m_musicUseTimeSeeking = true; - m_musicTimeSeekForward = 10; -@@ -502,6 +503,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); - XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); - XMLUtils::GetBoolean(pElement,"allowmpeg4vdpau",m_videoAllowMpeg4VDPAU); -+ XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading); - XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI); - XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); - XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index aaa4702..863e4f3 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -168,6 +168,7 @@ class CAdvancedSettings - bool m_DXVAForceProcessorRenderer; - bool m_DXVANoDeintProcForProgressive; - int m_videoFpsDetect; -+ bool m_videoDisableHi10pMultithreading; - - CStdString m_videoDefaultPlayer; - CStdString m_videoDefaultDVDPlayer; --- -1.7.10 - - -From a4824bb077abbf61dcc123f70e4bd78a021de2eb Mon Sep 17 00:00:00 2001 +From 9e099b7ba03687449ae5c725b48bda3ee378408b Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 69/73] X11: remove toggle full screen after resume +Subject: [PATCH 79/88] X11: remove toggle full screen after resume --- xbmc/powermanagement/PowerManager.cpp | 5 ----- @@ -19127,10 +20551,10 @@ index a5534c9..7e2ddc6 100644 1.7.10 -From db652deb4330ab7b7f3cc83a55359e910fc2caec Mon Sep 17 00:00:00 2001 +From b1420829ab0a6ab832f2bf36ed49a46e6e5e8d9f Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 70/73] xrandr: set screen on mode change command +Subject: [PATCH 80/88] xrandr: set screen on mode change command --- xbmc/windowing/X11/XRandR.cpp | 2 +- @@ -19153,10 +20577,10 @@ index 7a16488..6531ba3 100644 1.7.10 -From 81a1c20546aec833174595a86db363dd058b43b4 Mon Sep 17 00:00:00 2001 +From 2855a651752902838fd69fd298261cd9770132c0 Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 71/73] X11: recreate glx context when output changes +Subject: [PATCH 81/88] X11: recreate glx context when output changes --- xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- @@ -19207,89 +20631,487 @@ index 0b7c10a..33b1739 100644 1.7.10 -From 30eaf88e0a66baab5a3a18add429d295e4a272fb Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 27 Jan 2013 12:10:19 +0100 -Subject: [PATCH 72/73] vdpau: switch off de-interlacing on ff +From 171c0cde342915677b0b9467675eba4b89961ee8 Mon Sep 17 00:00:00 2001 +From: unknown +Date: Fri, 18 Jan 2013 15:16:38 +0100 +Subject: [PATCH 82/88] multi-screen: fix compilation on windows --- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + xbmc/settings/GUIWindowSettingsCategory.cpp | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 8858614..3e21d9d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2043,8 +2043,9 @@ void CMixer::InitCycle() - EINTERLACEMETHOD method = GetDeinterlacingMethod(); - bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; - -- if (mode == VS_DEINTERLACEMODE_FORCE || -- (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) -+ if (!(flags & DVP_FLAG_NO_POSTPROC) && -+ (mode == VS_DEINTERLACEMODE_FORCE || -+ (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) - { - if((method == VS_INTERLACEMETHOD_AUTO && interlaced) - || method == VS_INTERLACEMETHOD_VDPAU_BOB --- -1.7.10 - - -From 912b6ede1258d68c0f7cc7e57201bf1b50ae3fa7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Feb 2013 13:17:09 +0100 -Subject: [PATCH 73/73] vdpau: fix mp4 part2 decoding, activate by default - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++------ - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 3 insertions(+), 7 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 3e21d9d..524efae 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -127,10 +127,9 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int - VdpDecoderProfile profile = 0; - if(avctx->codec_id == CODEC_ID_H264) - profile = VDP_DECODER_PROFILE_H264_HIGH; --#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP - else if(avctx->codec_id == CODEC_ID_MPEG4) - profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; --#endif -+ - if(profile) +diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp +index cacb32a..cbf0acb 100644 +--- a/xbmc/settings/GUIWindowSettingsCategory.cpp ++++ b/xbmc/settings/GUIWindowSettingsCategory.cpp +@@ -528,12 +528,14 @@ void CGUIWindowSettingsCategory::CreateSettings() + FillInRefreshRates(strSetting, g_guiSettings.GetResolution(), false); + continue; + } ++#if defined(HAS_GLX) + else if (strSetting.Equals("videoscreen.monitor")) { - if (!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width)) -@@ -530,13 +529,10 @@ void CDecoder::ReadFormatOf( PixelFormat fmt - vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; --#if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) && \ -- (defined VDP_DECODER_PROFILE_MP) - case PIX_FMT_VDPAU_MPEG4: -- vdp_decoder_profile = VDP_DECOPEG4_PART2_ASP; -+ vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; --#endif - default: - vdp_decoder_profile = 0; - vdp_chroma_type = 0; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 6a48309..d390ec7 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -102,7 +102,7 @@ void CAdvancedSettings::Initialize() - m_videoNonLinStretchRatio = 0.5f; - m_videoEnableHighQualityHwScalers = false; - m_videoAutoScaleMaxFps = 30.0f; -- m_videoAllowMpeg4VDPAU = false; -+ m_videoAllowMpeg4VDPAU = true; - m_videoAllowMpeg4VAAPI = false; - m_videoDisableBackgroundDeinterlace = false; - m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect + AddSetting(pSetting, group->GetWidth(), iControlID); + FillInMonitors(strSetting); + continue; + } ++#endif + else if (strSetting.Equals("lookandfeel.skintheme")) + { + AddSetting(pSetting, group->GetWidth(), iControlID); +@@ -1483,6 +1485,7 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting + // Cascade + FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); + } ++#if defined(HAS_GLX) + else if (strSetting.Equals("videoscreen.monitor")) + { + CSettingString *pSettingString = (CSettingString *)pSettingControl->GetSetting(); +@@ -1497,6 +1500,7 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting + FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); + } + } ++#endif + else if (strSetting.Equals("videoscreen.resolution")) + { + RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution"); +@@ -2451,6 +2455,7 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES + + void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) + { ++#if defined(HAS_GLX) + // we expect "videoscreen.monitor" but it might be hidden on some platforms, + // so check that we actually have a visable control. + BaseSettingControlPtr control = GetSetting(strSetting); +@@ -2476,6 +2481,7 @@ void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) + pControl->SetValue(currentMonitor); + g_guiSettings.SetString("videoscreen.monitor", g_settings.m_ResInfo[RES_DESKTOP].strOutput); + } ++#endif + } + + +@@ -2607,7 +2613,10 @@ void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes) + RESOLUTION lastRes = g_graphicsContext.GetVideoResolution(); + bool cancelled = false; + +- bool outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); ++ bool outputChanged = true; ++#if defined(HAS_GLX) ++ outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); ++#endif + + g_guiSettings.SetResolution(nextRes); + g_graphicsContext.SetVideoResolution(nextRes, outputChanged); +-- +1.7.10 + + +From b4c3030639f4f89678d96597596c98ed49abb8c0 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Fri, 14 Dec 2012 14:19:15 +0100 +Subject: [PATCH 83/88] pvr: do not show selection dialog for a single menu + hook + +--- + xbmc/pvr/addons/PVRClients.cpp | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp +index ae11936..69d8b0d 100644 +--- a/xbmc/pvr/addons/PVRClients.cpp ++++ b/xbmc/pvr/addons/PVRClients.cpp +@@ -717,16 +717,19 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat) + if (GetConnectedClient(iClientID, client) && client->HaveMenuHooks(cat)) + { + hooks = client->GetMenuHooks(); +- std::vector hookIDs; ++ int selection = 0; + +- CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); +- pDialog->Reset(); +- pDialog->SetHeading(19196); +- for (unsigned int i = 0; i < hooks->size(); i++) +- pDialog->Add(client->GetString(hooks->at(i).iLocalizedStringId)); +- pDialog->DoModal(); ++ if (hooks->size() > 1) ++ { ++ CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); ++ pDialog->Reset(); ++ pDialog->SetHeading(19196); ++ for (unsigned int i = 0; i < hooks->size(); i++) ++ pDialog->Add(client->GetString(hooks->at(i).iLocalizedStringId)); ++ pDialog->DoModal(); ++ selection = pDialog->GetSelectedLabel(); ++ } + +- int selection = pDialog->GetSelectedLabel(); + if (selection >= 0) + client->CallMenuHook(hooks->at(selection)); + } +-- +1.7.10 + + +From fe99ee421cb83fea7342729fe89153c9ba4c1842 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 3 Feb 2013 08:17:16 +0100 +Subject: [PATCH 84/88] X11: use default screen parameters if no output + connected + +--- + xbmc/windowing/X11/WinSystemX11.cpp | 55 +++++++++++++++++++++-------------- + 1 file changed, 33 insertions(+), 22 deletions(-) + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index b87e264..3cadd13 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -203,25 +203,27 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl + } + + XMode currmode = g_xrandr.GetCurrentMode(out.name); +- +- // flip h/w when rotated +- if (m_bIsRotated) ++ if (!currmode.name.empty()) + { +- int w = mode.w; +- mode.w = mode.h; +- mode.h = w; +- } ++ // flip h/w when rotated ++ if (m_bIsRotated) ++ { ++ int w = mode.w; ++ mode.w = mode.h; ++ mode.h = w; ++ } + +- // only call xrandr if mode changes +- if (currmode.w != mode.w || currmode.h != mode.h || +- currmode.hz != mode.hz || currmode.id != mode.id) +- { +- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); +- OnLostDevice(); +- m_bIsInternalXrr = true; +- g_xrandr.SetMode(out, mode); +- if (m_glWindow) +- return true; ++ // only call xrandr if mode changes ++ if (currmode.w != mode.w || currmode.h != mode.h || ++ currmode.hz != mode.hz || currmode.id != mode.id) ++ { ++ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); ++ OnLostDevice(); ++ m_bIsInternalXrr = true; ++ g_xrandr.SetMode(out, mode); ++ if (m_glWindow) ++ return true; ++ } + } + #endif + +@@ -268,9 +270,10 @@ void CWinSystemX11::UpdateResolutions() + else + #endif + { +- int x11screen = m_nScreen; +- int w = DisplayWidth(m_dpy, x11screen); +- int h = DisplayHeight(m_dpy, x11screen); ++ g_guiSettings.SetString("videoscreen.monitor", "Default"); ++ m_nScreen = DefaultScreen(m_dpy); ++ int w = DisplayWidth(m_dpy, m_nScreen); ++ int h = DisplayHeight(m_dpy, m_nScreen); + UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, 0.0); + } + +@@ -819,11 +822,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + Colormap cmap; + XSetWindowAttributes swa; + XVisualInfo *vi; ++ int x0 = 0; ++ int y0 = 0; + + XOutput *out = g_xrandr.GetOutput(output); + if (!out) + out = g_xrandr.GetOutput(m_currentOutput); +- m_nScreen = out->screen; ++ if (out) ++ { ++ m_nScreen = out->screen; ++ x0 = out->x; ++ y0 = out->y; ++ } ++ + vi = glXChooseVisual(m_dpy, m_nScreen, att); + cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); + +@@ -842,7 +853,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd + unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; + + m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), +- out->x, out->y, width, height, 0, vi->depth, ++ x0, y0, width, height, 0, vi->depth, + InputOutput, vi->visual, + mask, &swa); + +-- +1.7.10 + + +From 11696cc729a3a94d8aa5434b1e7948ae5e7b249d Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 25 Feb 2013 08:47:10 +0100 +Subject: [PATCH 85/88] vdpau: release more resources on pre-cleanup + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 72 ++++++++++++++++++++++-- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 2 + + 2 files changed, 68 insertions(+), 6 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 524efae..38ef375 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1142,6 +1142,11 @@ void CMixer::Dispose() + m_dataPort.Purge(); + } + ++bool CMixer::IsActive() ++{ ++ return IsRunning(); ++} ++ + void CMixer::OnStartup() + { + CLog::Log(LOGNOTICE, "CMixer::OnStartup: Output Thread created"); +@@ -2455,6 +2460,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) + return; + case COutputControlProtocol::PRECLEANUP: + Flush(); ++ PreCleanup(); + msg->Reply(COutputControlProtocol::ACC); + return; + default: +@@ -2661,15 +2667,18 @@ bool COutput::Uninit() + + void COutput::Flush() + { +- Message *reply; +- if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, ++ if (m_mixer.IsActive()) ++ { ++ Message *reply; ++ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, + &reply, + 2000)) +- { +- reply->Release(); ++ { ++ reply->Release(); ++ } ++ else ++ CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); + } +- else +- CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); + + Message *msg; + while (m_mixer.m_dataPort.ReceiveInMessage(&msg)) +@@ -3008,6 +3017,57 @@ void COutput::ReleaseBufferPool() + } + } + ++void COutput::PreCleanup() ++{ ++ ++ VdpStatus vdp_st; ++ ++ m_mixer.Dispose(); ++ ++ CSingleLock lock(m_bufferPool.renderPicSec); ++ for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) ++ { ++ if (m_bufferPool.outputSurfaces[i] == VDP_INVALID_HANDLE) ++ continue; ++ ++ // check if output surface is in use ++ bool used = false; ++ std::deque::iterator it; ++ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) ++ { ++ if (((*it)->sourceIdx == m_bufferPool.outputSurfaces[i]) && (*it)->valid) ++ { ++ used = true; ++ break; ++ } ++ } ++ if (used) ++ continue; ++ ++#ifdef GL_NV_vdpau_interop ++ // unmap surface ++ std::map::iterator it_map; ++ it_map = m_bufferPool.glOutputSurfaceMap.find(m_bufferPool.outputSurfaces[i]); ++ if (it_map == m_bufferPool.glOutputSurfaceMap.end()) ++ { ++ CLog::Log(LOGERROR, "%s - could not find gl surface", __FUNCTION__); ++ continue; ++ } ++ glVDPAUUnregisterSurfaceNV(it_map->second.glVdpauSurface); ++ glDeleteTextures(1, it_map->second.texture); ++ m_bufferPool.glOutputSurfaceMap.erase(it_map); ++#endif ++ ++ vdp_st = m_config.vdpProcs.vdp_output_surface_destroy(m_bufferPool.outputSurfaces[i]); ++ CheckStatus(vdp_st, __LINE__); ++ ++ m_bufferPool.outputSurfaces[i] = VDP_INVALID_HANDLE; ++ ++ CLog::Log(LOGDEBUG, "VDPAU::PreCleanup - released output surface"); ++ } ++ ++} ++ + void COutput::InitMixer() + { + for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index 471ad68..e33b6f5 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -286,6 +286,7 @@ class CMixer : private CThread + virtual ~CMixer(); + void Start(); + void Dispose(); ++ bool IsActive(); + CMixerControlProtocol m_controlPort; + CMixerDataProtocol m_dataPort; + protected: +@@ -454,6 +455,7 @@ class COutput : private CThread + bool DestroyGlxContext(); + bool EnsureBufferPool(); + void ReleaseBufferPool(); ++ void PreCleanup(); + void InitMixer(); + bool GLInit(); + void GLMapSurfaces(); +-- +1.7.10 + + +From 046ece78a7cb25c9d9feca0d907c4547943843c5 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Tue, 5 Mar 2013 17:01:53 +0100 +Subject: [PATCH 86/88] LinuxRendererGL: do not upscale if source equals dest + +--- + xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +index 0bb924b..b5b0838 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +@@ -860,6 +860,14 @@ void CLinuxRendererGL::UpdateVideoFilter() + m_scalingMethod = VS_SCALINGMETHOD_LINEAR; + } + ++ // no need to scale if source equals dest ++ bool scale = ((float)m_sourceHeight != m_destRect.Height()) || ++ ((float)m_sourceWidth != m_destRect.Width()); ++ if(!scale) ++ { ++ m_scalingMethod = VS_SCALINGMETHOD_LINEAR; ++ } ++ + if (m_pVideoFilterShader) + { + m_pVideoFilterShader->Free(); +-- +1.7.10 + + +From 1ac2908aa3fd49bdbfd7e271ddd3a8f6c552929c Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Wed, 6 Mar 2013 07:35:10 +0100 +Subject: [PATCH 87/88] vdpau: set deinterlacing method to auto, if default + method not supported + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 38ef375..b69ae8c 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -2091,13 +2091,15 @@ void CMixer::InitCycle() + } + else + { +- CLog::Log(LOGERROR, "CMixer::%s - interlace method not supported", __FUNCTION__); ++ CLog::Log(LOGERROR, "CMixer::%s - interlace method: %d not supported, setting to AUTO", __FUNCTION__, method); + m_mixersteps = 1; + m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; + m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU; + m_mixerInput[1].DVDPic.iFlags &= ~(DVP_FLAG_TOP_FIELD_FIRST | + DVP_FLAG_REPEAT_TOP_FIELD | + DVP_FLAG_INTERLACED); ++ ++ g_settings.m_currentVideoSettings.m_InterlaceMethod = VS_INTERLACEMETHOD_AUTO; + } + } + else +-- +1.7.10 + + +From 1f1e576daead67677f3cacbb592f47129ad6f5f5 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 9 Mar 2013 14:04:15 +0100 +Subject: [PATCH 88/88] buffering: do not drop in RenderManager + +--- + xbmc/cores/VideoRenderers/RenderManager.cpp | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp +index c99a555..bc764da 100644 +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp ++++ b/xbmc/cores/VideoRenderers/RenderManager.cpp +@@ -1067,18 +1067,18 @@ void CXBMCRenderManager::PrepareNextRender() + + // look ahead in the queue + // if the next frame is already late, skip the one we are about to render +- while (idx != m_iOutputRenderBuffer) +- { +- int idx_next = (idx + 1) % m_iNumRenderBuffers; +- if (m_renderBuffers[idx_next].timestamp <= clocktime) +- { +- FlipRenderBuffer(); +- idx = GetNextRenderBufferIndex(); +- CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); +- } +- else +- break; +- } ++// while (idx != m_iOutputRenderBuffer) ++// { ++// int idx_next = (idx + 1) % m_iNumRenderBuffers; ++// if (m_renderBuffers[idx_next].timestamp <= clocktime) ++// { ++// FlipRenderBuffer(); ++// idx = GetNextRenderBufferIndex(); ++// CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); ++// } ++// else ++// break; ++// } + + double presenttime = m_renderBuffers[idx].timestamp; + -- 1.7.10 From de08817d2154cabc1d78c7ff6c393cc0c9882d9d Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 13:27:16 +0100 Subject: [PATCH 10/14] xbmc: add PR2395 Signed-off-by: Stephan Raue --- .../xbmc/patches/xbmc-990.28-PR2395.patch | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch b/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch new file mode 100644 index 0000000000..e5cc23d133 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch @@ -0,0 +1,31 @@ +From 7a9939f714bcafe8d6616bfbdeb87d2e4b1f24e8 Mon Sep 17 00:00:00 2001 +From: pitpompej +Date: Fri, 8 Mar 2013 21:05:31 +0100 +Subject: [PATCH] Prevent timeout error because of waiting for port settings + change event on the wrong pipeline object when using + deinterlace mode + +--- + xbmc/cores/omxplayer/OMXVideo.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp +index d4b8fbf..15bc8fa 100644 +--- a/xbmc/cores/omxplayer/OMXVideo.cpp ++++ b/xbmc/cores/omxplayer/OMXVideo.cpp +@@ -885,10 +885,10 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) + { + CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); + } +- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); ++ omx_err = m_omx_image_fx.WaitForEvent(OMX_EventPortSettingsChanged); + if(omx_err != OMX_ErrorNone) + { +- CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); + } + port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); + omx_err = m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition, &port_image); +-- +1.7.10 + From 6b5dc87d62ec57d60c45b126f79be08eac52f291 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 13:39:10 +0100 Subject: [PATCH 11/14] rpcbind: silence rpcbind output Signed-off-by: Stephan Raue --- packages/network/rpcbind/init.d/22_rpcbind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/network/rpcbind/init.d/22_rpcbind b/packages/network/rpcbind/init.d/22_rpcbind index d0e1c719bf..569f6cfbb6 100644 --- a/packages/network/rpcbind/init.d/22_rpcbind +++ b/packages/network/rpcbind/init.d/22_rpcbind @@ -23,4 +23,4 @@ # runlevels: openelec, textmode progress "start rpcbind daemon" - rpcbind \ No newline at end of file + rpcbind > /dev/null 2>&1 & \ No newline at end of file From 09b0a8d9e124ed1544732849b392cbf05c826228 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 14:32:15 +0100 Subject: [PATCH 12/14] projects/RPi/xbmc: cleanup advancedsettings.xml, use cachemembuffersize=2097152 Signed-off-by: Stephan Raue --- projects/RPi/xbmc/advancedsettings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/projects/RPi/xbmc/advancedsettings.xml b/projects/RPi/xbmc/advancedsettings.xml index f40e0124fc..78b6378b47 100644 --- a/projects/RPi/xbmc/advancedsettings.xml +++ b/projects/RPi/xbmc/advancedsettings.xml @@ -1,7 +1,5 @@ - cputemp - cputemp false false @@ -21,7 +19,7 @@ - 5282880 + 2097152 From 030f03896f3b88df490f6ef830aaf85e1391ee89 Mon Sep 17 00:00:00 2001 From: Daniel Forsberg Date: Sun, 10 Mar 2013 14:14:21 +0100 Subject: [PATCH 13/14] fix PS1 line wrapping, removed username. --- packages/sysutils/bash/profile.d/shell.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sysutils/bash/profile.d/shell.conf b/packages/sysutils/bash/profile.d/shell.conf index 652518d396..49472f63d0 100644 --- a/packages/sysutils/bash/profile.d/shell.conf +++ b/packages/sysutils/bash/profile.d/shell.conf @@ -23,7 +23,7 @@ # evironment variables that are not user defined. ################################################################################ -PS1='\[\e[0;32m\]\u\e[1;30m@\e[1;32m\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] ' +PS1="\[\033]0;\h: \w\007\]\[\e[1;32m\]\h\[\e[1;32m\]:\[\e[1;34m\]\w \[\e[0m\]\\$ " export PS1 case "$TERM" in @@ -43,4 +43,4 @@ case "$TERM" in ;; esac -export TERM \ No newline at end of file +export TERM From 12cfeb37a73a3776e350f54a56e92fdbf89bc337 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 18:06:11 +0100 Subject: [PATCH 14/14] xbmc: fix XVBA/VDPAU patch Signed-off-by: Stephan Raue --- .../xbmc-995.01-xvba_support-1f1e576.patch | 20535 ++++++---------- 1 file changed, 7611 insertions(+), 12924 deletions(-) diff --git a/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch b/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch index 45a76f534a..704449ffe0 100644 --- a/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch +++ b/packages/mediacenter/xbmc/patches/xbmc-995.01-xvba_support-1f1e576.patch @@ -1,1367 +1,1045 @@ -From 7a1298aa773b8a098ca2589dcccebdda46b4995f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:03:31 +0200 -Subject: [PATCH 01/88] VideoRenerers: add buffering - ---- - xbmc/Application.cpp | 3 + - xbmc/cores/IPlayer.h | 2 + - xbmc/cores/VideoRenderers/BaseRenderer.h | 5 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 41 ++-- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 13 +- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 8 +- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 4 +- - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 24 +- - xbmc/cores/VideoRenderers/OverlayRenderer.h | 9 +- - xbmc/cores/VideoRenderers/RenderManager.cpp | 294 +++++++++++++++++++---- - xbmc/cores/VideoRenderers/RenderManager.h | 63 ++++- - xbmc/cores/VideoRenderers/WinRenderer.cpp | 8 +- - xbmc/cores/VideoRenderers/WinRenderer.h | 2 +- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 5 + - xbmc/cores/dvdplayer/DVDPlayer.h | 2 + - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 34 ++- - 16 files changed, 417 insertions(+), 100 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 46b2fde..efb3ac0 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2371,7 +2371,10 @@ void CApplication::Render() - m_lastFrameTime = XbmcThreads::SystemClockMillis(); - - if (flip) -+ { - g_graphicsContext.Flip(dirtyRegions); -+ g_renderManager.NotifyDisplayFlip(); -+ } - CTimeUtils::UpdateFrameTime(flip); - - g_TextureManager.FreeUnusedTextures(); -diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h -index f2aa227..eb654ec 100644 ---- a/xbmc/cores/IPlayer.h -+++ b/xbmc/cores/IPlayer.h -@@ -229,6 +229,8 @@ class IPlayer - */ - virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; - -+ virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; -+ - protected: - IPlayerCallback& m_callback; - }; -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index 81d21d8..aa1e4ae 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -80,10 +80,13 @@ class CBaseRenderer - void GetVideoRect(CRect &source, CRect &dest); - float GetAspectRatio() const; - -- virtual bool AddVideoPicture(DVDVideoPicture* picture) { return false; } -+ virtual bool AddVideoPicture(DVDVideoPicture* picture, int index) { return false; } - virtual void Flush() {}; - - virtual unsigned int GetProcessorSize() { return 0; } -+ virtual unsigned int GetMaxBufferSize() { return 0; } -+ virtual void SetBufferSize(int numBuffers) { } -+ virtual void ReleaseBuffer(int idx) { } - - virtual bool Supports(ERENDERFEATURE feature) { return false; } - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 1cf52d3..b32a7ea 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -235,14 +235,6 @@ bool CLinuxRendererGL::ValidateRenderer() - return true; - } - -- --void CLinuxRendererGL::ManageTextures() --{ -- m_NumYV12Buffers = 2; -- //m_iYV12RenderBuffer = 0; -- return; --} -- - bool CLinuxRendererGL::ValidateRenderTarget() - { - if (!m_bValidated) -@@ -603,13 +595,28 @@ void CLinuxRendererGL::Flush() - glFinish(); - m_bValidated = false; - m_fbo.fbo.Cleanup(); -+ m_iYV12RenderBuffer = 0; -+} -+ -+void CLinuxRendererGL::ReleaseBuffer(int idx) -+{ -+ YUVBUFFER &buf = m_buffers[idx]; -+#ifdef HAVE_LIBVDPAU -+ SAFE_RELEASE(buf.vdpau); -+#endif -+#ifdef HAVE_LIBVA -+ buf.vaapi.surface.reset(); -+#endif -+#ifdef TARGET_DARWIN -+ if (buf.cvBufferRef) -+ CVBufferRelease(buf.cvBufferRef); -+#endif - } - - void CLinuxRendererGL::Update(bool bPauseDrawing) - { - if (!m_bConfigured) return; - ManageDisplay(); -- ManageTextures(); - } - - void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) -@@ -625,7 +632,6 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - } - - ManageDisplay(); -- ManageTextures(); - - g_graphicsContext.BeginPaint(); - -@@ -782,7 +788,6 @@ unsigned int CLinuxRendererGL::PreInit() - m_resolution = RES_DESKTOP; - - m_iYV12RenderBuffer = 0; -- m_NumYV12Buffers = 2; - - m_formats.push_back(RENDER_FMT_YUV420P); - GLint size; -@@ -2465,7 +2470,7 @@ void CLinuxRendererGL::UploadVAAPITexture(int index) - || status == VA_STATUS_ERROR_INVALID_DISPLAY) - { - va.display->lost(true); -- for(int i = 0; i < NUM_BUFFERS; i++) -+ for(int i = 0; i < m_NumYV12Buffers; i++) - { - m_buffers[i].vaapi.display.reset(); - m_buffers[i].vaapi.surface.reset(); -@@ -3412,26 +3417,26 @@ void CLinuxRendererGL::UnBindPbo(YUVBUFFER& buff) - } - - #ifdef HAVE_LIBVDPAU --void CLinuxRendererGL::AddProcessor(CVDPAU* vdpau) -+void CLinuxRendererGL::AddProcessor(CVDPAU* vdpau, int index) - { -- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; -+ YUVBUFFER &buf = m_buffers[index]; - SAFE_RELEASE(buf.vdpau); - buf.vdpau = (CVDPAU*)vdpau->Acquire(); - } - #endif - - #ifdef HAVE_LIBVA --void CLinuxRendererGL::AddProcessor(VAAPI::CHolder& holder) -+void CLinuxRendererGL::AddProcessor(VAAPI::CHolder& holder, int index) - { -- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; -+ YUVBUFFER &buf = m_buffers[index]; - buf.vaapi.surface = holder.surface; - } - #endif - - #ifdef TARGET_DARWIN --void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef) -+void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) - { -- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; -+ YUVBUFFER &buf = m_buffers[index]; - if (buf.cvBufferRef) - CVBufferRelease(buf.cvBufferRef); - buf.cvBufferRef = cvBufferRef; -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index acebfe0..7c9fcae 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -44,7 +44,7 @@ - namespace Shaders { class BaseVideoFilterShader; } - namespace VAAPI { struct CHolder; } - --#define NUM_BUFFERS 3 -+#define NUM_BUFFERS 10 - - - #undef ALIGN -@@ -138,15 +138,19 @@ class CLinuxRendererGL : public CBaseRenderer - virtual void UnInit(); - virtual void Reset(); /* resets renderer after seek for example */ - virtual void Flush(); -+ virtual void ReleaseBuffer(int idx); -+ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } -+ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } -+ virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } - - #ifdef HAVE_LIBVDPAU -- virtual void AddProcessor(CVDPAU* vdpau); -+ virtual void AddProcessor(CVDPAU* vdpau, int index); - #endif - #ifdef HAVE_LIBVA -- virtual void AddProcessor(VAAPI::CHolder& holder); -+ virtual void AddProcessor(VAAPI::CHolder& holder, int index); - #endif - #ifdef TARGET_DARWIN -- virtual void AddProcessor(struct __CVBuffer *cvBufferRef); -+ virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); - #endif - - virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); -@@ -168,7 +172,6 @@ class CLinuxRendererGL : public CBaseRenderer - void DrawBlackBars(); - - bool ValidateRenderer(); -- virtual void ManageTextures(); - int NextYV12Texture(); - virtual bool ValidateRenderTarget(); - virtual void LoadShaders(int field=FIELD_FULL); -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index cb0939f..2a59e2b 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -1982,16 +1982,16 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod() - } - - #ifdef HAVE_LIBOPENMAX --void CLinuxRendererGLES::AddProcessor(COpenMax* openMax, DVDVideoPicture *picture) -+void CLinuxRendererGLES::AddProcessor(COpenMax* openMax, DVDVideoPicture *picture, int index) - { -- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; -+ YUVBUFFER &buf = m_buffers[index]; - buf.openMaxBuffer = picture->openMaxBuffer; - } - #endif - #ifdef HAVE_VIDEOTOOLBOXDECODER --void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef) -+void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef, int index) - { -- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; -+ YUVBUFFER &buf = m_buffers[index]; - if (buf.cvBufferRef) - CVBufferRelease(buf.cvBufferRef); - buf.cvBufferRef = cvBufferRef; -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index 76b5437..c6b69db 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -153,10 +153,10 @@ class CLinuxRendererGLES : public CBaseRenderer - virtual std::vector SupportedFormats() { return m_formats; } - - #ifdef HAVE_LIBOPENMAX -- virtual void AddProcessor(COpenMax* openMax, DVDVideoPicture *picture); -+ virtual void AddProcessor(COpenMax* openMax, DVDVideoPicture *picture, int index); - #endif - #ifdef HAVE_VIDEOTOOLBOXDECODER -- virtual void AddProcessor(struct __CVBuffer *cvBufferRef); -+ virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); - #endif - - protected: -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index 19d2d7d..f7f74ce 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -89,29 +89,32 @@ long COverlayMainThread::Release() - CRenderer::CRenderer() - { - m_render = 0; -- m_decode = (m_render + 1) % 2; - } - - CRenderer::~CRenderer() - { -- for(int i = 0; i < 2; i++) -+ for(int i = 0; i < 10; i++) - Release(m_buffers[i]); - } - --void CRenderer::AddOverlay(CDVDOverlay* o, double pts) -+void CRenderer::AddOverlay(CDVDOverlay* o, double pts, int index) - { - CSingleLock lock(m_section); - -+ m_decode = index; -+ - SElement e; - e.pts = pts; - e.overlay_dvd = o->Acquire(); - m_buffers[m_decode].push_back(e); - } - --void CRenderer::AddOverlay(COverlay* o, double pts) -+void CRenderer::AddOverlay(COverlay* o, double pts, int index) - { - CSingleLock lock(m_section); - -+ m_decode = index; -+ - SElement e; - e.pts = pts; - e.overlay = o->Acquire(); -@@ -151,20 +154,23 @@ void CRenderer::Flush() - { - CSingleLock lock(m_section); - -- for(int i = 0; i < 2; i++) -+ for(int i = 0; i < m_iNumBuffers; i++) - Release(m_buffers[i]); - -+ m_render = 0; - Release(m_cleanup); - } - - void CRenderer::Flip() - { - CSingleLock lock(m_section); -+ m_render = (m_render + 1) % m_iNumBuffers; -+} - -- m_render = m_decode; -- m_decode =(m_decode + 1) % 2; -- -- Release(m_buffers[m_decode]); -+void CRenderer::ReleaseBuffer(int idx) -+{ -+ CSingleLock lock(m_section); -+ Release(m_buffers[idx]); - } - - void CRenderer::Render() -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index d2175d8..0921fc5 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.h -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -92,12 +92,14 @@ - CRenderer(); - ~CRenderer(); - -- void AddOverlay(CDVDOverlay* o, double pts); -- void AddOverlay(COverlay* o, double pts); -+ void AddOverlay(CDVDOverlay* o, double pts, int index); -+ void AddOverlay(COverlay* o, double pts, int index); - void AddCleanup(COverlay* o); - void Flip(); - void Render(); - void Flush(); -+ void SetNumBuffers(int numBuffers) { m_iNumBuffers = numBuffers; } -+ void ReleaseBuffer(int idx); - - protected: - -@@ -124,7 +126,8 @@ - void Release(SElementV& list); - - CCriticalSection m_section; -- SElementV m_buffers[2]; -+ SElementV m_buffers[10]; -+ int m_iNumBuffers; - int m_decode; - int m_render; - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index d22287d..c13f83d 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -28,6 +28,7 @@ - #include "utils/MathUtils.h" - #include "threads/SingleLock.h" - #include "utils/log.h" -+#include "utils/TimeUtils.h" - - #include "Application.h" - #include "ApplicationMessenger.h" -@@ -227,7 +228,7 @@ CStdString CXBMCRenderManager::GetVSyncState() - return state; - } - --bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation) -+bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering) - { - /* make sure any queued frame was fully presented */ - double timeout = m_presenttime + 0.1; -@@ -247,6 +248,9 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - return false; - } - -+ // set buffering -+ m_bCodecSupportsBuffering = buffering; -+ - bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation); - if(result) - { -@@ -261,6 +265,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_bReconfigured = true; - m_presentstep = PRESENT_IDLE; - m_presentevent.Set(); -+ ResetRenderBuffer(); - } - - return result; -@@ -292,8 +297,12 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - if (!m_pRenderer) - return; - -+ if (m_presentstep == PRESENT_IDLE) -+ PrepareNextRender(); -+ - if(m_presentstep == PRESENT_FLIP) - { -+ FlipRenderBuffer(); - m_overlays.Flip(); - m_pRenderer->FlipPage(m_presentsource); - m_presentstep = PRESENT_FRAME; -@@ -338,6 +347,10 @@ unsigned int CXBMCRenderManager::PreInit() - - UpdateDisplayLatency(); - -+ m_bUseBuffering = false; -+ m_bCodecSupportsBuffering = true; -+ ResetRenderBuffer(); -+ - return m_pRenderer->PreInit(); - } - -@@ -366,7 +379,9 @@ bool CXBMCRenderManager::Flush() - - CRetakeLock lock(m_sharedSection); - m_pRenderer->Flush(); -+ m_overlays.Flush(); - m_flushEvent.Set(); -+ ResetRenderBuffer(); - } - else - { -@@ -534,25 +549,21 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) - m_pRenderer->SetViewMode(iViewMode); - } - --void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) -+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/, int speed /*= 1000*/) - { -- if(timestamp - GetPresentTime() > MAXPRESENTDELAY) -- timestamp = GetPresentTime() + MAXPRESENTDELAY; -- -- /* can't flip, untill timestamp */ -- if(!g_graphicsContext.IsFullScreenVideo()) -- WaitPresentTime(timestamp); -- -- /* make sure any queued frame was fully presented */ -- double timeout = m_presenttime + 1.0; -- while(m_presentstep != PRESENT_IDLE && !bStop) -+ if (!m_bUseBuffering) - { -- if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) -+ /* make sure any queued frame was fully presented */ -+ double timeout = m_presenttime + 1.0; -+ while(m_presentstep != PRESENT_IDLE && !bStop) - { -- CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for previous frame"); -- return; -+ if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) -+ { -+ CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for previous frame"); -+ return; -+ } - } -- }; -+ } - - if(bStop) - return; -@@ -560,58 +571,67 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - { CRetakeLock lock(m_sharedSection); - if(!m_pRenderer) return; - -- m_presenttime = timestamp; -- m_presentfield = sync; -- m_presentstep = PRESENT_FLIP; -- m_presentsource = source; -+ double presenttime = timestamp; -+ EFIELDSYNC presentfield = sync; -+ EPRESENTMETHOD presentmethod; -+ - EDEINTERLACEMODE deinterlacemode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; - EINTERLACEMETHOD interlacemethod = AutoInterlaceMethodInternal(g_settings.m_currentVideoSettings.m_InterlaceMethod); - - bool invert = false; - - if (deinterlacemode == VS_DEINTERLACEMODE_OFF) -- m_presentmethod = PRESENT_METHOD_SINGLE; -+ presentmethod = PRESENT_METHOD_SINGLE; - else - { -- if (deinterlacemode == VS_DEINTERLACEMODE_AUTO && m_presentfield == FS_NONE) -- m_presentmethod = PRESENT_METHOD_SINGLE; -+ if (deinterlacemode == VS_DEINTERLACEMODE_AUTO && presentfield == FS_NONE) -+ presentmethod = PRESENT_METHOD_SINGLE; - else - { -- if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BLEND) m_presentmethod = PRESENT_METHOD_BLEND; -- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE) m_presentmethod = PRESENT_METHOD_WEAVE; -- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE_INVERTED) { m_presentmethod = PRESENT_METHOD_WEAVE ; invert = true; } -- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB) m_presentmethod = PRESENT_METHOD_BOB; -- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB_INVERTED) { m_presentmethod = PRESENT_METHOD_BOB; invert = true; } -- else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BOB) m_presentmethod = PRESENT_METHOD_BOB; -- else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BEST) m_presentmethod = PRESENT_METHOD_BOB; -- else m_presentmethod = PRESENT_METHOD_SINGLE; -+ if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BLEND) presentmethod = PRESENT_METHOD_BLEND; -+ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE) presentmethod = PRESENT_METHOD_WEAVE; -+ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE_INVERTED) { presentmethod = PRESENT_METHOD_WEAVE ; invert = true; } -+ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB) presentmethod = PRESENT_METHOD_BOB; -+ 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 presentmethod = PRESENT_METHOD_SINGLE; - - /* default to odd field if we want to deinterlace and don't know better */ -- if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && m_presentfield == FS_NONE) -- m_presentfield = FS_TOP; -+ if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && presentfield == FS_NONE) -+ presentfield = FS_TOP; - - /* invert present field */ - if(invert) - { -- if( m_presentfield == FS_BOT ) -- m_presentfield = FS_TOP; -+ if( presentfield == FS_BOT ) -+ presentfield = FS_TOP; - else -- m_presentfield = FS_BOT; -+ presentfield = FS_BOT; - } - } - } - -+ FlipFreeBuffer(); -+ m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; -+ m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; -+ m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; -+ m_speed = speed; - } - - g_application.NewFrame(); -- /* wait untill render thread have flipped buffers */ -- timeout = m_presenttime + 1.0; -- while(m_presentstep == PRESENT_FLIP && !bStop) -+ -+ if (!m_bUseBuffering) - { -- if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) -+ /* wait untill render thread have flipped buffers */ -+ double timeout = m_presenttime + 1.0; -+ while(m_presentstep == PRESENT_FLIP && !bStop) - { -- CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for flip to complete"); -- return; -+ if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) -+ { -+ CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for flip to complete"); -+ return; -+ } - } - } - } -@@ -675,8 +695,12 @@ void CXBMCRenderManager::Present() - if (!m_pRenderer) - return; - -+ if (m_presentstep == PRESENT_IDLE) -+ PrepareNextRender(); -+ - if(m_presentstep == PRESENT_FLIP) - { -+ FlipRenderBuffer(); - m_overlays.Flip(); - m_pRenderer->FlipPage(m_presentsource); - m_presentstep = PRESENT_FRAME; -@@ -800,11 +824,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - if (!m_pRenderer) - return -1; - -- if(m_pRenderer->AddVideoPicture(&pic)) -+ if(m_pRenderer->AddVideoPicture(&pic, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers)) - return 1; - - YV12Image image; -- int index = m_pRenderer->GetImage(&image); -+ int index = m_pRenderer->GetImage(&image, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); - - if(index < 0) - return index; -@@ -830,19 +854,19 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - } - #ifdef HAVE_LIBVDPAU - else if(pic.format == RENDER_FMT_VDPAU) -- m_pRenderer->AddProcessor(pic.vdpau); -+ m_pRenderer->AddProcessor(pic.vdpau, index); - #endif - #ifdef HAVE_LIBOPENMAX - else if(pic.format == RENDER_FMT_OMXEGL) -- m_pRenderer->AddProcessor(pic.openMax, &pic); -+ m_pRenderer->AddProcessor(pic.openMax, &pic, index); - #endif - #ifdef TARGET_DARWIN - else if(pic.format == RENDER_FMT_CVBREF) -- m_pRenderer->AddProcessor(pic.cvBufferRef); -+ m_pRenderer->AddProcessor(pic.cvBufferRef, index); - #endif - #ifdef HAVE_LIBVA - else if(pic.format == RENDER_FMT_VAAPI) -- m_pRenderer->AddProcessor(*pic.vaapi); -+ m_pRenderer->AddProcessor(*pic.vaapi, index); - #endif - m_pRenderer->ReleaseImage(index, false); - -@@ -904,3 +928,177 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO - - return mInt; - } -+ -+int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) -+{ -+ CSharedLock lock(m_sharedSection); -+ if (!m_pRenderer) -+ return -1; -+ -+ double maxwait = GetPresentTime() + (float)timeout/1000; -+ while(!HasFreeBuffer() && !bStop) -+ { -+ lock.Leave(); -+ m_flipEvent.WaitMSec(std::min(50, timeout)); -+ if(GetPresentTime() > maxwait && !bStop) -+ { -+ if (timeout != 0) -+ CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); -+ return -1; -+ } -+ lock.Enter(); -+ } -+ lock.Leave(); -+ -+ if (bStop) -+ return -1; -+ -+ return 1; -+} -+ -+int CXBMCRenderManager::GetNextRenderBufferIndex() -+{ -+ if (m_iOutputRenderBuffer == m_iCurrentRenderBuffer) -+ return -1; -+ return (m_iCurrentRenderBuffer + 1) % m_iNumRenderBuffers; -+} -+ -+void CXBMCRenderManager::FlipRenderBuffer() -+{ -+ m_iCurrentRenderBuffer = GetNextRenderBufferIndex(); -+} -+ -+int CXBMCRenderManager::FlipFreeBuffer() -+{ -+ // See "Render Buffer State Description" in header for information. -+ if (HasFreeBuffer()) -+ { -+ m_bAllRenderBuffersDisplayed = false; -+ m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; -+ return m_iOutputRenderBuffer; -+ } -+} -+ -+bool CXBMCRenderManager::HasFreeBuffer() -+{ -+ if (!m_bUseBuffering) -+ { -+ if (m_iOutputRenderBuffer != m_iCurrentRenderBuffer) -+ return false; +diff -Naur xbmc-12.0.4/configure.in xbmc-12.0.4.patch/configure.in +--- xbmc-12.0.4/configure.in 2013-03-08 13:01:45.000000000 +0100 ++++ xbmc-12.0.4.patch/configure.in 2013-03-10 13:00:12.321988177 +0100 +@@ -124,6 +124,8 @@ + vaapi_disabled="== VAAPI support manually disabled. ==" + crystalhd_not_found="== Could not find libcrystalhd. CrystalHD support disabled. ==" + crystalhd_disabled="== CrystalHD support manually disabled. ==" ++xvba_not_found="== Could not find amdxvba.h. XVBA support disabled. ==" ++xvba_disabled="== XVBA support manually disabled. ==" + vdadecoder_enabled="== VDADecoder support enabled. ==" + vdadecoder_disabled="== VDADecoder support manually disabled. ==" + vtbdecoder_enabled="== VTBDecoder support enabled. ==" +@@ -247,6 +249,12 @@ + [enable CrystalHD decoding (default is auto)])], + [use_crystalhd=$enableval], + [use_crystalhd=auto]) ++ ++AC_ARG_ENABLE([xvba], ++ [AS_HELP_STRING([--enable-xvba], ++ [enable XVBA decoding (default is auto)])], ++ [use_xvba=$enableval], ++ [use_xvba=auto]) + + AC_ARG_ENABLE([vdadecoder], + [AS_HELP_STRING([--enable-vdadecoder], +@@ -1751,6 +1759,38 @@ + USE_CRYSTALHD=0 + fi + ++# XVBA ++if test "x$use_xvba" != "xno"; then ++ if test "$host_vendor" = "apple" ; then ++ if test "x$use_xvba" = "xyes"; then ++ AC_MSG_ERROR([XVBA not supported on this platform]) + else -+ return true; -+ } -+ -+ int outputPlus1 = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; -+ if ((m_iOutputRenderBuffer == m_iDisplayedRenderBuffer && !m_bAllRenderBuffersDisplayed) -+ || outputPlus1 == m_iCurrentRenderBuffer) -+ return false; ++ use_xvba="no" ++ AC_MSG_NOTICE($xvba_disabled) ++ fi ++ USE_XVBA=0 + else -+ return true; -+} ++ initial_val=$use_xvba ++ AC_CHECK_HEADER([amd/amdxvba.h],, use_xvba=no, [#include ]) + -+void CXBMCRenderManager::ResetRenderBuffer() -+{ -+ m_iNumRenderBuffers = m_pRenderer->GetMaxBufferSize(); -+ m_iNumRenderBuffers = std::min(5, m_iNumRenderBuffers); -+ m_iNumRenderBuffers = std::max(2, m_iNumRenderBuffers); ++ if test "x$use_xvba" = "xno"; then ++ if test "x$initial_val" = "xyes"; then ++ AC_MSG_ERROR($xvba_not_found) ++ else ++ AC_MSG_RESULT($xvba_not_found) ++ fi ++ USE_XVBA=0 ++ else ++ AC_DEFINE([HAVE_LIBXVBA], [1], [Define to 1 if you have the 'xvba' header (amdxvba.h)]) ++ USE_XVBA=1 ++ fi ++ fi ++else ++ AC_MSG_NOTICE($xvba_disabled) ++ USE_XVBA=0 ++fi + -+ if (!m_bCodecSupportsBuffering) -+ m_iNumRenderBuffers = 2; + -+ CLog::Log(LOGNOTICE,"CXBMCRenderManager::ResetRenderBuffer - using %d render buffers", m_iNumRenderBuffers); -+ m_overlays.SetNumBuffers(m_iNumRenderBuffers); -+ m_pRenderer->SetBufferSize(m_iNumRenderBuffers); + # VDADecoder + if test "x$use_vdadecoder" != "xno"; then + if test "$host_vendor" = "apple" ; then +@@ -1962,6 +2002,12 @@ + final_message="$final_message\n CrystalHD:\tNo" + fi + ++if test "x$use_xvba" != "xno"; then ++ final_message="$final_message\n XVBA:\t\tYes" ++else ++ final_message="$final_message\n XVBA:\t\tNo" ++fi + -+ m_iCurrentRenderBuffer = 0; -+ m_iOutputRenderBuffer = 0; -+ m_iDisplayedRenderBuffer = 0; -+ m_bAllRenderBuffersDisplayed = true; -+ m_sleeptime = 1.0; -+ m_presentPts = DVD_NOPTS_VALUE; -+ m_speed = 0; -+} -+ -+void CXBMCRenderManager::PrepareNextRender() -+{ -+ int idx = GetNextRenderBufferIndex(); -+ if (idx < 0) -+ { -+ if (m_speed >= DVD_PLAYSPEED_NORMAL && g_graphicsContext.IsFullScreenVideo()) -+ CLog::Log(LOGDEBUG,"%s no buffer, out: %d, current: %d, display: %d", -+ __FUNCTION__, m_iOutputRenderBuffer, m_iCurrentRenderBuffer, m_iDisplayedRenderBuffer); -+ return; -+ } -+ -+ double iClockSleep, iPlayingClock, iCurrentClock; -+ if (g_application.m_pPlayer) -+ iPlayingClock = g_application.m_pPlayer->GetClock(iCurrentClock, false); -+ else -+ iPlayingClock = iCurrentClock = 0; -+ -+ iClockSleep = m_renderBuffers[idx].pts - iPlayingClock; -+ -+ if (m_speed) -+ iClockSleep = iClockSleep * DVD_PLAYSPEED_NORMAL / m_speed; -+ -+ double presenttime = (iCurrentClock + iClockSleep) / DVD_TIME_BASE; -+ double clocktime = iCurrentClock / DVD_TIME_BASE; -+ if(presenttime - clocktime > MAXPRESENTDELAY) -+ presenttime = clocktime + MAXPRESENTDELAY; -+ -+ m_sleeptime = presenttime - clocktime; -+ double frametime = 1 / g_graphicsContext.GetFPS(); -+ -+ if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) -+ { -+ m_presentPts = m_renderBuffers[idx].pts; -+ m_presenttime = presenttime; -+ m_presentmethod = m_renderBuffers[idx].presentmethod; -+ m_presentfield = m_renderBuffers[idx].presentfield; -+ m_presentstep = PRESENT_FLIP; -+ m_presentsource = idx; -+ } -+} -+ -+void CXBMCRenderManager::EnableBuffering(bool enable) -+{ -+ CRetakeLock lock(m_sharedSection); -+ -+ if (m_iNumRenderBuffers < 3) -+ return; -+ -+ m_bUseBuffering = enable; -+ if (!m_bUseBuffering) -+ m_iOutputRenderBuffer = m_iCurrentRenderBuffer; -+ -+ CLog::Log(LOGDEBUG, "CXBMCRenderManager::EnableBuffering - %d", m_bUseBuffering); -+} -+ -+void CXBMCRenderManager::DiscardBuffer() -+{ -+ CRetakeLock lock(m_sharedSection); -+ m_iOutputRenderBuffer = m_iCurrentRenderBuffer; -+} -+ -+void CXBMCRenderManager::NotifyDisplayFlip() -+{ -+ CRetakeLock lock(m_sharedSection); -+ if (!m_pRenderer) -+ return; -+ -+ if (m_iNumRenderBuffers >= 3) -+ { -+ int last = m_iDisplayedRenderBuffer; -+ m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; -+ -+ if (last != m_iDisplayedRenderBuffer -+ && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) -+ { -+ m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -+ m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); -+ } -+ } -+ -+ lock.Leave(); -+ m_flipEvent.Set(); -+} -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 7fe6bb2..96ab53f 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -31,6 +31,7 @@ - #include "OverlayRenderer.h" + if test "x$use_vdadecoder" != "xno"; then + final_message="$final_message\n VDADecoder:\tYes" + else +@@ -2435,6 +2481,7 @@ + AC_SUBST(USE_VDPAU) + AC_SUBST(USE_VAAPI) + AC_SUBST(USE_CRYSTALHD) ++AC_SUBST(USE_XVBA) + AC_SUBST(USE_LIBSMBCLIENT) + AC_SUBST(USE_LIBNFS) + AC_SUBST(USE_LIBAFPCLIENT) +@@ -2618,6 +2665,7 @@ + `if test "x$use_vdpau" != "xno"; then echo --enable-vdpau; else echo --disable-vdpau; fi` \ + `if test "x$use_vaapi" != "xno"; then echo --enable-vaapi; else echo --disable-vaapi; fi` \ + `if test "$use_optimizations" != "no"; then echo --enable-optimizations; else echo --disable-optimizations; fi` \ ++ `if test "x$use_xvba" != "xno"; then echo --enable-xvba; else echo --disable-xvba; fi` \ + --enable-protocol=http \ + --enable-pthreads \ + --enable-runtime-cpudetect \ +diff -Naur xbmc-12.0.4/language/English/strings.po xbmc-12.0.4.patch/language/English/strings.po +--- xbmc-12.0.4/language/English/strings.po 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/language/English/strings.po 2013-03-10 13:00:12.322988170 +0100 +@@ -895,7 +895,9 @@ + msgid "Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1) (VShift: %2.2f)" + msgstr "" - class CRenderCapture; -+class CDVDClock; +-#empty string with id 246 ++msgctxt "#246" ++msgid "Monitor" ++msgstr "" - namespace DXVA { class CProcessor; } - namespace VAAPI { class CSurfaceHolder; } -@@ -65,12 +66,12 @@ class CXBMCRenderManager - void SetViewMode(int iViewMode); + msgctxt "#247" + msgid "Scripts" +@@ -4369,11 +4371,7 @@ + msgid "VDPAU HQ Upscaling level" + msgstr "" - // Functions called from mplayer -- bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation); -+ bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering = false); - bool IsConfigured(); - - int AddVideoPicture(DVDVideoPicture& picture); - -- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); -+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); - unsigned int PreInit(); - void UnInit(); - bool Flush(); -@@ -78,7 +79,7 @@ class CXBMCRenderManager - void AddOverlay(CDVDOverlay* o, double pts) - { - CSharedLock lock(m_sharedSection); -- m_overlays.AddOverlay(o, pts); -+ m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); - } - - void AddCleanup(OVERLAY::COverlay* o) -@@ -132,6 +133,24 @@ class CXBMCRenderManager - - void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn); - -+ /** -+ * If player uses buffering it has to wait for a buffer before it calls -+ * AddVideoPicture and AddOverlay. It waits for max 50 ms before it returns -1 -+ * in case no buffer is available. Player may call this in a loop and decides -+ * by itself when it wants to drop a frame. -+ * If no buffering is requested in Configure, player does not need to call this, -+ * because FlipPage will block. -+ */ -+ int WaitForBuffer(volatile bool& bStop, int timeout = 100); -+ -+ /** -+ * Called by application right after flip. The buffer which has been rendered to -+ * display becomes available for player to deliver a new frame. -+ */ -+ void NotifyDisplayFlip(); -+ void EnableBuffering(bool enable); -+ void DiscardBuffer(); -+ - protected: - void Render(bool clear, DWORD flags, DWORD alpha); - -@@ -139,6 +158,13 @@ class CXBMCRenderManager - void PresentFields(bool clear, DWORD flags, DWORD alpha); - void PresentBlend(bool clear, DWORD flags, DWORD alpha); - -+ int GetNextRenderBufferIndex(); -+ void FlipRenderBuffer(); -+ int FlipFreeBuffer(); -+ bool HasFreeBuffer(); -+ void ResetRenderBuffer(); -+ void PrepareNextRender(); -+ - EINTERLACEMETHOD AutoInterlaceMethodInternal(EINTERLACEMETHOD mInt); - - bool m_bPauseDrawing; // true if we should pause rendering -@@ -169,6 +195,37 @@ class CXBMCRenderManager - double m_displayLatency; - void UpdateDisplayLatency(); - -+ // Render Buffer State Description: -+ // -+ // Output: is the buffer about to or having its texture prepared for render (ie from output thread). -+ // Cannot go past the "Displayed" buffer (otherwise we will probably overwrite buffers not yet -+ // displayed or even rendered). -+ // Current: is the current buffer being or having been submitted for render to back buffer. -+ // Cannot go past "Output" buffer (else it would be rendering old output). -+ // Displayed: is the buffer that is now considered to be safely copied from back buffer to front buffer -+ // (we assume that after two swap-buffer flips for the same "Current" render buffer that that -+ // buffer will be safe, but otherwise we consider that only the previous-to-"Current" is guaranteed). -+ -+ int m_iCurrentRenderBuffer; -+ int m_iNumRenderBuffers; -+ int m_iOutputRenderBuffer; -+ int m_iDisplayedRenderBuffer; -+ bool m_bAllRenderBuffersDisplayed; -+ bool m_bUseBuffering; -+ bool m_bCodecSupportsBuffering; -+ int m_speed; -+ CEvent m_flipEvent; -+ -+ struct -+ { -+ double pts; -+ EFIELDSYNC presentfield; -+ EPRESENTMETHOD presentmethod; -+ }m_renderBuffers[5]; -+ -+ double m_sleeptime; -+ double m_presentPts; -+ - double m_presenttime; - double m_presentcorr; - double m_presenterr; -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp -index f1d0768..f0f5b2d 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp -@@ -253,12 +253,12 @@ int CWinRenderer::NextYV12Texture() - return -1; - } - --bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture) -+bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture, int index) - { - if (m_renderMethod == RENDER_DXVA) - { -- int source = NextYV12Texture(); -- if(source < 0) -+ int source = index; -+ if(source < 0 || NextYV12Texture() < 0) - return false; - - DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source]; -@@ -274,7 +274,7 @@ int CWinRenderer::GetImage(YV12Image *image, int source, bool readonly) - if( source == AUTOSOURCE ) - source = NextYV12Texture(); - -- if( source < 0 ) -+ if( source < 0 || NextYV12Texture() < 0) - return -1; - - YUVBuffer *buf = (YUVBuffer*)m_VideoBuffers[source]; -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h -index 2ab5684..f493ba7 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.h -+++ b/xbmc/cores/VideoRenderers/WinRenderer.h -@@ -157,7 +157,7 @@ class CWinRenderer : public CBaseRenderer - virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation); - virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false); - virtual void ReleaseImage(int source, bool preserve = false); -- virtual bool AddVideoPicture(DVDVideoPicture* picture); -+ virtual bool AddVideoPicture(DVDVideoPicture* picture, int index); - virtual void FlipPage(int source); - virtual unsigned int PreInit(); - virtual void UnInit(); -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 0cd2510..dfb317f 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -4075,3 +4075,8 @@ bool CDVDPlayer::CachePVRStream(void) const - !g_PVRManager.IsPlayingRecording() && - g_advancedSettings.m_bPVRCacheInDvdPlayer; - } -+ -+double CDVDPlayer::GetClock(double& absolute, bool interpolated) -+{ -+ return m_clock.GetClock(absolute, interpolated); -+} -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index d3c201e..093318e 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -252,6 +252,8 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer - virtual bool SwitchChannel(const PVR::CPVRChannel &channel); - virtual bool CachePVRStream(void) const; - -+ virtual double GetClock(double& absolute, bool interpolated = true); -+ - enum ECacheState - { CACHESTATE_DONE = 0 - , CACHESTATE_FULL // player is filling up the demux queue -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 3008c25..19496a7 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -261,6 +261,7 @@ void CDVDPlayerVideo::OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec) - m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; - m_started = false; - m_codecname = m_pVideoCodec->GetName(); -+ g_renderManager.EnableBuffering(false); - } - - void CDVDPlayerVideo::CloseStream(bool bWaitForBuffers) -@@ -436,6 +437,7 @@ void CDVDPlayerVideo::Process() - picture.iFlags &= ~DVP_FLAG_ALLOCATED; - m_packets.clear(); - m_started = false; -+ g_renderManager.EnableBuffering(false); - } - else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) - { -@@ -448,6 +450,7 @@ void CDVDPlayerVideo::Process() - //we need to recalculate the framerate - //TODO: this needs to be set on a streamchange instead - ResetFrameRateCalc(); -+ g_renderManager.EnableBuffering(false); - - m_stalled = true; - m_started = false; -@@ -586,6 +589,8 @@ void CDVDPlayerVideo::Process() - - m_pVideoCodec->Reset(); - m_packets.clear(); -+ picture.iFlags &= ~DVP_FLAG_ALLOCATED; -+ g_renderManager.DiscardBuffer(); - break; - } - -@@ -700,6 +705,7 @@ void CDVDPlayerVideo::Process() - m_codecname = m_pVideoCodec->GetName(); - m_started = true; - m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO)); -+ g_renderManager.EnableBuffering(true); - } - - // guess next frame pts. iDuration is always valid -@@ -1088,47 +1094,61 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - } - - CStdString formatstr; -+ bool buffering; - - switch(pPicture->format) - { - case RENDER_FMT_YUV420P: - formatstr = "YV12"; -+ buffering = true; - break; - case RENDER_FMT_YUV420P16: - formatstr = "YV12P16"; -+ buffering = true; - break; - case RENDER_FMT_YUV420P10: - formatstr = "YV12P10"; -+ buffering = true; - break; - case RENDER_FMT_NV12: - formatstr = "NV12"; -+ buffering = true; - break; - case RENDER_FMT_UYVY422: - formatstr = "UYVY"; -+ buffering = true; - break; - case RENDER_FMT_YUYV422: - formatstr = "YUY2"; -+ buffering = true; - break; - case RENDER_FMT_VDPAU: - formatstr = "VDPAU"; -+ buffering = true; - break; - case RENDER_FMT_DXVA: - formatstr = "DXVA"; -+ buffering = false; - break; - case RENDER_FMT_VAAPI: - formatstr = "VAAPI"; -+ buffering = false; - break; - case RENDER_FMT_OMXEGL: - formatstr = "OMXEGL"; -+ buffering = false; - break; - case RENDER_FMT_CVBREF: - formatstr = "BGRA"; -+ buffering = false; - break; - case RENDER_FMT_BYPASS: - formatstr = "BYPASS"; -+ buffering = false; - break; - case RENDER_FMT_NONE: - formatstr = "NONE"; -+ buffering = false; - break; - } - -@@ -1139,7 +1159,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - } - - CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str()); -- if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation)) -+ if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation, buffering)) - { - CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); - return EOS_ABORT; -@@ -1317,6 +1337,16 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - mDisplayField = FS_BOT; - } - -+ int buffer = g_renderManager.WaitForBuffer(m_bStop); -+ while (buffer < 0 && !CThread::m_bStop && -+ CDVDClock::GetAbsoluteClock(false) < iCurrentClock + iSleepTime + DVD_MSEC_TO_TIME(500) ) -+ { -+ Sleep(1); -+ buffer = g_renderManager.WaitForBuffer(m_bStop); -+ } -+ if (buffer < 0) -+ return EOS_DROPPED; -+ - ProcessOverlays(pPicture, pts); - AutoCrop(pPicture); - -@@ -1333,7 +1363,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - if (index < 0) - return EOS_DROPPED; - -- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); -+ g_renderManager.FlipPage(CThread::m_bStop, pts, -1, mDisplayField, m_speed); - - return result; - #else --- -1.7.10 - - -From 383daa67f101ff6cc75f0fde39c8bca69a7789ae Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 08:32:18 +0100 -Subject: [PATCH 02/88] add buffering for GLES - ---- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 10 ---------- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 6 ++++-- - 2 files changed, 4 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index 2a59e2b..1bf2f3b 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -135,13 +135,6 @@ - delete m_dllSwScale; - } - --void CLinuxRendererGLES::ManageTextures() --{ -- m_NumYV12Buffers = 2; -- //m_iYV12RenderBuffer = 0; -- return; --} +-msgctxt "#13122" +-msgid "VDPAU Studio level color conversion" +-msgstr "" - - bool CLinuxRendererGLES::ValidateRenderTarget() - { - if (!m_bValidated) -@@ -395,7 +388,6 @@ void CLinuxRendererGLES::Update(bool bPauseDrawing) - { - if (!m_bConfigured) return; - ManageDisplay(); -- ManageTextures(); - } +-#empty strings from id 13123 to 13129 ++#empty strings from id 13122 to 13129 - void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) -@@ -409,7 +401,6 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - if (m_renderMethod & RENDER_BYPASS) - { - ManageDisplay(); -- ManageTextures(); - // 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) -@@ -449,7 +440,6 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - return; + msgctxt "#13130" + msgid "Blank other displays" +@@ -5114,7 +5112,19 @@ + msgid "Play only this" + msgstr "" - ManageDisplay(); -- ManageTextures(); - - g_graphicsContext.BeginPaint(); - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index c6b69db..5bae10d 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -41,7 +41,7 @@ - class COpenMaxVideo; - typedef std::vector Features; - --#define NUM_BUFFERS 3 -+#define NUM_BUFFERS 10 - - - #undef ALIGN -@@ -138,6 +138,9 @@ class CLinuxRendererGLES : public CBaseRenderer - virtual void UnInit(); - virtual void Reset(); /* resets renderer after seek for example */ - virtual void ReorderDrawPoints(); -+ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } -+ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } -+ virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } - - virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - -@@ -162,7 +165,6 @@ class CLinuxRendererGLES : public CBaseRenderer - protected: - virtual void Render(DWORD flags, int index); - -- virtual void ManageTextures(); - int NextYV12Texture(); - virtual bool ValidateRenderTarget(); - virtual void LoadShaders(int field=FIELD_FULL); --- -1.7.10 - - -From 41ee337f40e25843a134c3f1e02d66db733555d0 Mon Sep 17 00:00:00 2001 -From: unknown -Date: Sat, 16 Feb 2013 11:17:02 +0100 -Subject: [PATCH 03/88] WinRenderer: add buffering - ---- - xbmc/cores/VideoRenderers/WinRenderer.cpp | 14 ++++++-------- - xbmc/cores/VideoRenderers/WinRenderer.h | 12 +++++------- - 2 files changed, 11 insertions(+), 15 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp -index f0f5b2d..b6279f2 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp -@@ -103,21 +103,19 @@ static enum PixelFormat PixelFormatFromFormat(ERenderFormat format) - - void CWinRenderer::ManageTextures() - { -- int neededbuffers = 2; -- -- if( m_NumYV12Buffers < neededbuffers ) -+ if( m_NumYV12Buffers < m_neededBuffers ) - { -- for(int i = m_NumYV12Buffers; i neededbuffers ) -+ else if( m_NumYV12Buffers > m_neededBuffers ) - { -- m_NumYV12Buffers = neededbuffers; -+ m_NumYV12Buffers = m_neededBuffers; - m_iYV12RenderBuffer = m_iYV12RenderBuffer % m_NumYV12Buffers; - -- for(int i = m_NumYV12Buffers-1; i>=neededbuffers;i--) -+ for(int i = m_NumYV12Buffers-1; i>=m_neededBuffers;i--) - DeleteYV12Texture(i); - } - } -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h -index f493ba7..b3448ed 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.h -+++ b/xbmc/cores/VideoRenderers/WinRenderer.h -@@ -32,13 +32,7 @@ - #include "cores/VideoRenderers/RenderFlags.h" - #include "cores/VideoRenderers/RenderFormats.h" - --//#define MP_DIRECTRENDERING -- --#ifdef MP_DIRECTRENDERING --#define NUM_BUFFERS 3 --#else --#define NUM_BUFFERS 2 --#endif -+#define NUM_BUFFERS 10 - - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) - #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) -@@ -176,6 +170,8 @@ class CWinRenderer : public CBaseRenderer - void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - - virtual unsigned int GetProcessorSize() { return m_processor.Size(); } -+ virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; } -+ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } - - protected: - virtual void Render(DWORD flags); -@@ -245,6 +241,8 @@ class CWinRenderer : public CBaseRenderer - // the separable HQ scalers need this info, but could the m_destRect be used instead? - unsigned int m_destWidth; - unsigned int m_destHeight; +-#empty strings from id 13435 to 13499 ++msgctxt "#13435" ++msgid "Allow Vdpau OpenGL interop" ++msgstr "" + -+ int m_neededBuffers; ++msgctxt "#13436" ++msgid "Prefer VDPAU Video Mixer" ++msgstr "" ++ ++msgctxt "#13437" ++msgid "Allow hardware acceleration (XVBA)" ++msgstr "" ++ ++#empty strings from id 13438 to 13499 + + msgctxt "#13500" + msgid "A/V sync method" +@@ -6333,10 +6343,14 @@ + msgstr "" + + msgctxt "#16325" +-msgid "Auto - ION Optimized" ++msgid "VDPAU - Bob" ++msgstr "" ++ ++msgctxt "#16326" ++msgid "XVBA" + msgstr "" + +-#empty strings from id 16326 to 16399 ++#empty strings from id 16327 to 16399 + + msgctxt "#16400" + msgid "Post-processing" +diff -Naur xbmc-12.0.4/lib/DllAvFormat.h xbmc-12.0.4.patch/lib/DllAvFormat.h +--- xbmc-12.0.4/lib/DllAvFormat.h 2013-03-08 13:01:40.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/DllAvFormat.h 2013-03-10 13:00:12.325988148 +0100 +@@ -98,6 +98,7 @@ + virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options)=0; + virtual int av_write_trailer(AVFormatContext *s)=0; + virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt)=0; ++ virtual int av_find_default_stream_index(AVFormatContext *s)=0; }; - #else --- -1.7.10 - - -From b0d133ededb6849b4313a65204ee9716cd0aae9f Mon Sep 17 00:00:00 2001 -From: unknown -Date: Sat, 16 Feb 2013 11:17:32 +0100 -Subject: [PATCH 04/88] DXVA: activate buffering in renderer - ---- - 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 19496a7..3bfe180 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1128,7 +1128,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - break; - case RENDER_FMT_DXVA: - formatstr = "DXVA"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_VAAPI: - formatstr = "VAAPI"; --- -1.7.10 - - -From bcbb88a9c2c822bf40c1f4d862cd10b9baccfd02 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 10:49:09 +0200 -Subject: [PATCH 05/88] linuxrenderer: delete all textures on reconfigure - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index b32a7ea..a2dc2be 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -251,7 +251,7 @@ bool CLinuxRendererGL::ValidateRenderTarget() - // function pointer for texture might change in - // call to LoadShaders - glFinish(); -- for (int i = 0 ; i < m_NumYV12Buffers ; i++) -+ for (int i = 0 ; i < NUM_BUFFERS ; i++) - (this->*m_textureDelete)(i); + #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) +@@ -153,6 +154,7 @@ + virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options) { return ::avformat_write_header (s, options); } + virtual int av_write_trailer(AVFormatContext *s) { return ::av_write_trailer(s); } + virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt) { return ::av_write_frame(s, pkt); } ++ virtual int av_find_default_stream_index(AVFormatContext *s) { return ::av_find_default_stream_index(s); } - // trigger update of video filters --- -1.7.10 - - -From 3d37fe3c9eca279b4ed2e0977651834b858f3682 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:17:33 +0200 -Subject: [PATCH 06/88] drop frame counter in application, ask render manager - instead - ---- - xbmc/Application.cpp | 50 +++++---------------------- - xbmc/Application.h | 6 ++-- - xbmc/cores/VideoRenderers/RenderManager.cpp | 11 ++++++ - xbmc/cores/VideoRenderers/RenderManager.h | 1 + - 4 files changed, 23 insertions(+), 45 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index efb3ac0..5c7017c 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp + // DLL faking. + virtual bool ResolveExports() { return true; } +@@ -209,6 +211,7 @@ + DEFINE_METHOD2(int, avformat_write_header , (AVFormatContext *p1, AVDictionary **p2)) + DEFINE_METHOD1(int, av_write_trailer, (AVFormatContext *p1)) + DEFINE_METHOD2(int, av_write_frame , (AVFormatContext *p1, AVPacket *p2)) ++ DEFINE_METHOD1(int, av_find_default_stream_index, (AVFormatContext *p1)) + BEGIN_METHOD_RESOLVE() + RESOLVE_METHOD_RENAME(av_register_all, av_register_all_dont_call) + RESOLVE_METHOD(av_find_input_format) +@@ -243,6 +246,7 @@ + RESOLVE_METHOD(avformat_write_header) + RESOLVE_METHOD(av_write_trailer) + RESOLVE_METHOD(av_write_frame) ++ RESOLVE_METHOD(av_find_default_stream_index) + END_METHOD_RESOLVE() + + /* dependencies of libavformat */ +diff -Naur xbmc-12.0.4/lib/ffmpeg/configure xbmc-12.0.4.patch/lib/ffmpeg/configure +--- xbmc-12.0.4/lib/ffmpeg/configure 2013-03-08 13:01:41.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/configure 2013-03-10 13:00:12.318988199 +0100 +@@ -113,6 +113,7 @@ + --enable-vdpau enable VDPAU code [autodetect] + --disable-dxva2 disable DXVA2 code + --disable-vda disable VDA code ++ --disable-xvba disable XVBA code + --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary) + --enable-hardcoded-tables use hardcoded tables instead of runtime generation + --disable-safe-bitstream-reader +@@ -1084,6 +1085,7 @@ + vaapi + vda + vdpau ++ xvba + version3 + x11grab + zlib +@@ -1423,6 +1425,7 @@ + h264_vaapi_hwaccel_select="vaapi h264_decoder" + h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" + h264_vda_hwaccel_select="vda h264_decoder" ++h264_xvba_hwaccel_select="xvba h264_decoder" + h264_vdpau_decoder_select="vdpau h264_decoder" + imc_decoder_select="fft mdct sinewin" + jpegls_decoder_select="golomb" +@@ -1459,6 +1462,7 @@ + mpeg4_decoder_select="h263_decoder mpeg4video_parser" + mpeg4_encoder_select="h263_encoder" + mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" ++mpeg2_xvba_hwaccel_select="xvba mpeg2video_decoder" + mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" + msmpeg4_crystalhd_decoder_select="crystalhd" + msmpeg4v1_decoder_select="h263_decoder" +@@ -1501,6 +1505,7 @@ + vc1_dxva2_hwaccel_deps="dxva2api_h" + vc1_dxva2_hwaccel_select="dxva2 vc1_decoder" + vc1_vaapi_hwaccel_select="vaapi vc1_decoder" ++vc1_xvba_hwaccel_select="xvba vc1_decoder" + vc1_vdpau_decoder_select="vdpau vc1_decoder" + vc1image_decoder_select="vc1_decoder" + vorbis_decoder_select="mdct" +@@ -1525,6 +1530,7 @@ + wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" + wmv3_vdpau_decoder_select="vc1_vdpau_decoder" + wmv3image_decoder_select="wmv3_decoder" ++wmv3_xvba_hwaccel_select="vc1_xvba_hwaccel" + zlib_decoder_select="zlib" + zlib_encoder_select="zlib" + zmbv_decoder_select="zlib" +@@ -1533,6 +1539,7 @@ + crystalhd_deps="libcrystalhd_libcrystalhd_if_h" + vaapi_deps="va_va_h" + vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" ++xvba_deps="amd_amdxvba_h" + vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" + + # parsers +@@ -3062,6 +3069,7 @@ + check_header termios.h + check_header vdpau/vdpau.h + check_header vdpau/vdpau_x11.h ++check_header amd/amdxvba.h + check_cpp_condition vdpau/vdpau.h "defined(VDP_DECODER_PROFILE_MPEG4_PART2_SP)" && enable vdpau_mpeg4_support + + check_header X11/extensions/XvMClib.h +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/allcodecs.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/allcodecs.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/allcodecs.c 2013-03-08 13:01:45.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/allcodecs.c 2013-03-10 13:00:12.319988191 +0100 +@@ -59,14 +59,18 @@ + REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); + REGISTER_HWACCEL (H264_VDA, h264_vda); + REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); ++ REGISTER_HWACCEL (H264_XVBA, h264_xvba); + REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); + REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); + REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); + REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); ++ REGISTER_HWACCEL (MPEG2_XVBA, mpeg2_xvba); + REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); + REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); ++ REGISTER_HWACCEL (VC1_XVBA, vc1_xvba); + REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2); + REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi); ++ REGISTER_HWACCEL (WMV3_XVBA, wmv3_xvba); + + /* video codecs */ + REGISTER_ENCODER (A64MULTI, a64multi); +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/h264.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/h264.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/h264.c 2013-03-08 13:01:45.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/h264.c 2013-03-10 13:00:12.319988191 +0100 +@@ -60,6 +60,7 @@ + PIX_FMT_DXVA2_VLD, + PIX_FMT_VAAPI_VLD, + PIX_FMT_VDA_VLD, ++ PIX_FMT_XVBA_VLD, + PIX_FMT_YUVJ420P, + PIX_FMT_NONE + }; +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/Makefile xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/Makefile +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/Makefile 2013-03-08 13:01:42.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/Makefile 2013-03-10 13:00:12.318988199 +0100 +@@ -3,7 +3,7 @@ + NAME = avcodec + FFLIBS = avutil + +-HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h ++HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h xvba.h + + OBJS = allcodecs.o \ + audioconvert.o \ +@@ -51,6 +51,7 @@ + OBJS-$(CONFIG_VAAPI) += vaapi.o + OBJS-$(CONFIG_VDA) += vda.o + OBJS-$(CONFIG_VDPAU) += vdpau.o ++OBJS-$(CONFIG_XVBA) += xvba.o + + # decoders/encoders/hardware accelerators + OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o +@@ -201,6 +202,7 @@ + OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o + OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o + OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o ++OBJS-$(CONFIG_H264_XVBA_HWACCEL) += xvba_h264.o + OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o + OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o + OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o +@@ -284,6 +286,7 @@ + mpegvideo.o error_resilience.o + OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o + OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o ++OBJS-$(CONFIG_MPEG2_XVBA_HWACCEL) += xvba_mpeg2.o + OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o \ + mpegvideo.o error_resilience.o + OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ +@@ -431,6 +434,7 @@ + intrax8.o intrax8dsp.o + OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o + OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o ++OBJS-$(CONFIG_VC1_XVBA_HWACCEL) += xvba_vc1.o + OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o + OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o + OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o +@@ -732,6 +736,7 @@ + SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h + SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h + SKIPHEADERS-$(CONFIG_VDA) += vda_internal.h ++SKIPHEADERS-$(CONFIG_XVBA) += xvba_internal.h + SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h + SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h + SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/mpegvideo.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/mpegvideo.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/mpegvideo.c 2013-03-08 13:01:42.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/mpegvideo.c 2013-03-10 13:00:12.320988184 +0100 +@@ -136,6 +136,7 @@ + PIX_FMT_DXVA2_VLD, + PIX_FMT_VAAPI_VLD, + PIX_FMT_VDA_VLD, ++ PIX_FMT_XVBA_VLD, + PIX_FMT_YUV420P, + PIX_FMT_NONE + }; +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba.c 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba.c 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,66 @@ ++/* ++ * HW decode acceleration for MPEG-2, H.264 and VC-1 ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++ ++/** ++ * \addtogroup XVBA_Decoding ++ * ++ * @{ ++ */ ++ ++#include ++#include "xvba.h" ++#include "xvba_internal.h" ++#include "avcodec.h" ++ ++int ff_xvba_translate_profile(int profile) { ++ ++ if (profile == 66) ++ return 1; ++ else if (profile == 77) ++ return 2; ++ else if (profile == 100) ++ return 3; ++ else if (profile == 0) ++ return 4; ++ else if (profile == 1) ++ return 5; ++ else if (profile == 3) ++ return 6; ++ else ++ return -1; ++} ++ ++void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size) { ++ ++ render->buffers = av_fast_realloc( ++ render->buffers, ++ &render->buffers_alllocated, ++ sizeof(struct xvba_bitstream_buffers)*(render->num_slices + 1) ++ ); ++ ++ render->buffers[render->num_slices].buffer = buffer; ++ render->buffers[render->num_slices].size = size; ++ ++ render->num_slices++; ++} ++ +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba.h xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba.h +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba.h 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,71 @@ ++/* ++ * HW decode acceleration for MPEG-2, H.264 and VC-1 ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef AVCODEC_XVBA_H ++#define AVCODEC_XVBA_H ++ ++#include ++#include ++#include ++ ++ ++/** ++ * \defgroup XVBA_Decoding VA API Decoding ++ * \ingroup Decoder ++ * @{ ++ */ ++ ++/** \brief The videoSurface is used for rendering. */ ++#define FF_XVBA_STATE_USED_FOR_RENDER 1 ++ ++/** ++ * \brief The videoSurface is needed for reference/prediction. ++ * The codec manipulates this. ++ */ ++#define FF_XVBA_STATE_USED_FOR_REFERENCE 2 ++ ++/** ++ * \brief The videoSurface holds a decoded frame. ++ * The codec manipulates this. ++ */ ++#define FF_XVBA_STATE_DECODED 4 ++ ++/* @} */ ++ ++struct xvba_bitstream_buffers ++{ ++ const void *buffer; ++ unsigned int size; ++}; ++ ++struct xvba_render_state { ++ ++ int state; ///< Holds FF_XVBA_STATE_* values. ++ void *surface; ++ XVBAPictureDescriptor *picture_descriptor; ++ XVBAQuantMatrixAvc *iq_matrix; ++ unsigned int num_slices; ++ struct xvba_bitstream_buffers *buffers; ++ uint32_t buffers_alllocated; ++}; ++ ++#endif /* AVCODEC_XVBA_H */ +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_h264.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_h264.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_h264.c 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_h264.c 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,195 @@ ++/* ++ * H.264 HW decode acceleration through XVBA ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "xvba.h" ++#include "xvba_internal.h" ++#include "h264.h" ++#include ++ ++/** @file ++ * This file implements the glue code between FFmpeg's and XvBA API's ++ * structures for H.264 decoding. ++ */ ++ ++ ++/** Initialize and start decoding a frame with XVBA. */ ++static int start_frame(AVCodecContext *avctx, ++ av_unused const uint8_t *buffer, ++ av_unused uint32_t size) ++{ ++ H264Context * const h = avctx->priv_data; ++ MpegEncContext * const s = &h->s; ++ struct xvba_render_state *render; ++ XVBAPictureDescriptor *pic_descriptor; ++ int i; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ if (render->picture_descriptor == 0) ++ return -1; ++ ++ pic_descriptor = render->picture_descriptor; ++ ++ for (i = 0; i < 2; ++i) { ++ int foc = s->current_picture_ptr->field_poc[i]; ++ if (foc == INT_MAX) ++ foc = 0; ++ pic_descriptor->avc_curr_field_order_cnt_list[i] = foc; ++ } ++ ++ pic_descriptor->avc_frame_num = h->frame_num; ++ ++ render->num_slices = 0; ++ ++ return 0; ++} ++ ++/** End a hardware decoding based frame. */ ++static int end_frame(AVCodecContext *avctx) ++{ ++ H264Context * const h = avctx->priv_data; ++ MpegEncContext * const s = &h->s; ++ struct xvba_render_state *render; ++ XVBAPictureDescriptor *pic_descriptor; ++ XVBAQuantMatrixAvc *iq_matrix; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ if (render->picture_descriptor == 0 || render->iq_matrix == 0) ++ return -1; ++ ++ pic_descriptor = render->picture_descriptor; ++ iq_matrix = render->iq_matrix; ++ ++ av_dlog(avctx, "end_frame()\n"); ++ ++ /* Fill in Picture Parameters*/ ++ pic_descriptor->profile = ff_xvba_translate_profile(avctx->profile); ++ pic_descriptor->level = avctx->level; ++ pic_descriptor->width_in_mb = s->mb_width; ++ pic_descriptor->height_in_mb = s->mb_height; ++ pic_descriptor->picture_structure = s->picture_structure; ++ pic_descriptor->chroma_format = s->chroma_format ? s->chroma_format : 1; ++ pic_descriptor->avc_intra_flag = (h->slice_type == AV_PICTURE_TYPE_I) ? 1 : 0; ++ pic_descriptor->avc_reference = (s->current_picture_ptr->f.reference & 3) ? 1 : 0; ++ ++ pic_descriptor->avc_bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; ++ pic_descriptor->avc_bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; ++ pic_descriptor->avc_log2_max_frame_num_minus4 = h->sps.log2_max_frame_num -4; ++ pic_descriptor->avc_pic_order_cnt_type = h->sps.poc_type; ++ pic_descriptor->avc_log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4; ++ pic_descriptor->avc_num_ref_frames = h->sps.ref_frame_count; ++ pic_descriptor->avc_reserved_8bit = 0; ++ ++ /* Set a level that can decode stuff in every case without a lookup table ++ xvba seems to have problems only when the number of Reframes goes beyond ++ the max support number of Level4.1@High. So in praxis decoding a Level 3.0 ++ file that in deed has level4.1@High specs does not matter. We use this fact ++ and check if the ref_frames stay in the range Level4.1@high can decode if ++ not, we set Level5.1 */ ++ if (pic_descriptor->avc_num_ref_frames > 4) { ++ const unsigned int mbw = pic_descriptor->width_in_mb; ++ const unsigned int mbh = pic_descriptor->height_in_mb; ++ // this matches Level4.1@High stats to differ between <= 4.1 and 5.1 ++ const unsigned int max_ref_frames = 12288 * 1024 / (mbw * mbh * 384); ++ const unsigned int num_ref_frames = pic_descriptor->avc_num_ref_frames; ++ if (max_ref_frames < num_ref_frames) ++ pic_descriptor->level = 51; ++ } ++ ++ pic_descriptor->avc_num_slice_groups_minus1 = h->pps.slice_group_count - 1; ++ pic_descriptor->avc_num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1; ++ pic_descriptor->avc_num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1; ++ ++ pic_descriptor->avc_pic_init_qp_minus26 = h->pps.init_qp - 26; ++ pic_descriptor->avc_pic_init_qs_minus26 = h->pps.init_qs - 26; ++ pic_descriptor->avc_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; ++ pic_descriptor->avc_second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; ++ pic_descriptor->avc_slice_group_change_rate_minus1 = 0; // not implemented in ffmpeg ++ pic_descriptor->avc_reserved_16bit = 0; // must be 0 ++ memset(pic_descriptor->avc_field_order_cnt_list,0,sizeof(pic_descriptor->avc_field_order_cnt_list)); // must be 0 ++ memset(pic_descriptor->avc_slice_group_map,0,sizeof(pic_descriptor->avc_slice_group_map)); // must be 0 ++ ++ // sps ++ pic_descriptor->sps_info.avc.delta_pic_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; ++ pic_descriptor->sps_info.avc.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; ++ pic_descriptor->sps_info.avc.frame_mbs_only_flag = h->sps.frame_mbs_only_flag; ++ pic_descriptor->sps_info.avc.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag; ++ pic_descriptor->sps_info.avc.mb_adaptive_frame_field_flag = h->sps.mb_aff; ++ pic_descriptor->sps_info.avc.residual_colour_transform_flag = h->sps.residual_color_transform_flag; ++ pic_descriptor->sps_info.avc.xvba_avc_sps_reserved = 0; ++ ++ // pps ++ pic_descriptor->pps_info.avc.entropy_coding_mode_flag = h->pps.cabac; ++ pic_descriptor->pps_info.avc.pic_order_present_flag = h->pps.pic_order_present; ++ pic_descriptor->pps_info.avc.weighted_pred_flag = h->pps.weighted_pred; ++ pic_descriptor->pps_info.avc.weighted_bipred_idc = h->pps.weighted_bipred_idc; ++ pic_descriptor->pps_info.avc.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; ++ pic_descriptor->pps_info.avc.constrained_intra_pred_flag = h->pps.constrained_intra_pred; ++ pic_descriptor->pps_info.avc.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; ++ pic_descriptor->pps_info.avc.transform_8x8_mode_flag = h->pps.transform_8x8_mode; ++ pic_descriptor->pps_info.avc.xvba_avc_pps_reserved = 0; // must be 0 ++ ++ memcpy(iq_matrix->bScalingLists4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->bScalingLists4x4)); ++ memcpy(iq_matrix->bScalingLists8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->bScalingLists8x8[0])); ++ memcpy(iq_matrix->bScalingLists8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->bScalingLists8x8[0])); ++ ++ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs ++ if (!h->got_first_iframe) { ++ if (h->slice_type != AV_PICTURE_TYPE_I && h->slice_type != AV_PICTURE_TYPE_SI) ++ return -1; ++ h->got_first_iframe = 1; ++ } ++ ++ ff_draw_horiz_band(s, 0, s->avctx->height); ++ ++ return 0; ++} ++ ++/** Decode the given H.264 slice with XVBA. */ ++static int decode_slice(AVCodecContext *avctx, ++ const uint8_t *buffer, ++ uint32_t size) ++{ ++ H264Context * const h = avctx->priv_data; ++ MpegEncContext * const s = &h->s; ++ struct xvba_render_state *render; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ ff_xvba_add_slice_data(render, buffer, size); ++ ++ return 0; ++} ++ ++AVHWAccel ff_h264_xvba_hwaccel = { ++ .name = "h264_xvba", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = CODEC_ID_H264, ++ .pix_fmt = PIX_FMT_XVBA_VLD, ++ .start_frame = start_frame, ++ .end_frame = end_frame, ++ .decode_slice = decode_slice, ++}; +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_internal.h xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_internal.h +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_internal.h 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,24 @@ ++/* ++ * HW decode acceleration for MPEG-2, H.264 and VC-1 ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++int ff_xvba_translate_profile(int profile); ++void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size); +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_mpeg2.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_mpeg2.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_mpeg2.c 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_mpeg2.c 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,52 @@ ++/* ++ * MPEG-2 HW decode acceleration through XVBA ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "dsputil.h" ++ ++static int start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) ++{ ++ struct MpegEncContext * const s = avctx->priv_data; ++ return 0; ++} ++ ++static int end_frame(AVCodecContext *avctx) ++{ ++ return 0; ++} ++ ++static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) ++{ ++ struct MpegEncContext * const s = avctx->priv_data; ++ return 0; ++} ++ ++AVHWAccel ff_mpeg2_xvba_hwaccel = { ++ .name = "mpeg2_xvba", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = CODEC_ID_MPEG2VIDEO, ++ .pix_fmt = PIX_FMT_XVBA_VLD, ++ .capabilities = 0, ++ .start_frame = start_frame, ++ .end_frame = end_frame, ++ .decode_slice = decode_slice, ++ .priv_data_size = 0, ++}; +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_vc1.c xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_vc1.c +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvba_vc1.c 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvba_vc1.c 2013-03-10 13:00:12.320988184 +0100 +@@ -0,0 +1,190 @@ ++/* ++ * VC-1 HW decode acceleration through XVBA ++ * ++ * Copyright (C) 2005-2011 Team XBMC ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "xvba.h" ++#include "xvba_internal.h" ++#include "vc1.h" ++#include "vc1data.h" ++#include ++ ++ ++/** @file ++ * Implement structures of ffmpeg <-> XvBA ++ */ ++ ++/* Initialize and start decoding a frame with XvBA */ ++static int start_frame(AVCodecContext *avctx, ++ av_unused const uint8_t *buffer, ++ av_unused uint32_t size) ++{ ++ VC1Context * const v = avctx->priv_data; ++ MpegEncContext * const s = &v->s; ++ struct xvba_render_state *render; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ render->num_slices = 0; ++ return 0; ++} ++ ++/* End a hardware decoding based frame */ ++static int end_frame(AVCodecContext *avctx) ++{ ++ VC1Context* const v = avctx->priv_data; ++ MpegEncContext* const s = &v->s; ++ struct xvba_render_state *render, *last, *next; ++ XVBAPictureDescriptor *pic_descriptor; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ if (render->picture_descriptor == 0) ++ return -1; ++ ++ pic_descriptor = render->picture_descriptor; ++ ++ av_dlog(avctx, "xvba_vc1_end_frame()\n"); ++ ++ memset(pic_descriptor, 0, sizeof(*pic_descriptor)); ++ ++ /* Fill in Parameters - for reference see AMD sdk documentation */ ++ pic_descriptor->profile = ff_xvba_translate_profile(v->profile); ++ pic_descriptor->level = v->level; ++ //done like in va-driver and vaapi ++ if (v->profile == PROFILE_ADVANCED) { ++ pic_descriptor->width_in_mb = s->avctx->coded_width; ++ pic_descriptor->height_in_mb = s->avctx->coded_height; ++ } else { ++ pic_descriptor->width_in_mb = s->mb_width; ++ pic_descriptor->height_in_mb = s->mb_height; ++ } ++ pic_descriptor->picture_structure = s->picture_structure; ++ // xvba-video set this to 1 only 4:2:0 supported ++ // doc says: if not set, choose 1 - we try this ++ pic_descriptor->chroma_format = 1; ++ pic_descriptor->avc_intra_flag = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type == 1; ++ pic_descriptor->avc_reference = (s->current_picture_ptr->f.reference & 3) ? 1 : 0; ++ ++ // VC-1 explicit parameters see page 30 of sdk ++ // sps_info ++ pic_descriptor->sps_info.vc1.postprocflag = v->postprocflag; ++ ++ // done as in vaapi ++ pic_descriptor->sps_info.vc1.pulldown = v->broadcast; ++ pic_descriptor->sps_info.vc1.interlace = v->interlace; ++ pic_descriptor->sps_info.vc1.tfcntrflag = v->tfcntrflag; ++ pic_descriptor->sps_info.vc1.finterpflag = v->finterpflag; ++ pic_descriptor->sps_info.vc1.reserved = 1; ++ // eventually check if this makes sense together with interlace ++ pic_descriptor->sps_info.vc1.psf = v->psf; ++ // what about if it is a frame (page 31) ++ // looked at xvba-driver ++ pic_descriptor->sps_info.vc1.second_field = !s->first_field; ++ pic_descriptor->sps_info.vc1.xvba_vc1_sps_reserved = 0; ++ ++ // VC-1 explicit parameters see page 30 of sdk ++ // pps_info ++ pic_descriptor->pps_info.vc1.panscan_flag = v->panscanflag; ++ pic_descriptor->pps_info.vc1.refdist_flag = v->refdist_flag; ++ pic_descriptor->pps_info.vc1.loopfilter = s->loop_filter; ++ pic_descriptor->pps_info.vc1.fastuvmc = v->fastuvmc; ++ pic_descriptor->pps_info.vc1.extended_mv = v->extended_mv; ++ pic_descriptor->pps_info.vc1.dquant = v->dquant; ++ pic_descriptor->pps_info.vc1.vstransform = v->vstransform; ++ pic_descriptor->pps_info.vc1.overlap = v->overlap; ++ pic_descriptor->pps_info.vc1.quantizer = v->quantizer_mode; ++ pic_descriptor->pps_info.vc1.extended_dmv = v->extended_dmv; ++ pic_descriptor->pps_info.vc1.maxbframes = s->avctx->max_b_frames; ++ pic_descriptor->pps_info.vc1.rangered = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : v->rangered; ++ pic_descriptor->pps_info.vc1.syncmarker = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : s->resync_marker; ++ pic_descriptor->pps_info.vc1.multires = v->multires; ++ pic_descriptor->pps_info.vc1.reserved = 1; ++ pic_descriptor->pps_info.vc1.range_mapy_flag = v->range_mapy_flag; ++ pic_descriptor->pps_info.vc1.range_mapy = v->range_mapy; ++ pic_descriptor->pps_info.vc1.range_mapuv_flag = v->range_mapuv_flag; ++ pic_descriptor->pps_info.vc1.range_mapuv = v->range_mapuv; ++ pic_descriptor->pps_info.vc1.xvba_vc1_pps_reserved = 0; ++ ++ pic_descriptor->past_surface = 0; ++ pic_descriptor->future_surface = 0; ++ switch (s->pict_type) { ++ case AV_PICTURE_TYPE_B: ++ next = (struct xvba_render_state *)s->next_picture.f.data[0]; ++ assert(next); ++ if (next) ++ pic_descriptor->past_surface = next->surface; ++ // fall-through ++ case AV_PICTURE_TYPE_P: ++ last = (struct xvba_render_state *)s->last_picture.f.data[0]; ++ assert(last); ++ if (last) ++ pic_descriptor->future_surface = last->surface; ++ break; ++ } ++ ++ ff_draw_horiz_band(s, 0, s->avctx->height); ++ ++ return 0; ++} ++ ++static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) ++{ ++ VC1Context* const v = avctx->priv_data; ++ MpegEncContext* const s = &v->s; ++ struct xvba_render_state *render; ++ ++ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; ++ assert(render); ++ ++ if (avctx->codec_id == CODEC_ID_VC1 && ++ size >= 4 && IS_MARKER(AV_RB32(buffer))) { ++ buffer += 4; ++ size -= 4; ++ } ++ ++ ff_xvba_add_slice_data(render, buffer, size); ++ ++ return 0; ++} ++ ++#if CONFIG_WMV3_XVBA_HWACCEL ++AVHWAccel ff_wmv3_xvba_hwaccel = { ++ .name = "wmv3_xvba", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = CODEC_ID_WMV3, ++ .pix_fmt = PIX_FMT_XVBA_VLD, ++ .start_frame = start_frame, ++ .end_frame = end_frame, ++ .decode_slice = decode_slice, ++}; ++#endif ++ ++AVHWAccel ff_vc1_xvba_hwaccel = { ++ .name = "vc1_xvba", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = CODEC_ID_VC1, ++ .pix_fmt = PIX_FMT_XVBA_VLD, ++ .start_frame = start_frame, ++ .end_frame = end_frame, ++ .decode_slice = decode_slice, ++}; +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavcodec/xvmc_internal.h xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvmc_internal.h +--- xbmc-12.0.4/lib/ffmpeg/libavcodec/xvmc_internal.h 2013-03-08 13:01:44.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavcodec/xvmc_internal.h 2013-03-10 13:00:12.321988177 +0100 +@@ -1,5 +1,7 @@ + /* +- * XVideo Motion Compensation internal functions ++ * HW decode acceleration for MPEG-2, H.264 and VC-1 ++ * ++ * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavutil/pixdesc.c xbmc-12.0.4.patch/lib/ffmpeg/libavutil/pixdesc.c +--- xbmc-12.0.4/lib/ffmpeg/libavutil/pixdesc.c 2013-03-08 13:01:41.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavutil/pixdesc.c 2013-03-10 13:00:12.321988177 +0100 +@@ -874,6 +874,12 @@ + .log2_chroma_h = 1, + .flags = PIX_FMT_HWACCEL, + }, ++ [PIX_FMT_XVBA_VLD] = { ++ .name = "xvba_vld", ++ .log2_chroma_w = 1, ++ .log2_chroma_h = 1, ++ .flags = PIX_FMT_HWACCEL, ++ }, + [PIX_FMT_YUV420P9LE] = { + .name = "yuv420p9le", + .nb_components = 3, +diff -Naur xbmc-12.0.4/lib/ffmpeg/libavutil/pixfmt.h xbmc-12.0.4.patch/lib/ffmpeg/libavutil/pixfmt.h +--- xbmc-12.0.4/lib/ffmpeg/libavutil/pixfmt.h 2013-03-08 13:01:41.000000000 +0100 ++++ xbmc-12.0.4.patch/lib/ffmpeg/libavutil/pixfmt.h 2013-03-10 13:00:12.321988177 +0100 +@@ -129,6 +129,7 @@ + PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer ++ PIX_FMT_XVBA_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + + PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 + PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 +diff -Naur xbmc-12.0.4/system/shaders/yuv2rgb_basic.glsl xbmc-12.0.4.patch/system/shaders/yuv2rgb_basic.glsl +--- xbmc-12.0.4/system/shaders/yuv2rgb_basic.glsl 2013-03-08 13:01:46.000000000 +0100 ++++ xbmc-12.0.4.patch/system/shaders/yuv2rgb_basic.glsl 2013-03-10 13:00:12.294988371 +0100 +@@ -70,6 +70,18 @@ + rgb.a = gl_Color.a; + gl_FragColor = rgb; + ++#elif defined(XBMC_VDPAU_NV12) ++ ++ vec4 yuv, rgb; ++ yuv.rgba = vec4( texture2D(m_sampY, stretch(m_cordY)).r ++ , texture2D(m_sampU, stretch(m_cordU)).r ++ , texture2D(m_sampV, stretch(m_cordV)).g ++ , 1.0 ); ++ ++ rgb = m_yuvmat * yuv; ++ rgb.a = gl_Color.a; ++ gl_FragColor = rgb; ++ + #elif defined(XBMC_YUY2) || defined(XBMC_UYVY) + + #if(XBMC_texture_rectangle) +diff -Naur xbmc-12.0.4/xbmc/Application.cpp xbmc-12.0.4.patch/xbmc/Application.cpp +--- xbmc-12.0.4/xbmc/Application.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/Application.cpp 2013-03-10 13:00:12.308988270 +0100 @@ -419,8 +419,6 @@ #endif m_currentStack = new CFileItemList; @@ -1371,7 +1049,16 @@ index efb3ac0..5c7017c 100644 m_bPresentFrame = false; m_bPlatformDirectories = true; -@@ -2231,28 +2229,18 @@ float CApplication::GetDimScreenSaverLevel() const +@@ -796,7 +794,7 @@ + + uint32_t sdlFlags = 0; + +-#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2) ++#if (defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)) && !defined(HAS_GLX) + sdlFlags |= SDL_INIT_VIDEO; + #endif + +@@ -2231,28 +2229,18 @@ bool CApplication::WaitFrame(unsigned int timeout) { @@ -1405,7 +1092,7 @@ index efb3ac0..5c7017c 100644 } void CApplication::Render() -@@ -2272,7 +2260,6 @@ void CApplication::Render() +@@ -2272,7 +2260,6 @@ int vsync_mode = g_guiSettings.GetInt("videoscreen.vsync"); @@ -1413,7 +1100,7 @@ index efb3ac0..5c7017c 100644 bool hasRendered = false; bool limitFrames = false; unsigned int singleFrameTime = 10; // default limit 100 fps -@@ -2286,13 +2273,10 @@ void CApplication::Render() +@@ -2286,13 +2273,10 @@ m_bPresentFrame = false; if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !IsPaused()) { @@ -1431,7 +1118,7 @@ index efb3ac0..5c7017c 100644 hasRendered = true; } else -@@ -2316,8 +2300,6 @@ void CApplication::Render() +@@ -2316,8 +2300,6 @@ else if (lowfps) singleFrameTime = 200; // 5 fps, <=200 ms latency to wake up } @@ -1440,7 +1127,17 @@ index efb3ac0..5c7017c 100644 } } -@@ -2381,13 +2363,6 @@ void CApplication::Render() +@@ -2371,20 +2353,16 @@ + m_lastFrameTime = XbmcThreads::SystemClockMillis(); + + if (flip) ++ { + g_graphicsContext.Flip(dirtyRegions); ++ g_renderManager.NotifyDisplayFlip(); ++ } + CTimeUtils::UpdateFrameTime(flip); + + g_TextureManager.FreeUnusedTextures(); g_renderManager.UpdateResolution(); g_renderManager.ManageCaptures(); @@ -1454,7 +1151,7 @@ index efb3ac0..5c7017c 100644 } void CApplication::SetStandAlone(bool value) -@@ -5633,12 +5608,6 @@ bool CApplication::SwitchToFullScreen() +@@ -5630,12 +5608,6 @@ // See if we're playing a video, and are in GUI mode if ( IsPlayingVideo() && g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO) { @@ -1467,7 +1164,7 @@ index efb3ac0..5c7017c 100644 // then switch to fullscreen mode g_windowManager.ActivateWindow(WINDOW_FULLSCREEN_VIDEO); return true; -@@ -5871,7 +5840,6 @@ bool CApplication::IsCurrentThread() const +@@ -5868,7 +5840,6 @@ bool CApplication::IsPresentFrame() { @@ -1475,11 +1172,10 @@ index efb3ac0..5c7017c 100644 bool ret = m_bPresentFrame; return ret; -diff --git a/xbmc/Application.h b/xbmc/Application.h -index 69609fa..6764a60 100644 ---- a/xbmc/Application.h -+++ b/xbmc/Application.h -@@ -422,10 +422,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs +diff -Naur xbmc-12.0.4/xbmc/Application.h xbmc-12.0.4.patch/xbmc/Application.h +--- xbmc-12.0.4/xbmc/Application.h 2013-03-08 13:01:27.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/Application.h 2013-03-10 13:00:12.283988450 +0100 +@@ -422,10 +422,8 @@ bool m_bEnableLegacyRes; bool m_bTestMode; bool m_bSystemScreenSaverEnable; @@ -1492,2786 +1188,35 @@ index 69609fa..6764a60 100644 VIDEO::CVideoInfoScanner *m_videoInfoScanner; MUSIC_INFO::CMusicInfoScanner *m_musicInfoScanner; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index c13f83d..35aba7e 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1102,3 +1102,14 @@ void CXBMCRenderManager::NotifyDisplayFlip() - lock.Leave(); - m_flipEvent.Set(); - } -+ -+bool CXBMCRenderManager::HasFrame() -+{ -+ CSharedLock lock(m_sharedSection); -+ if (m_presentstep == PRESENT_IDLE && -+ GetNextRenderBufferIndex() < 0 && -+ m_speed > 0) -+ return false; -+ else -+ return true; -+} -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 96ab53f..1e44233 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -148,6 +148,7 @@ class CXBMCRenderManager - * display becomes available for player to deliver a new frame. - */ - void NotifyDisplayFlip(); -+ bool HasFrame(); - void EnableBuffering(bool enable); - void DiscardBuffer(); - --- -1.7.10 - - -From 61ece20a4691e8d7f6203054bdc1a5fc5e9b84ab Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 11:02:29 +0200 -Subject: [PATCH 07/88] vaapi: adopt to buffering in renderer - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 3 ++- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h | 1 + - 3 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 8f81637..286fd67 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -106,7 +106,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - && (avctx->codec_id != CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) - { - VAAPI::CDecoder* dec = new VAAPI::CDecoder(); -- if(dec->Open(avctx, *cur)) -+ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) - { - ctx->SetHardware(dec); - return *cur; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index 9f5a960..a2b9195 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -357,6 +357,7 @@ bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int su - CHECK(vaCreateConfig(m_display->get(), profile, entrypoint, &attrib, 1, &m_hwaccel->config_id)) - m_config = m_hwaccel->config_id; - -+ m_renderbuffers_count = surfaces; - if (!EnsureContext(avctx)) - return false; - -@@ -388,7 +389,7 @@ bool CDecoder::EnsureContext(AVCodecContext *avctx) - else - m_refs = 2; - } -- return EnsureSurfaces(avctx, m_refs + 3); -+ return EnsureSurfaces(avctx, m_refs + m_renderbuffers_count + 1); - } - - bool CDecoder::EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -index 863edc4..417cbc0 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h -@@ -122,6 +122,7 @@ class CDecoder - static const unsigned m_surfaces_max = 32; - unsigned m_surfaces_count; - VASurfaceID m_surfaces[m_surfaces_max]; -+ unsigned m_renderbuffers_count; - - int m_refs; - std::list m_surfaces_used; --- -1.7.10 - - -From ab9b5a5d746f712a0d3e5332cc191d129fc3a175 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 20:17:29 +0100 -Subject: [PATCH 08/88] add buffering - some documentation - ---- - xbmc/cores/IPlayer.h | 3 +++ - xbmc/cores/VideoRenderers/RenderManager.h | 40 +++++++++++++++++++++++++++++ - 2 files changed, 43 insertions(+) - -diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h -index eb654ec..cbf2faa 100644 ---- a/xbmc/cores/IPlayer.h -+++ b/xbmc/cores/IPlayer.h -@@ -229,6 +229,9 @@ class IPlayer - */ - virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; - -+ /*! -+ \brief called by RenderManager in order to schedule frames -+ */ - virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; - - protected: -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 1e44233..49da2ed 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -66,11 +66,38 @@ class CXBMCRenderManager - void SetViewMode(int iViewMode); - - // Functions called from mplayer -+ /** -+ * Called by video player to configure renderer -+ * @param width width of decoded frame -+ * @param height height of decoded frame -+ * @param d_width displayed width of frame (aspect ratio) -+ * @param d_height displayed height of frame -+ * @param fps frames per second of video -+ * @param flags see RenderFlags.h -+ * @param format see RenderFormats.h -+ * @param extended_format used by DXVA -+ * @param orientation -+ * @param buffering enable buffering in renderer, defaults to false -+ */ - bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering = false); - bool IsConfigured(); - - int AddVideoPicture(DVDVideoPicture& picture); - -+ /** -+ * Called by video player to flip render buffers -+ * If buffering is enabled this method does not block. In case of disabled buffering -+ * this method blocks waiting for the render thread to pass by. -+ * When buffering is used there might be no free buffer available after the call to -+ * this method. Player has to call WaitForBuffer. A free buffer will become -+ * available after the main thread has flipped front / back buffers. -+ * -+ * @param bStop reference to stop flag of calling thread -+ * @param timestamp pts of frame delivered with AddVideoPicture -+ * @param source depreciated -+ * @param sync signals frame, top, or bottom field -+ * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind -+ */ - void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); - unsigned int PreInit(); - void UnInit(); -@@ -148,8 +175,21 @@ class CXBMCRenderManager - * display becomes available for player to deliver a new frame. - */ - void NotifyDisplayFlip(); -+ -+ /** -+ * Called by application (main thread) to query if there is any frame to render -+ */ - bool HasFrame(); -+ -+ /** -+ * Video player can dynamically enable/disable buffering. In situations like -+ * rewind buffering is not ideal. -+ */ - void EnableBuffering(bool enable); -+ -+ /** -+ * Video player call this on flush in oder to discard any queued frames -+ */ - void DiscardBuffer(); - - protected: --- -1.7.10 - - -From 9d2f1cbcf647826f3449fb58c995a478bfd0697c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 18 Feb 2013 10:42:00 +0100 -Subject: [PATCH 09/88] RenderManager: only flip free buffer if player has - added something - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 29 +++++++++++++++++++++++---- - xbmc/cores/VideoRenderers/RenderManager.h | 7 ++----- - 2 files changed, 27 insertions(+), 9 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 35aba7e..f5cc0f6 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -612,10 +612,12 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - } - } - -- FlipFreeBuffer(); -- m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; -- m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; -- m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; -+ if (FlipFreeBuffer() >= 0) -+ { -+ m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; -+ m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; -+ m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; -+ } - m_speed = speed; - } - -@@ -825,7 +827,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - return -1; - - if(m_pRenderer->AddVideoPicture(&pic, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers)) -+ { -+ m_bRenderBufferUsed = true; - return 1; -+ } - - YV12Image image; - int index = m_pRenderer->GetImage(&image, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); -@@ -870,9 +875,17 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2013-03-10 13:00:12.325988148 +0100 +@@ -169,6 +169,11 @@ + #elif defined(_LINUX) && !defined(TARGET_DARWIN) + hwSupport += "VAAPI:no "; #endif - m_pRenderer->ReleaseImage(index, false); - -+ m_bRenderBufferUsed = true; - return index; - } - -+void CXBMCRenderManager::AddOverlay(CDVDOverlay* o, double pts) -+{ -+ CSharedLock lock(m_sharedSection); -+ m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); -+ m_bRenderBufferUsed = true; -+} -+ - bool CXBMCRenderManager::Supports(ERENDERFEATURE feature) - { - CSharedLock lock(m_sharedSection); -@@ -973,10 +986,17 @@ int CXBMCRenderManager::FlipFreeBuffer() - // See "Render Buffer State Description" in header for information. - if (HasFreeBuffer()) - { -+ if (!m_bRenderBufferUsed) -+ { -+ return -1; -+ } -+ m_bRenderBufferUsed = false; - m_bAllRenderBuffersDisplayed = false; - m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; - return m_iOutputRenderBuffer; - } -+ else -+ return -1; - } - - bool CXBMCRenderManager::HasFreeBuffer() -@@ -1017,6 +1037,7 @@ void CXBMCRenderManager::ResetRenderBuffer() - m_sleeptime = 1.0; - m_presentPts = DVD_NOPTS_VALUE; - m_speed = 0; -+ m_bRenderBufferUsed = false; - } - - void CXBMCRenderManager::PrepareNextRender() -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 49da2ed..afb6b1f 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -103,11 +103,7 @@ class CXBMCRenderManager - void UnInit(); - bool Flush(); - -- void AddOverlay(CDVDOverlay* o, double pts) -- { -- CSharedLock lock(m_sharedSection); -- m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); -- } -+ void AddOverlay(CDVDOverlay* o, double pts); - - void AddCleanup(OVERLAY::COverlay* o) - { -@@ -255,6 +251,7 @@ class CXBMCRenderManager - bool m_bUseBuffering; - bool m_bCodecSupportsBuffering; - int m_speed; -+ bool m_bRenderBufferUsed; - CEvent m_flipEvent; - - struct --- -1.7.10 - - -From d4d025be1cd04effdc90d6b6103097ce193067a0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 19 Feb 2013 09:06:22 +0100 -Subject: [PATCH 10/88] move NUM_BUFFERS up to BaseRenderer.h - ---- - xbmc/cores/VideoRenderers/BaseRenderer.h | 3 ++- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 2 -- - xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 2 -- - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 2 +- - xbmc/cores/VideoRenderers/OverlayRenderer.h | 3 ++- - xbmc/cores/VideoRenderers/WinRenderer.h | 2 -- - 6 files changed, 5 insertions(+), 9 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h -index aa1e4ae..60b7197 100644 ---- a/xbmc/cores/VideoRenderers/BaseRenderer.h -+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h -@@ -26,10 +26,11 @@ - - #define MAX_PLANES 3 - #define MAX_FIELDS 3 -+#define NUM_BUFFERS 10 - - typedef struct YV12Image - { -- BYTE * plane[MAX_PLANES]; -+ uint8_t* plane[MAX_PLANES]; - int planesize[MAX_PLANES]; - unsigned stride[MAX_PLANES]; - unsigned width; -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 7c9fcae..a7b5886 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -44,8 +44,6 @@ - namespace Shaders { class BaseVideoFilterShader; } - namespace VAAPI { struct CHolder; } - --#define NUM_BUFFERS 10 -- - - #undef ALIGN - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -index 5bae10d..fe32eff 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h -@@ -41,8 +41,6 @@ - class COpenMaxVideo; - typedef std::vector Features; - --#define NUM_BUFFERS 10 -- - - #undef ALIGN - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index f7f74ce..5236390 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -93,7 +93,7 @@ long COverlayMainThread::Release() - - CRenderer::~CRenderer() - { -- for(int i = 0; i < 10; i++) -+ for(int i = 0; i < NUM_BUFFERS; i++) - Release(m_buffers[i]); - } - -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index 0921fc5..66c592a 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.h -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -23,6 +23,7 @@ - #pragma once - - #include "threads/CriticalSection.h" -+#include "BaseRenderer.h" - - #include - -@@ -126,7 +127,7 @@ - void Release(SElementV& list); - - CCriticalSection m_section; -- SElementV m_buffers[10]; -+ SElementV m_buffers[NUM_BUFFERS]; - int m_iNumBuffers; - int m_decode; - int m_render; -diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h -index b3448ed..b099697 100644 ---- a/xbmc/cores/VideoRenderers/WinRenderer.h -+++ b/xbmc/cores/VideoRenderers/WinRenderer.h -@@ -32,8 +32,6 @@ - #include "cores/VideoRenderers/RenderFlags.h" - #include "cores/VideoRenderers/RenderFormats.h" - --#define NUM_BUFFERS 10 -- - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) - #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) - --- -1.7.10 - - -From 08665778e71d52fa461150f596dd18de1035915f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Feb 2013 09:55:00 +0100 -Subject: [PATCH 11/88] OverlayRenderer: align buffers with index in - renderManager - ---- - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 26 ++++++++++++++++--------- - xbmc/cores/VideoRenderers/OverlayRenderer.h | 8 ++++---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 11 +++++++---- - xbmc/cores/VideoRenderers/RenderManager.h | 1 + - 4 files changed, 29 insertions(+), 17 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index 5236390..5592eca 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -127,27 +127,32 @@ void CRenderer::AddCleanup(COverlay* o) - m_cleanup.push_back(o->Acquire()); - } - --void CRenderer::Release(SElementV& list) -+long CRenderer::Release(SElementV& list) - { - SElementV l = list; - list.clear(); - -+ long count = 0; - for(SElementV::iterator it = l.begin(); it != l.end(); it++) - { - if(it->overlay) -- it->overlay->Release(); -+ count += it->overlay->Release(); - if(it->overlay_dvd) -- it->overlay_dvd->Release(); -+ count += it->overlay_dvd->Release(); - } -+ return count; - } - --void CRenderer::Release(COverlayV& list) -+long CRenderer::Release(COverlayV& list) - { - COverlayV l = list; - list.clear(); - -+ long count = 0; - for(COverlayV::iterator it = l.begin(); it != l.end(); it++) -- (*it)->Release(); -+ count += (*it)->Release(); -+ -+ return count; - } - - void CRenderer::Flush() -@@ -161,16 +166,19 @@ void CRenderer::Flush() - Release(m_cleanup); - } - --void CRenderer::Flip() -+void CRenderer::Flip(int source) - { - CSingleLock lock(m_section); -- m_render = (m_render + 1) % m_iNumBuffers; -+ if( source >= 0 && source < m_iNumBuffers ) -+ m_render = source; -+ else -+ m_render = (m_render + 1) % m_iNumBuffers; - } - --void CRenderer::ReleaseBuffer(int idx) -+long CRenderer::ReleaseBuffer(int idx) - { - CSingleLock lock(m_section); -- Release(m_buffers[idx]); -+ return Release(m_buffers[idx]); - } - - void CRenderer::Render() -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index 66c592a..627dd9f 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.h -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -96,11 +96,11 @@ - void AddOverlay(CDVDOverlay* o, double pts, int index); - void AddOverlay(COverlay* o, double pts, int index); - void AddCleanup(COverlay* o); -- void Flip(); -+ void Flip(int source); - void Render(); - void Flush(); - void SetNumBuffers(int numBuffers) { m_iNumBuffers = numBuffers; } -- void ReleaseBuffer(int idx); -+ long ReleaseBuffer(int idx); - - protected: - -@@ -123,8 +123,8 @@ - COverlay* Convert(CDVDOverlay* o, double pts); - COverlay* Convert(CDVDOverlaySSA* o, double pts); - -- void Release(COverlayV& list); -- void Release(SElementV& list); -+ long Release(COverlayV& list); -+ long Release(SElementV& list); - - CCriticalSection m_section; - SElementV m_buffers[NUM_BUFFERS]; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index f5cc0f6..e887313 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -303,7 +303,7 @@ void CXBMCRenderManager::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - if(m_presentstep == PRESENT_FLIP) - { - FlipRenderBuffer(); -- m_overlays.Flip(); -+ m_overlays.Flip(m_presentsource); - m_pRenderer->FlipPage(m_presentsource); - m_presentstep = PRESENT_FRAME; - m_presentevent.Set(); -@@ -703,7 +703,7 @@ void CXBMCRenderManager::Present() - if(m_presentstep == PRESENT_FLIP) - { - FlipRenderBuffer(); -- m_overlays.Flip(); -+ m_overlays.Flip(m_presentsource); - m_pRenderer->FlipPage(m_presentsource); - m_presentstep = PRESENT_FRAME; - m_presentevent.Set(); -@@ -986,11 +986,12 @@ int CXBMCRenderManager::FlipFreeBuffer() - // See "Render Buffer State Description" in header for information. - if (HasFreeBuffer()) - { -- if (!m_bRenderBufferUsed) -+ if (!m_bRenderBufferUsed && !m_bOverlayReleased) - { - return -1; - } - m_bRenderBufferUsed = false; -+ m_bOverlayReleased = false; - m_bAllRenderBuffersDisplayed = false; - m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; - return m_iOutputRenderBuffer; -@@ -1038,6 +1039,7 @@ void CXBMCRenderManager::ResetRenderBuffer() - m_presentPts = DVD_NOPTS_VALUE; - m_speed = 0; - m_bRenderBufferUsed = false; -+ m_bOverlayReleased = false; - } - - void CXBMCRenderManager::PrepareNextRender() -@@ -1116,7 +1118,8 @@ void CXBMCRenderManager::NotifyDisplayFlip() - && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) - { - m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -- m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer); -+ if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer) > 0) -+ m_bOverlayReleased = true; - } - } - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index afb6b1f..3f95793 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -252,6 +252,7 @@ class CXBMCRenderManager - bool m_bCodecSupportsBuffering; - int m_speed; - bool m_bRenderBufferUsed; -+ bool m_bOverlayReleased; - CEvent m_flipEvent; - - struct --- -1.7.10 - - -From a0838293cf956be846f298e4bc5b6211e80f535a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 26 Feb 2013 09:00:21 +0100 -Subject: [PATCH 12/88] add buffering - submit absolute time to render buffers - ---- - xbmc/cores/IPlayer.h | 5 ----- - xbmc/cores/VideoRenderers/RenderManager.cpp | 20 +++----------------- - xbmc/cores/VideoRenderers/RenderManager.h | 5 ++--- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 5 ----- - xbmc/cores/dvdplayer/DVDPlayer.h | 2 -- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 6 files changed, 6 insertions(+), 33 deletions(-) - -diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h -index cbf2faa..f2aa227 100644 ---- a/xbmc/cores/IPlayer.h -+++ b/xbmc/cores/IPlayer.h -@@ -229,11 +229,6 @@ class IPlayer - */ - virtual void GetSubtitleCapabilities(std::vector &subCaps) { subCaps.assign(1,IPC_SUBS_ALL); }; - -- /*! -- \brief called by RenderManager in order to schedule frames -- */ -- virtual double GetClock(double& absolute, bool interpolated = true) {return 0; }; -- - protected: - IPlayerCallback& m_callback; - }; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index e887313..a2001c0 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -571,7 +571,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - { CRetakeLock lock(m_sharedSection); - if(!m_pRenderer) return; - -- double presenttime = timestamp; - EFIELDSYNC presentfield = sync; - EPRESENTMETHOD presentmethod; - -@@ -614,7 +613,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - - if (FlipFreeBuffer() >= 0) - { -- m_renderBuffers[m_iOutputRenderBuffer].pts = timestamp; -+ m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; - m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; - m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; - } -@@ -1036,7 +1035,6 @@ void CXBMCRenderManager::ResetRenderBuffer() - m_iDisplayedRenderBuffer = 0; - m_bAllRenderBuffersDisplayed = true; - m_sleeptime = 1.0; -- m_presentPts = DVD_NOPTS_VALUE; - m_speed = 0; - m_bRenderBufferUsed = false; - m_bOverlayReleased = false; -@@ -1053,19 +1051,8 @@ void CXBMCRenderManager::PrepareNextRender() - return; - } - -- double iClockSleep, iPlayingClock, iCurrentClock; -- if (g_application.m_pPlayer) -- iPlayingClock = g_application.m_pPlayer->GetClock(iCurrentClock, false); -- else -- iPlayingClock = iCurrentClock = 0; -- -- iClockSleep = m_renderBuffers[idx].pts - iPlayingClock; -- -- if (m_speed) -- iClockSleep = iClockSleep * DVD_PLAYSPEED_NORMAL / m_speed; -- -- double presenttime = (iCurrentClock + iClockSleep) / DVD_TIME_BASE; -- double clocktime = iCurrentClock / DVD_TIME_BASE; -+ double presenttime = m_renderBuffers[idx].timestamp; -+ double clocktime = GetPresentTime(); - if(presenttime - clocktime > MAXPRESENTDELAY) - presenttime = clocktime + MAXPRESENTDELAY; - -@@ -1074,7 +1061,6 @@ void CXBMCRenderManager::PrepareNextRender() - - if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) - { -- m_presentPts = m_renderBuffers[idx].pts; - m_presenttime = presenttime; - m_presentmethod = m_renderBuffers[idx].presentmethod; - m_presentfield = m_renderBuffers[idx].presentfield; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 3f95793..858a547 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -93,7 +93,7 @@ class CXBMCRenderManager - * available after the main thread has flipped front / back buffers. - * - * @param bStop reference to stop flag of calling thread -- * @param timestamp pts of frame delivered with AddVideoPicture -+ * @param timestamp of frame delivered with AddVideoPicture - * @param source depreciated - * @param sync signals frame, top, or bottom field - * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind -@@ -257,13 +257,12 @@ class CXBMCRenderManager - - struct - { -- double pts; -+ double timestamp; - EFIELDSYNC presentfield; - EPRESENTMETHOD presentmethod; - }m_renderBuffers[5]; - - double m_sleeptime; -- double m_presentPts; - - double m_presenttime; - double m_presentcorr; -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index dfb317f..0cd2510 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -4075,8 +4075,3 @@ bool CDVDPlayer::CachePVRStream(void) const - !g_PVRManager.IsPlayingRecording() && - g_advancedSettings.m_bPVRCacheInDvdPlayer; - } -- --double CDVDPlayer::GetClock(double& absolute, bool interpolated) --{ -- return m_clock.GetClock(absolute, interpolated); --} -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index 093318e..d3c201e 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -252,8 +252,6 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer - virtual bool SwitchChannel(const PVR::CPVRChannel &channel); - virtual bool CachePVRStream(void) const; - -- virtual double GetClock(double& absolute, bool interpolated = true); -- - enum ECacheState - { CACHESTATE_DONE = 0 - , CACHESTATE_FULL // player is filling up the demux queue -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 3bfe180..a90c141 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1363,7 +1363,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - if (index < 0) - return EOS_DROPPED; - -- g_renderManager.FlipPage(CThread::m_bStop, pts, -1, mDisplayField, m_speed); -+ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField, m_speed); - - return result; - #else --- -1.7.10 - - -From aee70c4018b40358ff2e8a98727ccb55be65da63 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 08:05:00 +0100 -Subject: [PATCH 13/88] RenderManager: some rework, squash add buffering - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index a2001c0..09daaef 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -616,6 +616,8 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; - m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; - m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; -+ if (!m_bUseBuffering) -+ PrepareNextRender(); - } - m_speed = speed; - } -@@ -825,17 +827,17 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - if (!m_pRenderer) - return -1; - -- if(m_pRenderer->AddVideoPicture(&pic, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers)) -+ int index = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; -+ -+ if(m_pRenderer->AddVideoPicture(&pic, index)) - { - m_bRenderBufferUsed = true; - return 1; - } - - YV12Image image; -- int index = m_pRenderer->GetImage(&image, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); -- -- if(index < 0) -- return index; -+ if (m_pRenderer->GetImage(&image, index) < 0) -+ return -1; - - if(pic.format == RENDER_FMT_YUV420P - || pic.format == RENDER_FMT_YUV420P10 -@@ -947,14 +949,14 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) - if (!m_pRenderer) - return -1; - -- double maxwait = GetPresentTime() + (float)timeout/1000; -+ XbmcThreads::EndTime endtime(timeout); - while(!HasFreeBuffer() && !bStop) - { - lock.Leave(); - m_flipEvent.WaitMSec(std::min(50, timeout)); -- if(GetPresentTime() > maxwait && !bStop) -+ if(endtime.IsTimePast()) - { -- if (timeout != 0) -+ if (timeout != 0 && !bStop) - CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); - return -1; - } --- -1.7.10 - - -From 927a0787cf8c8eb9d87e1c39f1abc4adc680235a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 08:07:07 +0100 -Subject: [PATCH 14/88] dvdplayer: disable buffering unil dropping is improved - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index a90c141..c02bb96 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1100,35 +1100,35 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - { - case RENDER_FMT_YUV420P: - formatstr = "YV12"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_YUV420P16: - formatstr = "YV12P16"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_YUV420P10: - formatstr = "YV12P10"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_NV12: - formatstr = "NV12"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_UYVY422: - formatstr = "UYVY"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_YUYV422: - formatstr = "YUY2"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_VDPAU: - formatstr = "VDPAU"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_DXVA: - formatstr = "DXVA"; -- buffering = true; -+ buffering = false; - break; - case RENDER_FMT_VAAPI: - formatstr = "VAAPI"; --- -1.7.10 - - -From b4dba473cb37652a888d8a47cb37d4f489ff8133 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:00:51 +0100 -Subject: [PATCH 15/88] RenderManager: skip very late frames in render buffer - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 09daaef..9897f1c 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1053,13 +1053,30 @@ void CXBMCRenderManager::PrepareNextRender() - return; - } - -- double presenttime = m_renderBuffers[idx].timestamp; - double clocktime = GetPresentTime(); -+ double frametime = 1 / g_graphicsContext.GetFPS(); -+ -+ // look ahead in the queue -+ // if the next frame is already late, skip the one we are about to render -+ while (idx != m_iOutputRenderBuffer) -+ { -+ int idx_next = (idx + 1) % m_iNumRenderBuffers; -+ if (m_renderBuffers[idx_next].timestamp <= clocktime) -+ { -+ FlipRenderBuffer(); -+ idx = GetNextRenderBufferIndex(); -+ CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); -+ } -+ else -+ break; -+ } -+ -+ double presenttime = m_renderBuffers[idx].timestamp; -+ - if(presenttime - clocktime > MAXPRESENTDELAY) - presenttime = clocktime + MAXPRESENTDELAY; - - m_sleeptime = presenttime - clocktime; -- double frametime = 1 / g_graphicsContext.GetFPS(); - - if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) - { --- -1.7.10 - - -From c77b0cded556ed2e5a83df8df37278cc40490123 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:10:17 +0100 -Subject: [PATCH 16/88] renderbuffers: drop enable/disable in this iteration - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 4 ++++ - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 ---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 9897f1c..e479adc 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -266,6 +266,7 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi - m_presentstep = PRESENT_IDLE; - m_presentevent.Set(); - ResetRenderBuffer(); -+ EnableBuffering(buffering); - } - - return result; -@@ -1093,7 +1094,10 @@ void CXBMCRenderManager::EnableBuffering(bool enable) - CRetakeLock lock(m_sharedSection); - - if (m_iNumRenderBuffers < 3) -+ { -+ m_bUseBuffering = false; - return; -+ } - - m_bUseBuffering = enable; - if (!m_bUseBuffering) -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index c02bb96..1d3c7e3 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -261,7 +261,6 @@ void CDVDPlayerVideo::OpenStream(CDVDStreamInfo &hint, CDVDVideoCodec* codec) - m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; - m_started = false; - m_codecname = m_pVideoCodec->GetName(); -- g_renderManager.EnableBuffering(false); - } - - void CDVDPlayerVideo::CloseStream(bool bWaitForBuffers) -@@ -437,7 +436,6 @@ void CDVDPlayerVideo::Process() - picture.iFlags &= ~DVP_FLAG_ALLOCATED; - m_packets.clear(); - m_started = false; -- g_renderManager.EnableBuffering(false); - } - else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) - { -@@ -450,7 +448,6 @@ void CDVDPlayerVideo::Process() - //we need to recalculate the framerate - //TODO: this needs to be set on a streamchange instead - ResetFrameRateCalc(); -- g_renderManager.EnableBuffering(false); - - m_stalled = true; - m_started = false; -@@ -705,7 +702,6 @@ void CDVDPlayerVideo::Process() - m_codecname = m_pVideoCodec->GetName(); - m_started = true; - m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO)); -- g_renderManager.EnableBuffering(true); - } - - // guess next frame pts. iDuration is always valid --- -1.7.10 - - -From 094da266d519fd5385ca99866817f7b51944a0c0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:31:11 +0100 -Subject: [PATCH 17/88] RenderManager: add method SetSpeed - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 10 +++++++--- - xbmc/cores/VideoRenderers/RenderManager.h | 8 ++++++-- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 3 ++- - 3 files changed, 15 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index e479adc..dc984cf 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -550,7 +550,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) - m_pRenderer->SetViewMode(iViewMode); - } - --void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/, int speed /*= 1000*/) -+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) - { - if (!m_bUseBuffering) - { -@@ -620,7 +620,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - if (!m_bUseBuffering) - PrepareNextRender(); - } -- m_speed = speed; - } - - g_application.NewFrame(); -@@ -1038,7 +1037,7 @@ void CXBMCRenderManager::ResetRenderBuffer() - m_iDisplayedRenderBuffer = 0; - m_bAllRenderBuffersDisplayed = true; - m_sleeptime = 1.0; -- m_speed = 0; -+ m_speed = DVD_PLAYSPEED_NORMAL; - m_bRenderBufferUsed = false; - m_bOverlayReleased = false; - } -@@ -1112,6 +1111,11 @@ void CXBMCRenderManager::DiscardBuffer() - m_iOutputRenderBuffer = m_iCurrentRenderBuffer; - } - -+void CXBMCRenderManager::SetSpeed(int speed) -+{ -+ m_speed = speed; -+} -+ - void CXBMCRenderManager::NotifyDisplayFlip() - { - CRetakeLock lock(m_sharedSection); -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index 858a547..c9edb64 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -96,9 +96,8 @@ class CXBMCRenderManager - * @param timestamp of frame delivered with AddVideoPicture - * @param source depreciated - * @param sync signals frame, top, or bottom field -- * @param speed current speed of player, needed for some optimizations like keeping the gui responsive on rewind - */ -- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE, int speed = 1000); -+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); - unsigned int PreInit(); - void UnInit(); - bool Flush(); -@@ -188,6 +187,11 @@ class CXBMCRenderManager - */ - void DiscardBuffer(); - -+ /** -+ * notify RenderManager about play speed -+ */ -+ void SetSpeed(int speed); -+ - protected: - void Render(bool clear, DWORD flags, DWORD alpha); - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 1d3c7e3..db4f7bd 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -465,6 +465,7 @@ void CDVDPlayerVideo::Process() - m_speed = static_cast(pMsg)->m_value; - if(m_speed == DVD_PLAYSPEED_PAUSE) - m_iNrOfPicturesNotToSkip = 0; -+ g_renderManager.SetSpeed(m_speed); - } - else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) - { -@@ -1359,7 +1360,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - if (index < 0) - return EOS_DROPPED; - -- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField, m_speed); -+ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); - - return result; - #else --- -1.7.10 - - -From e46b7cb93cc01827dc03966dd8f0d3cbdbbc8f60 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 10 Feb 2013 18:40:30 +0100 -Subject: [PATCH 18/88] OMXPlayer: adapt to buffering - ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 25 ++++++++----------------- - 1 file changed, 8 insertions(+), 17 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 4d813db..8b1c06e 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -359,7 +359,7 @@ void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) - - if(!g_renderManager.Configure(m_hints.width, m_hints.height, - iDisplayWidth, iDisplayHeight, m_fps, flags, format, 0, -- m_hints.orientation)) -+ m_hints.orientation, true)) - { - CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); - return; -@@ -453,25 +453,16 @@ void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) - m_dropbase = 0.0f; - #endif - -- // DVDPlayer sleeps until m_iSleepEndTime here before calling FlipPage. -- // Video playback in asynchronous in OMXPlayer, so we don't want to do that here, as it prevents the video fifo from being kept full. -- // So, we keep track of when FlipPage would have been called on DVDPlayer and return early if it is not time. -- // m_iSleepEndTime == DVD_NOPTS_VALUE means we are not waiting to call FlipPage, otherwise it is the time we want to call FlipPage -- if (m_iSleepEndTime == DVD_NOPTS_VALUE) { -- m_iSleepEndTime = iCurrentClock + iSleepTime; -- } -- -- if (!CThread::m_bStop && m_av_clock->GetAbsoluteClock(false) < m_iSleepEndTime + DVD_MSEC_TO_TIME(500)) -+ int buffer = g_renderManager.WaitForBuffer(m_bStop, 0); -+ if (buffer < 0) - return; - -- double pts_media = m_av_clock->OMXMediaTime(false, false); -- ProcessOverlays(iGroupId, pts_media); -- -- g_renderManager.FlipPage(CThread::m_bStop, m_iSleepEndTime / DVD_TIME_BASE, -1, FS_NONE); -- -- m_iSleepEndTime = DVD_NOPTS_VALUE; -+ double pts_overlay = m_av_clock->OMXMediaTime(false, false) -+ + 2* (double)DVD_TIME_BASE / g_graphicsContext.GetFPS(); -+ ProcessOverlays(iGroupId, pts_overlay); - -- //m_av_clock->WaitAbsoluteClock((iCurrentClock + iSleepTime)); -+ double timestamp = CDVDClock::GetAbsoluteClock(false) + 2 / g_graphicsContext.GetFPS(); -+ g_renderManager.FlipPage(CThread::m_bStop, timestamp, -1, FS_NONE); - } - - void OMXPlayerVideo::Process() --- -1.7.10 - - -From b4f1ed7fd41c48b9ec199cce6854d6f2e25f53c0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 20:42:10 +0100 -Subject: [PATCH 19/88] overlays: squash to - b0b5c7c825b0265c5e7c888a48a76d11eb719246 - ---- - xbmc/cores/VideoRenderers/OverlayRenderer.cpp | 19 +++++++++---------- - xbmc/cores/VideoRenderers/OverlayRenderer.h | 4 ++-- - xbmc/cores/VideoRenderers/RenderManager.cpp | 4 +++- - 3 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -index 5592eca..8559720 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.cpp -@@ -127,32 +127,31 @@ void CRenderer::AddCleanup(COverlay* o) - m_cleanup.push_back(o->Acquire()); - } - --long CRenderer::Release(SElementV& list) -+bool CRenderer::Release(SElementV& list) - { - SElementV l = list; - list.clear(); - -- long count = 0; -+ bool change = false; - for(SElementV::iterator it = l.begin(); it != l.end(); it++) - { - if(it->overlay) -- count += it->overlay->Release(); -+ it->overlay->Release(); - if(it->overlay_dvd) -- count += it->overlay_dvd->Release(); -+ it->overlay_dvd->Release(); -+ -+ change = true; - } -- return count; -+ return change; - } - --long CRenderer::Release(COverlayV& list) -+void CRenderer::Release(COverlayV& list) - { - COverlayV l = list; - list.clear(); - -- long count = 0; - for(COverlayV::iterator it = l.begin(); it != l.end(); it++) -- count += (*it)->Release(); -- -- return count; -+ (*it)->Release(); - } - - void CRenderer::Flush() -diff --git a/xbmc/cores/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoRenderers/OverlayRenderer.h -index 627dd9f..e0c497d 100644 ---- a/xbmc/cores/VideoRenderers/OverlayRenderer.h -+++ b/xbmc/cores/VideoRenderers/OverlayRenderer.h -@@ -123,8 +123,8 @@ - COverlay* Convert(CDVDOverlay* o, double pts); - COverlay* Convert(CDVDOverlaySSA* o, double pts); - -- long Release(COverlayV& list); -- long Release(SElementV& list); -+ void Release(COverlayV& list); -+ bool Release(SElementV& list); - - CCriticalSection m_section; - SElementV m_buffers[NUM_BUFFERS]; -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index dc984cf..1343a71 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -967,6 +967,8 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) - if (bStop) - return -1; - -+ // make sure overlay buffer is released, this won't happen on AddOverlay -+ m_overlays.ReleaseBuffer((m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); - return 1; - } - -@@ -1131,7 +1133,7 @@ void CXBMCRenderManager::NotifyDisplayFlip() - && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) - { - m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); -- if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer) > 0) -+ if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer)) - m_bOverlayReleased = true; - } - } --- -1.7.10 - - -From 652203771888444899ae4b2655224d4022278c56 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 20/88] videoplayer: adapt lateness detection and dropping to - buffering - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 17 +- - xbmc/cores/VideoRenderers/RenderManager.h | 11 +- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 14 ++ - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 31 +++ - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 7 + - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 226 ++++++++++++++++---- - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 24 +++ - 7 files changed, 282 insertions(+), 48 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index 1343a71..c4ca57e 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -550,7 +550,7 @@ void CXBMCRenderManager::SetViewMode(int iViewMode) - m_pRenderer->SetViewMode(iViewMode); - } - --void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) -+void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) - { - if (!m_bUseBuffering) - { -@@ -614,6 +614,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L - - if (FlipFreeBuffer() >= 0) - { -+ m_renderBuffers[m_iOutputRenderBuffer].pts = pts; - m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; - m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; - m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; -@@ -1040,6 +1041,7 @@ void CXBMCRenderManager::ResetRenderBuffer() - m_bAllRenderBuffersDisplayed = true; - m_sleeptime = 1.0; - m_speed = DVD_PLAYSPEED_NORMAL; -+ m_presentPts = DVD_NOPTS_VALUE; - m_bRenderBufferUsed = false; - m_bOverlayReleased = false; - } -@@ -1082,6 +1084,7 @@ void CXBMCRenderManager::PrepareNextRender() - - if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) - { -+ m_presentPts = m_renderBuffers[idx].pts; - m_presenttime = presenttime; - m_presentmethod = m_renderBuffers[idx].presentmethod; - m_presentfield = m_renderBuffers[idx].presentfield; -@@ -1142,6 +1145,18 @@ void CXBMCRenderManager::NotifyDisplayFlip() - m_flipEvent.Set(); - } - -+bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel) -+{ -+ CSharedLock lock(m_sharedSection); -+ sleeptime = m_sleeptime; -+ pts = m_presentPts; -+ if (m_iNumRenderBuffers < 3) -+ bufferLevel = -1; -+ else -+ bufferLevel = (m_iOutputRenderBuffer - m_iCurrentRenderBuffer + m_iNumRenderBuffers) % m_iNumRenderBuffers; -+ return true; -+} -+ - bool CXBMCRenderManager::HasFrame() - { - CSharedLock lock(m_sharedSection); -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index c9edb64..b3e6547 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -94,10 +94,11 @@ class CXBMCRenderManager - * - * @param bStop reference to stop flag of calling thread - * @param timestamp of frame delivered with AddVideoPicture -+ * @param pts used for lateness detection - * @param source depreciated - * @param sync signals frame, top, or bottom field - */ -- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); -+ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); - unsigned int PreInit(); - void UnInit(); - bool Flush(); -@@ -177,6 +178,12 @@ class CXBMCRenderManager - bool HasFrame(); - - /** -+ * Can be called by player for lateness detection. This is done best by -+ * looking at the end of the queue. -+ */ -+ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); -+ -+ /** - * Video player can dynamically enable/disable buffering. In situations like - * rewind buffering is not ideal. - */ -@@ -261,12 +268,14 @@ class CXBMCRenderManager - - struct - { -+ double pts; - double timestamp; - EFIELDSYNC presentfield; - EPRESENTMETHOD presentmethod; - }m_renderBuffers[5]; - - double m_sleeptime; -+ double m_presentPts; - - double m_presenttime; - double m_presentcorr; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 1d8bad3..5001aac 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -110,6 +110,10 @@ struct DVDVideoUserData - #define DVP_FLAG_NOSKIP 0x00000010 // indicate this picture should never be dropped - #define DVP_FLAG_DROPPED 0x00000020 // indicate that this picture has been dropped in decoder stage, will have no data - -+#define DVP_FLAG_DROPDEINT 0x00000040 // indicate that this picture was requested to have been dropped in deint stage -+#define DVP_FLAG_NO_POSTPROC 0x00000100 -+#define DVP_FLAG_DRAIN 0x00000200 -+ - // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2! - - #define DVP_QSCALE_UNKNOWN 0 -@@ -127,6 +131,9 @@ struct DVDVideoUserData - #define VC_PICTURE 0x00000004 // the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data - #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data - #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again -+#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped -+#define VC_HURRY 0x00000040 -+ - class CDVDVideoCodec - { - public: -@@ -237,4 +244,11 @@ class CDVDVideoCodec - { - return 0; - } -+ -+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) -+ { -+ return false; -+ } -+ -+ virtual void SetCodecControl(int flags) {} - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 286fd67..dae3b8e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -142,6 +142,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - m_iLastKeyframe = 0; - m_dts = DVD_NOPTS_VALUE; - m_started = false; -+ m_decoderPts = DVD_NOPTS_VALUE; - } - - CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() -@@ -340,6 +341,14 @@ void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop) - { - if( m_pCodecContext ) - { -+ if (bDrop && m_pHardware && m_pHardware->CanSkipDeint()) -+ { -+ m_requestSkipDeint = true; -+ bDrop = false; -+ } -+ else -+ m_requestSkipDeint = false; -+ - // i don't know exactly how high this should be set - // couldn't find any good docs on it. think it varies - // from codec to codec on what it does -@@ -541,6 +550,7 @@ int CDVDVideoCodecFFmpeg::Decode(BYTE* pData, int iSize, double dts, double pts) - void CDVDVideoCodecFFmpeg::Reset() - { - m_started = false; -+ m_decoderPts = DVD_NOPTS_VALUE; - m_iLastKeyframe = m_pCodecContext->has_b_frames; - m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); - -@@ -639,6 +649,22 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) - else - pDvdVideoPicture->pts = DVD_NOPTS_VALUE; - -+ if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE) -+ m_decoderPts = pDvdVideoPicture->pts; -+ else -+ m_decoderPts = m_dts; -+ -+ if (m_requestSkipDeint) -+ { -+ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPDEINT; -+ m_skippedDeint = 1; -+ } -+ else -+ m_skippedDeint = 0; -+ -+ m_requestSkipDeint = false; -+ pDvdVideoPicture->iFlags |= m_codecControlFlags; -+ - if(!m_started) - pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; - -@@ -861,3 +887,8 @@ unsigned CDVDVideoCodecFFmpeg::GetConvergeCount() - else - return 0; - } -+ -+void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) -+{ -+ m_codecControlFlags = flags; -+} -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 61d0305..52e1113 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -44,6 +44,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec - virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) = 0; - virtual int Check (AVCodecContext* avctx) = 0; - virtual void Reset () {} -+ virtual bool CanSkipDeint() {return false; } - virtual const std::string Name() = 0; - virtual CCriticalSection* Section() { return NULL; } - }; -@@ -60,6 +61,8 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec - virtual unsigned int SetFilters(unsigned int filters); - virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open - virtual unsigned GetConvergeCount(); -+ virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} -+ virtual void SetCodecControl(int flags); - - bool IsHardwareAllowed() { return !m_bSoftware; } - IHardwareDecoder * GetHardware() { return m_pHardware; }; -@@ -119,4 +122,8 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec - double m_dts; - bool m_started; - std::vector m_formats; -+ double m_decoderPts, m_decoderInterval; -+ int m_skippedDeint; -+ bool m_requestSkipDeint; -+ int m_codecControlFlags; - }; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index db4f7bd..5484073 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -325,8 +325,10 @@ void CDVDPlayerVideo::Process() - - int iDropped = 0; //frames dropped in a row - bool bRequestDrop = false; -+ int iDropDirective; - - m_videoStats.Start(); -+ m_droppingStats.Reset(); - - while (!m_bStop) - { -@@ -436,6 +438,7 @@ void CDVDPlayerVideo::Process() - picture.iFlags &= ~DVP_FLAG_ALLOCATED; - m_packets.clear(); - m_started = false; -+ m_droppingStats.Reset(); - } - else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) - { -@@ -448,6 +451,7 @@ void CDVDPlayerVideo::Process() - //we need to recalculate the framerate - //TODO: this needs to be set on a streamchange instead - ResetFrameRateCalc(); -+ m_droppingStats.Reset(); - - m_stalled = true; - m_started = false; -@@ -466,6 +470,7 @@ void CDVDPlayerVideo::Process() - if(m_speed == DVD_PLAYSPEED_PAUSE) - m_iNrOfPicturesNotToSkip = 0; - g_renderManager.SetSpeed(m_speed); -+ m_droppingStats.Reset(); - } - else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) - { -@@ -500,6 +505,28 @@ void CDVDPlayerVideo::Process() - m_iNrOfPicturesNotToSkip = 1; - } - -+ bRequestDrop = false; -+ iDropDirective = CalcDropRequirement(pts); -+ if (iDropDirective & EOS_VERYLATE) -+ { -+ if (m_bAllowDrop) -+ { -+ m_pullupCorrection.Flush(); -+ bRequestDrop = true; -+ } -+ } -+ int codecControl = 0; -+ if (iDropDirective & EOS_BUFFER_LEVEL) -+ codecControl |= DVP_FLAG_DRAIN; -+ if (m_speed > DVD_PLAYSPEED_NORMAL) -+ codecControl |= DVP_FLAG_NO_POSTPROC; -+ m_pVideoCodec->SetCodecControl(codecControl); -+ if (iDropDirective & EOS_DROPPED) -+ { -+ m_iDroppedFrames++; -+ iDropped++; -+ } -+ - #ifdef PROFILE - bRequestDrop = false; - #else -@@ -509,6 +536,7 @@ void CDVDPlayerVideo::Process() - bRequestDrop = false; - m_iDroppedRequest = 0; - m_iLateFrames = 0; -+ m_droppingStats.m_requestOutputDrop = false; - } - #endif - -@@ -556,15 +584,8 @@ void CDVDPlayerVideo::Process() - } - - m_videoStats.AddSampleBytes(pPacket->iSize); -- // assume decoder dropped a picture if it didn't give us any -- // picture from a demux packet, this should be reasonable -- // for libavformat as a demuxer as it normally packetizes -- // pictures when they come from demuxer -- if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE)) -- { -- m_iDroppedFrames++; -- iDropped++; -- } -+ -+ bRequestDrop = false; - - // loop while no error - while (!m_bStop) -@@ -1255,50 +1276,30 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - m_FlipTimeStamp += max(0.0, iSleepTime); - m_FlipTimeStamp += iFrameDuration; - -- if (iSleepTime <= 0 && m_speed) -- m_iLateFrames++; -- else -- m_iLateFrames = 0; -- -- // ask decoder to drop frames next round, as we are very late -- if(m_iLateFrames > 10) -- { -- if (!(pPicture->iFlags & DVP_FLAG_NOSKIP)) -- { -- //if we're calculating the framerate, -- //don't drop frames until we've calculated a stable framerate -- if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL) -- { -- result |= EOS_VERYLATE; -- m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it -- } -- -- //if we requested 5 drops in a row and we're still late, drop on output -- //this keeps a/v sync if the decoder can't drop, or we're still calculating the framerate -- if (m_iDroppedRequest > 5) -- { -- m_iDroppedRequest--; //decrease so we only drop half the frames -- return result | EOS_DROPPED; -- } -- m_iDroppedRequest++; -- } -- } -- else -+ if ((m_droppingStats.m_requestOutputDrop && !(pPicture->iFlags & DVP_FLAG_NOSKIP)) -+ || (pPicture->iFlags & DVP_FLAG_DROPPED)) - { -- m_iDroppedRequest = 0; -+ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); -+ m_droppingStats.m_requestOutputDrop = false; -+ CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__); -+ return result | EOS_DROPPED; - } - - if( m_speed < 0 ) - { -- if( iClockSleep < -DVD_MSEC_TO_TIME(200) -- && !(pPicture->iFlags & DVP_FLAG_NOSKIP) ) -+ double decoderPts = m_droppingStats.m_lastDecoderPts; -+ double renderPts = m_droppingStats.m_lastRenderPts; -+ if (pts > renderPts) -+ { -+ if (decoderPts >= renderPts) -+ { -+ Sleep(200); -+ } - return result | EOS_DROPPED; -+ } - } - -- if( (pPicture->iFlags & DVP_FLAG_DROPPED) ) -- return result | EOS_DROPPED; -- -- if( m_speed != DVD_PLAYSPEED_NORMAL && limited ) -+ if( m_speed != DVD_PLAYSPEED_NORMAL && m_speed >= 0 && limited ) - { - // calculate frame dropping pattern to render at this speed - // we do that by deciding if this or next frame is closest -@@ -1360,7 +1361,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - if (index < 0) - return EOS_DROPPED; - -- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); -+ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); - - return result; - #else -@@ -1659,3 +1660,136 @@ void CDVDPlayerVideo::CalcFrameRate() - m_iFrameRateCount = 0; - } - } -+ -+int CDVDPlayerVideo::CalcDropRequirement(double pts) -+{ -+ int result = 0; -+ double iSleepTime; -+ double iDecoderPts, iRenderPts; -+ double iInterval; -+ int interlaced; -+ double iGain; -+ double iLateness; -+ bool bNewFrame; -+ int iSkippedDeint = 0; -+ int iBufferLevel; -+ -+ // get decoder stats -+ if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) -+ iDecoderPts = pts; -+ if (iDecoderPts == DVD_NOPTS_VALUE) -+ iDecoderPts = pts; -+ -+ // get render stats -+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); -+ -+ if (iBufferLevel < 0) -+ result |= EOS_BUFFER_LEVEL; -+ else if (iBufferLevel < 2) -+ { -+ result |= EOS_BUFFER_LEVEL; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - hurry: %d", iBufferLevel); -+ } -+ -+ bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts; -+ -+ if (interlaced) -+ iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE; -+ else -+ iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; -+ -+ if (m_droppingStats.m_lastDecoderPts > 0 -+ && bNewFrame -+ && m_bAllowDrop -+ && m_droppingStats.m_dropRequests > 0) -+ { -+ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE; -+ if (iSkippedDeint) -+ { -+ CDroppingStats::CGain gain; -+ gain.gain = 1/m_fFrameRate; -+ gain.pts = iDecoderPts; -+ m_droppingStats.m_gain.push_back(gain); -+ m_droppingStats.m_totalGain += gain.gain; -+ result |= EOS_DROPPED; -+ m_droppingStats.m_dropRequests = 0; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped de-interlacing cycle, Sleeptime: %f, Bufferlevel: %d", iSleepTime, iBufferLevel); -+ } -+ else if (iGain > 1/m_fFrameRate) -+ { -+ CDroppingStats::CGain gain; -+ gain.gain = iGain; -+ gain.pts = iDecoderPts; -+ m_droppingStats.m_gain.push_back(gain); -+ m_droppingStats.m_totalGain += iGain; -+ result |= EOS_DROPPED; -+ m_droppingStats.m_dropRequests = 0; -+ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped in decoder, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain); -+ } -+ } -+ m_droppingStats.m_lastDecoderPts = iDecoderPts; -+ -+ // subtract gains -+ while (!m_droppingStats.m_gain.empty() && -+ iRenderPts >= m_droppingStats.m_gain.front().pts) -+ { -+ m_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().gain; -+ m_droppingStats.m_gain.pop_front(); -+ } -+ -+ // calculate lateness -+ iLateness = iSleepTime + m_droppingStats.m_totalGain; -+ if (iLateness < 0 && m_speed) -+ { -+ if (bNewFrame) -+ m_droppingStats.m_lateFrames++; -+ -+ // if lateness is smaller than frametime, we observe this state -+ // for 10 cycles -+ if (m_droppingStats.m_lateFrames > 10 || iLateness < -2/m_fFrameRate) -+ { -+ // is frame allowed to skip -+ if (m_iNrOfPicturesNotToSkip <= 0) -+ { -+ result |= EOS_VERYLATE; -+ -+ // drop in output -+ if (m_droppingStats.m_dropRequests > 7 && g_graphicsContext.IsFullScreenVideo()) -+ { -+ m_droppingStats.m_dropRequests--; //decrease so we only drop half the frames -+ m_droppingStats.m_requestOutputDrop = true; -+ } -+ else if (bNewFrame) -+ m_droppingStats.m_dropRequests++; -+ } -+ } -+ } -+ else -+ { -+ m_droppingStats.m_dropRequests = 0; -+ m_droppingStats.m_lateFrames = 0; -+ m_droppingStats.m_requestOutputDrop = false; -+ } -+ m_droppingStats.m_lastRenderPts = iRenderPts; -+ return result; -+} -+ -+void CDroppingStats::Reset() -+{ -+ m_gain.clear(); -+ m_totalGain = 0; -+ m_lastDecoderPts = 0; -+ m_lastRenderPts = 0; -+ m_lateFrames = 0; -+ m_dropRequests = 0; -+ m_requestOutputDrop = false; -+} -+ -+void CDroppingStats::AddOutputDropGain(double pts, double frametime) -+{ -+ CDroppingStats::CGain gain; -+ gain.gain = frametime; -+ gain.pts = pts; -+ m_gain.push_back(gain); -+ m_totalGain += frametime; -+} -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index fe7e12c..4913712 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -37,6 +37,26 @@ - - #define VIDEO_PICTURE_QUEUE_SIZE 1 - -+class CDroppingStats -+{ -+public: -+ void Reset(); -+ void AddOutputDropGain(double pts, double frametime); -+ struct CGain -+ { -+ double gain; -+ double pts; -+ }; -+ std::deque m_gain; -+ double m_totalGain; -+ double m_lastDecoderPts; -+ double m_lastRenderPts; -+ unsigned int m_lateFrames; -+ unsigned int m_dropRequests; -+ bool m_requestOutputDrop; -+}; -+ -+ - class CDVDPlayerVideo : public CThread - { - public: -@@ -110,6 +130,7 @@ class CDVDPlayerVideo : public CThread - #define EOS_ABORT 1 - #define EOS_DROPPED 2 - #define EOS_VERYLATE 4 -+#define EOS_BUFFER_LEVEL 8 - - void AutoCrop(DVDVideoPicture* pPicture); - void AutoCrop(DVDVideoPicture *pPicture, RECT &crop); -@@ -135,6 +156,7 @@ class CDVDPlayerVideo : public CThread - - void ResetFrameRateCalc(); - void CalcFrameRate(); -+ int CalcDropRequirement(double pts); - - double m_fFrameRate; //framerate of the video currently playing - bool m_bCalcFrameRate; //if we should calculate the framerate from the timestamps -@@ -195,5 +217,7 @@ class CDVDPlayerVideo : public CThread - CPullupCorrection m_pullupCorrection; - - std::list m_packets; -+ -+ CDroppingStats m_droppingStats; - }; - --- -1.7.10 - - -From cf731f6c3d24d7e53ed79402b01666aa6dae0991 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 21/88] video player: present correct pts to user for a/v sync - (after buffering in renderer) - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 41 +++++++++++++++++++------------ - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 2 +- - 2 files changed, 26 insertions(+), 17 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 5484073..8ac5a32 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1260,22 +1260,6 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - else - iSleepTime = iFrameSleep + (iClockSleep - iFrameSleep) / m_autosync; - --#ifdef PROFILE /* during profiling, try to play as fast as possible */ -- iSleepTime = 0; --#endif -- -- // present the current pts of this frame to user, and include the actual -- // presentation delay, to allow him to adjust for it -- if( m_stalled ) -- m_iCurrentPts = DVD_NOPTS_VALUE; -- else -- m_iCurrentPts = pts - max(0.0, iSleepTime); -- -- // timestamp when we think next picture should be displayed based on current duration -- m_FlipTimeStamp = iCurrentClock; -- m_FlipTimeStamp += max(0.0, iSleepTime); -- m_FlipTimeStamp += iFrameDuration; -- - if ((m_droppingStats.m_requestOutputDrop && !(pPicture->iFlags & DVP_FLAG_NOSKIP)) - || (pPicture->iFlags & DVP_FLAG_DROPPED)) - { -@@ -1580,6 +1564,22 @@ void CDVDPlayerVideo::ResetFrameRateCalc() - g_advancedSettings.m_videoFpsDetect == 0; - } - -+double CDVDPlayerVideo::GetCurrentPts() -+{ -+ double iSleepTime, iRenderPts; -+ int iBufferLevel; -+ -+ // get render stats -+ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); -+ -+ if( m_stalled ) -+ iRenderPts = DVD_NOPTS_VALUE; -+ else -+ iRenderPts = iRenderPts - max(0.0, iSleepTime); -+ -+ return iRenderPts; -+} -+ - #define MAXFRAMERATEDIFF 0.01 - #define MAXFRAMESERR 1000 - -@@ -1698,6 +1698,15 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - else - iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; - -+ -+ m_FlipTimeStamp = m_pClock->GetAbsoluteClock() + max(0.0, iSleepTime) + iInterval; -+ -+ if( m_stalled ) -+ m_iCurrentPts = DVD_NOPTS_VALUE; -+ else -+ m_iCurrentPts = iRenderPts - max(0.0, iSleepTime); -+ -+ - if (m_droppingStats.m_lastDecoderPts > 0 - && bNewFrame - && m_bAllowDrop -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index 4913712..509d5f7 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -108,7 +108,7 @@ class CDVDPlayerVideo : public CThread - - bool InitializedOutputDevice(); - -- double GetCurrentPts() { return m_iCurrentPts; } -+ double GetCurrentPts(); - int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); } - - double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */ --- -1.7.10 - - -From 5e05def8121969dbf936848e2025e419e68335a5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 18:25:53 +0100 -Subject: [PATCH 22/88] videoplayer: some rework and documentation - ---- - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 29 ++++++++++++++++++-- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 11 ++++++++ - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 2 +- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 4 files changed, 40 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 5001aac..e84e65f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -132,7 +132,6 @@ struct DVDVideoUserData - #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data - #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again - #define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped --#define VC_HURRY 0x00000040 - - class CDVDVideoCodec - { -@@ -245,10 +244,36 @@ class CDVDVideoCodec - return 0; - } - -- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) -+ /** -+ * For calculation of dropping requirements player asks for some information. -+ * -+ * - pts : right after decoder, used to detect gaps (dropped frames in decoder) -+ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle -+ * instead of dropping a full frame -+ * - interlaced : when detecting gaps in pts, player needs to know whether -+ * it's interlaced or not -+ * -+ * If codec does not implement this method, pts of decoded frame at input -+ * video player is used. In case coded does post-proc and de-interlacing there -+ * may be quite some frames queued up between exit decoder and entry player. -+ */ -+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced) - { - return false; - } - -+ /** -+ * Codec can be informed by player with the following flags: -+ * -+ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off -+ * postprocessing and de-interlacing -+ * -+ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing. -+ * If video buffers in RenderManager are about to run dry, -+ * this is signaled to codec. Codec can wait for post-proc -+ * to be finished instead of returning empty and getting another -+ * packet. -+ * -+ */ - virtual void SetCodecControl(int flags) {} - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index dae3b8e..2c2353d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -888,6 +888,17 @@ unsigned CDVDVideoCodecFFmpeg::GetConvergeCount() - return 0; - } - -+bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced) -+{ -+ pts = m_decoderPts; -+ skippedDeint = m_skippedDeint; -+ if (m_pFrame) -+ interlaced = m_pFrame->interlaced_frame; -+ else -+ interlaced = 0; -+ return true; -+} -+ - void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) - { - m_codecControlFlags = flags; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 52e1113..3631f7f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -61,7 +61,7 @@ class CDVDVideoCodecFFmpeg : public CDVDVideoCodec - virtual unsigned int SetFilters(unsigned int filters); - virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open - virtual unsigned GetConvergeCount(); -- virtual bool GetPts(double &pts, int &skippedDeint, int &interlaced) {pts=m_decoderPts; skippedDeint=m_skippedDeint; if (m_pFrame) interlaced = m_pFrame->interlaced_frame; return true;} -+ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced); - virtual void SetCodecControl(int flags); - - bool IsHardwareAllowed() { return !m_bSoftware; } -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 8ac5a32..12b08ac 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1675,7 +1675,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - int iBufferLevel; - - // get decoder stats -- if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced)) -+ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) - iDecoderPts = pts; - if (iDecoderPts == DVD_NOPTS_VALUE) - iDecoderPts = pts; --- -1.7.10 - - -From 903e78e4320a8549eccd0a710eac7747032c18eb Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 09:57:16 +0100 -Subject: [PATCH 23/88] Revert "dvdplayer: disable buffering unit dropping is - improves" - -This reverts commit de1caf5686c1fb53cb7ab11b356e6c22770740db. ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 12b08ac..3297513 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1118,35 +1118,35 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - { - case RENDER_FMT_YUV420P: - formatstr = "YV12"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_YUV420P16: - formatstr = "YV12P16"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_YUV420P10: - formatstr = "YV12P10"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_NV12: - formatstr = "NV12"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_UYVY422: - formatstr = "UYVY"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_YUYV422: - formatstr = "YUY2"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_VDPAU: - formatstr = "VDPAU"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_DXVA: - formatstr = "DXVA"; -- buffering = false; -+ buffering = true; - break; - case RENDER_FMT_VAAPI: - formatstr = "VAAPI"; --- -1.7.10 - - -From 82974290389d5caa2692079301b167cb80323491 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 24/88] videoplayer: update frametime, it might change due to - fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 3297513..8eb2eda 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -719,6 +719,8 @@ void CDVDPlayerVideo::Process() - CDVDCodecUtils::FreePicture(pTempYUVPackedPicture); - #endif - -+ frametime = (double)DVD_TIME_BASE/m_fFrameRate; -+ - if(m_started == false) - { - m_codecname = m_pVideoCodec->GetName(); --- -1.7.10 - - -From 5b62f34f8013302cd10c06944120032ec1f8d555 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 25/88] videoplayer: give streams with invalid fps a chance - for fps detection - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 8eb2eda..d004153 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1606,7 +1606,7 @@ void CDVDPlayerVideo::CalcFrameRate() - double frameduration = m_pullupCorrection.GetFrameDuration(); - - if (frameduration == DVD_NOPTS_VALUE || -- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) -+ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) - { - //reset the stored framerates if no good framerate was detected - m_fStableFrameRate = 0.0; --- -1.7.10 - - -From 7493aa51685421085be83c56c62267709b22c65f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 26/88] dvdplayer: allow rewinding at end of stream, do a seek - after rewind - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 0cd2510..3737419 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1542,7 +1542,7 @@ void CDVDPlayer::HandlePlaySpeed() - - } - else if (m_CurrentVideo.id >= 0 -- && m_CurrentVideo.inited == true -+ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file - && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() - && m_SpeedState.lasttime != GetTime()) - { -@@ -2183,6 +2183,12 @@ void CDVDPlayer::HandleMessages() - pvrinputstream->Pause( speed == 0 ); - } - -+ // do a seek after rewind, clock is not in sync with current pts -+ if (m_playSpeed < 0 && speed >= 0) -+ { -+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ } -+ - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE - // audioplayer, stops outputing audio to audiorendere, but still tries to - // sleep an correct amount for each packet --- -1.7.10 - - -From 4ae2ba6880415872258c400fae19e58307ed4828 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 7 Apr 2012 09:19:00 +0200 -Subject: [PATCH 27/88] vdpau: redesign - ---- - language/English/strings.po | 12 +- - system/shaders/yuv2rgb_basic.glsl | 12 + - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 203 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 13 +- - xbmc/cores/VideoRenderers/RenderFormats.h | 1 + - xbmc/cores/VideoRenderers/RenderManager.cpp | 3 +- - xbmc/cores/VideoRenderers/RenderManager.h | 2 +- - .../VideoRenderers/VideoShaders/YUV2RGBShader.cpp | 2 + - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 +- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 23 +- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 1 - - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 3800 +++++++++++++++----- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 662 +++- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 + - xbmc/settings/AdvancedSettings.cpp | 8 +- - xbmc/settings/AdvancedSettings.h | 4 +- - xbmc/settings/GUISettings.cpp | 2 + - xbmc/settings/GUIWindowSettingsCategory.cpp | 34 + - xbmc/utils/ActorProtocol.cpp | 253 ++ - xbmc/utils/ActorProtocol.h | 87 + - xbmc/utils/Makefile | 1 + - xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 2 +- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 23 files changed, 3942 insertions(+), 1192 deletions(-) - create mode 100644 xbmc/utils/ActorProtocol.cpp - create mode 100644 xbmc/utils/ActorProtocol.h - -diff --git a/language/English/strings.po b/language/English/strings.po -index dff2978..88292d3 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5114,7 +5114,15 @@ msgctxt "#13434" - msgid "Play only this" - msgstr "" - --#empty strings from id 13435 to 13499 -+msgctxt "#13435" -+msgid "Allow Vdpau OpenGL interop" -+msgstr "" -+ -+msgctxt "#13436" -+msgid "Allow Vdpau OpenGL interop YUV" -+msgstr "" -+ -+#empty strings from id 13437 to 13499 - - msgctxt "#13500" - msgid "A/V sync method" -@@ -6333,7 +6341,7 @@ msgid "Software Blend" - msgstr "" - - msgctxt "#16325" --msgid "Auto - ION Optimized" -+msgid "VDPAU - Bob" - msgstr "" - - #empty strings from id 16326 to 16399 -diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl -index 88c33b2..aa26174 100644 ---- a/system/shaders/yuv2rgb_basic.glsl -+++ b/system/shaders/yuv2rgb_basic.glsl -@@ -70,6 +70,18 @@ void main() - rgb.a = gl_Color.a; - gl_FragColor = rgb; - -+#elif defined(XBMC_VDPAU_NV12) -+ -+ vec4 yuv, rgb; -+ yuv.rgba = vec4( texture2D(m_sampY, stretch(m_cordY)).r -+ , texture2D(m_sampU, stretch(m_cordU)).r -+ , texture2D(m_sampV, stretch(m_cordV)).g -+ , 1.0 ); -+ -+ rgb = m_yuvmat * yuv; -+ rgb.a = gl_Color.a; -+ gl_FragColor = rgb; -+ - #elif defined(XBMC_YUY2) || defined(XBMC_UYVY) - - #if(XBMC_texture_rectangle) -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index a2dc2be..4ee50c1 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -689,6 +689,18 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - glDisable(GL_POLYGON_STIPPLE); - - } -+ else if(m_format == RENDER_FMT_VDPAU_420 -+ && !(flags & RENDER_FLAG_BOTH)) -+ { -+ glDisable(GL_BLEND); -+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f); -+ Render(flags | RENDER_FLAG_TOP, index); -+ -+ glEnable(GL_BLEND); -+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -+ glColor4f(1.0f, 1.0f, 1.0f, 128 / 255.0f); -+ Render(flags | RENDER_FLAG_BOT , index); -+ } - else - Render(flags, index); - -@@ -769,11 +781,6 @@ void CLinuxRendererGL::FlipPage(int source) - - m_buffers[m_iYV12RenderBuffer].flipindex = ++m_flipindex; - --#ifdef HAVE_LIBVDPAU -- if((m_renderMethod & RENDER_VDPAU) && m_buffers[m_iYV12RenderBuffer].vdpau) -- m_buffers[m_iYV12RenderBuffer].vdpau->Present(); --#endif -- - return; - } - -@@ -1100,6 +1107,12 @@ void CLinuxRendererGL::LoadShaders(int field) - m_textureCreate = &CLinuxRendererGL::CreateVDPAUTexture; - m_textureDelete = &CLinuxRendererGL::DeleteVDPAUTexture; - } -+ else if (m_format == RENDER_FMT_VDPAU_420) -+ { -+ m_textureUpload = &CLinuxRendererGL::UploadVDPAUTexture420; -+ m_textureCreate = &CLinuxRendererGL::CreateVDPAUTexture420; -+ m_textureDelete = &CLinuxRendererGL::DeleteVDPAUTexture420; -+ } - else if (m_format == RENDER_FMT_VAAPI) - { - m_textureUpload = &CLinuxRendererGL::UploadVAAPITexture; -@@ -1175,7 +1188,10 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - m_currentField = FIELD_FULL; - - // call texture load function -+ m_skipRender = false; - (this->*m_textureUpload)(renderBuffer); -+ if (m_skipRender) -+ return; - - if (m_renderMethod & RENDER_GLSL) - { -@@ -1541,17 +1557,12 @@ void CLinuxRendererGL::RenderFromFBO() - void CLinuxRendererGL::RenderVDPAU(int index, int field) - { - #ifdef HAVE_LIBVDPAU -- YUVPLANE &plane = m_buffers[index].fields[field][0]; -- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; -- -- if (!vdpau) -- return; -+ YUVPLANE &plane = m_buffers[index].fields[0][1]; - - glEnable(m_textureTarget); - glActiveTextureARB(GL_TEXTURE0); -- glBindTexture(m_textureTarget, plane.id); - -- vdpau->BindPixmap(); -+ glBindTexture(m_textureTarget, plane.id); - - // Try some clamping or wrapping - glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -@@ -1609,8 +1620,6 @@ void CLinuxRendererGL::RenderVDPAU(int index, int field) - if (m_pVideoFilterShader) - m_pVideoFilterShader->Disable(); - -- vdpau->ReleasePixmap(); -- - glBindTexture (m_textureTarget, 0); - glDisable(m_textureTarget); - #endif -@@ -2295,12 +2304,14 @@ void CLinuxRendererGL::DeleteVDPAUTexture(int index) - { - #ifdef HAVE_LIBVDPAU - YUVPLANE &plane = m_buffers[index].fields[0][0]; -+ YUVFIELDS &fields = m_buffers[index].fields; - - SAFE_RELEASE(m_buffers[index].vdpau); - - if(plane.id && glIsTexture(plane.id)) - glDeleteTextures(1, &plane.id); - plane.id = 0; -+ fields[0][1].id = 0; - #endif - } - -@@ -2334,11 +2345,152 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index) - void CLinuxRendererGL::UploadVDPAUTexture(int index) - { - #ifdef HAVE_LIBVDPAU -+ VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau; -+ -+ unsigned int flipindex = m_buffers[index].flipindex; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[0][0]; -+ -+ if (!vdpau || !vdpau->valid) -+ { -+ m_eventTexturesDone[index]->Set(); -+ m_skipRender = true; -+ return; -+ } -+ -+ fields[0][1].id = vdpau->texture[0]; -+ -+ m_eventTexturesDone[index]->Set(); ++#if defined(HAVE_LIBXVBA) && defined(TARGET_LINUX) ++ hwSupport += "XVBA:yes "; ++#elif defined(TARGET_LINUX) ++ hwSupport += "XVBA:no "; +#endif -+} -+ -+void CLinuxRendererGL::DeleteVDPAUTexture420(int index) -+{ -+#ifdef HAVE_LIBVDPAU -+ YUVPLANE &plane = m_buffers[index].fields[0][0]; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ -+ SAFE_RELEASE(m_buffers[index].vdpau); -+ -+ if(plane.id && glIsTexture(plane.id)) -+ glDeleteTextures(1, &plane.id); -+ plane.id = 0; -+ fields[1][0].id = 0; -+ fields[1][1].id = 0; -+ fields[2][0].id = 0; -+ fields[2][1].id = 0; -+ -+#endif -+} -+ -+bool CLinuxRendererGL::CreateVDPAUTexture420(int index) -+{ -+#ifdef HAVE_LIBVDPAU -+ YV12Image &im = m_buffers[index].image; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[0][0]; -+ GLuint *pbo = m_buffers[index].pbo; -+ -+ DeleteVDPAUTexture420(index); -+ -+ memset(&im , 0, sizeof(im)); -+ memset(&fields, 0, sizeof(fields)); -+ -+ im.cshift_x = 1; -+ im.cshift_y = 1; -+ -+ im.plane[0] = NULL; -+ im.plane[1] = NULL; -+ im.plane[2] = NULL; -+ -+ for(int p = 0;p<3;p++) -+ { -+ pbo[p] = None; -+ } -+ -+ glEnable(m_textureTarget); -+ glGenTextures(1, &plane.id); -+ glDisable(m_textureTarget); -+ - m_eventTexturesDone[index]->Set(); -- glPixelStorei(GL_UNPACK_ALIGNMENT,1); //what's this for? - #endif -+ return true; - } -+void CLinuxRendererGL::UploadVDPAUTexture420(int index) -+{ -+#ifdef HAVE_LIBVDPAU -+ VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau; -+ YV12Image &im = m_buffers[index].image; -+ -+ unsigned int flipindex = m_buffers[index].flipindex; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[0][0]; -+ -+ if (!vdpau || !vdpau->valid) -+ { -+ m_eventTexturesDone[index]->Set(); -+ m_skipRender = true; -+ return; -+ } -+ -+ im.height = vdpau->texHeight; -+ im.width = vdpau->texWidth; -+ -+ // YUV -+ for (int f = FIELD_FULL; f<=FIELD_BOT ; f++) -+ { -+ int fieldshift = (f==FIELD_FULL) ? 0 : 1; -+ YUVPLANES &planes = fields[f]; -+ -+ planes[0].texwidth = im.width; -+ planes[0].texheight = im.height >> fieldshift; -+ -+ planes[1].texwidth = planes[0].texwidth >> im.cshift_x; -+ planes[1].texheight = planes[0].texheight >> im.cshift_y; -+ planes[2].texwidth = planes[1].texwidth; -+ planes[2].texheight = planes[1].texheight; -+ -+ for (int p = 0; p < 3; p++) -+ { -+ planes[p].pixpertex_x = 1; -+ planes[p].pixpertex_y = 1; -+ } -+ } -+ // crop -+// m_sourceRect.x1 += vdpau->crop.x1; -+// m_sourceRect.x2 -= vdpau->crop.x2; -+// m_sourceRect.y1 += vdpau->crop.y1; -+// m_sourceRect.y2 -= vdpau->crop.y2; -+ -+ // set textures -+ fields[1][0].id = vdpau->texture[0]; -+ fields[1][1].id = vdpau->texture[2]; -+ fields[2][0].id = vdpau->texture[1]; -+ fields[2][1].id = vdpau->texture[3]; -+ -+ glEnable(m_textureTarget); -+ for (int f = 1; f < 3; f++) -+ { -+ for (int p=0;p<2;p++) -+ { -+ glBindTexture(m_textureTarget,fields[f][p].id); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -+ -+ glBindTexture(m_textureTarget,0); -+ VerifyGLState(); -+ } -+ fields[f][2].id = fields[f][1].id; -+ } -+ CalculateTextureSourceRects(index, 3); -+ glDisable(m_textureTarget); -+ -+ m_eventTexturesDone[index]->Set(); -+#endif -+} + CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); - void CLinuxRendererGL::DeleteVAAPITexture(int index) - { -@@ -3276,12 +3428,13 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) - if(method == VS_INTERLACEMETHOD_AUTO) - return true; - -- if(m_renderMethod & RENDER_VDPAU) -+ if(m_renderMethod & RENDER_VDPAU || -+ m_format == RENDER_FMT_VDPAU_420) - { - #ifdef HAVE_LIBVDPAU -- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; -- if(vdpau) -- return vdpau->Supports(method); -+ VDPAU::CVdpauRenderPicture *vdpauPic = m_buffers[m_iYV12RenderBuffer].vdpau; -+ if(vdpauPic && vdpauPic->vdpau) -+ return vdpauPic->vdpau->Supports(method); - #endif - return false; - } -@@ -3367,14 +3520,7 @@ EINTERLACEMETHOD CLinuxRendererGL::AutoInterlaceMethod() - return VS_INTERLACEMETHOD_NONE; - - if(m_renderMethod & RENDER_VDPAU) -- { --#ifdef HAVE_LIBVDPAU -- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; -- if(vdpau) -- return vdpau->AutoInterlaceMethod(); --#endif - return VS_INTERLACEMETHOD_NONE; -- } - - if(Supports(VS_INTERLACEMETHOD_RENDER_BOB)) - return VS_INTERLACEMETHOD_RENDER_BOB; -@@ -3417,11 +3563,12 @@ void CLinuxRendererGL::UnBindPbo(YUVBUFFER& buff) - } - - #ifdef HAVE_LIBVDPAU --void CLinuxRendererGL::AddProcessor(CVDPAU* vdpau, int index) -+void CLinuxRendererGL::AddProcessor(VDPAU::CVdpauRenderPicture *vdpau, int index) - { - YUVBUFFER &buf = m_buffers[index]; -+ VDPAU::CVdpauRenderPicture *pic = vdpau->Acquire(); - SAFE_RELEASE(buf.vdpau); -- buf.vdpau = (CVDPAU*)vdpau->Acquire(); -+ buf.vdpau = pic; - } - #endif - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index a7b5886..329ddee 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -38,12 +38,11 @@ - - class CRenderCapture; - --class CVDPAU; - class CBaseTexture; - namespace Shaders { class BaseYUV2RGBShader; } - namespace Shaders { class BaseVideoFilterShader; } - namespace VAAPI { struct CHolder; } -- -+namespace VDPAU { class CVdpauRenderPicture; } - - #undef ALIGN - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) -@@ -142,7 +141,7 @@ class CLinuxRendererGL : public CBaseRenderer - virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } - - #ifdef HAVE_LIBVDPAU -- virtual void AddProcessor(CVDPAU* vdpau, int index); -+ virtual void AddProcessor(VDPAU::CVdpauRenderPicture* vdpau, int index); - #endif +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp 2013-03-10 13:00:12.323988163 +0100 +@@ -56,6 +56,9 @@ #ifdef HAVE_LIBVA - virtual void AddProcessor(VAAPI::CHolder& holder, int index); -@@ -193,6 +192,10 @@ class CLinuxRendererGL : public CBaseRenderer - void DeleteVDPAUTexture(int index); - bool CreateVDPAUTexture(int index); - -+ void UploadVDPAUTexture420(int index); -+ void DeleteVDPAUTexture420(int index); -+ bool CreateVDPAUTexture420(int index); -+ - void UploadVAAPITexture(int index); - void DeleteVAAPITexture(int index); - bool CreateVAAPITexture(int index); -@@ -219,6 +222,7 @@ class CLinuxRendererGL : public CBaseRenderer - void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer - void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer - void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware -+ void RenderVDPAUYV12(int renderBuffer, int field); // render using vdpau hardware - void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware - - struct -@@ -279,7 +283,7 @@ class CLinuxRendererGL : public CBaseRenderer - GLuint pbo[MAX_PLANES]; - - #ifdef HAVE_LIBVDPAU -- CVDPAU* vdpau; -+ VDPAU::CVdpauRenderPicture *vdpau; + #include "VAAPI.h" #endif - #ifdef HAVE_LIBVA - VAAPI::CHolder& vaapi; -@@ -325,6 +329,7 @@ class CLinuxRendererGL : public CBaseRenderer - bool m_nonLinStretch; - bool m_nonLinStretchGui; - float m_pixelRatio; -+ bool m_skipRender; - }; ++#ifdef HAVE_LIBXVBA ++#include "XVBA.h" ++#endif + using namespace boost; -diff --git a/xbmc/cores/VideoRenderers/RenderFormats.h b/xbmc/cores/VideoRenderers/RenderFormats.h -index 09f8f5d..0262c60 100644 ---- a/xbmc/cores/VideoRenderers/RenderFormats.h -+++ b/xbmc/cores/VideoRenderers/RenderFormats.h -@@ -26,6 +26,7 @@ enum ERenderFormat { - RENDER_FMT_YUV420P10, - RENDER_FMT_YUV420P16, - RENDER_FMT_VDPAU, -+ RENDER_FMT_VDPAU_420, - RENDER_FMT_NV12, - RENDER_FMT_UYVY422, - RENDER_FMT_YUYV422, -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index c4ca57e..b89ec67 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -860,7 +860,8 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - CDVDCodecUtils::CopyDXVA2Picture(&image, &pic); - } - #ifdef HAVE_LIBVDPAU -- else if(pic.format == RENDER_FMT_VDPAU) -+ else if(pic.format == RENDER_FMT_VDPAU -+ || pic.format == RENDER_FMT_VDPAU_420) - m_pRenderer->AddProcessor(pic.vdpau, index); - #endif - #ifdef HAVE_LIBOPENMAX -diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h -index b3e6547..e4bd614 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.h -+++ b/xbmc/cores/VideoRenderers/RenderManager.h -@@ -35,7 +35,7 @@ - - namespace DXVA { class CProcessor; } - namespace VAAPI { class CSurfaceHolder; } --class CVDPAU; -+namespace VDPAU { class CVdpauRenderPicture; } - struct DVDVideoPicture; - - #define ERRORBUFFSIZE 30 -diff --git a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp -index 58f26b0..50606eb 100644 ---- a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp -+++ b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp -@@ -201,6 +201,8 @@ static void CalculateYUVMatrixGL(GLfloat res[4][4] - m_defines += "#define XBMC_YUY2\n"; - else if (m_format == RENDER_FMT_UYVY422) - m_defines += "#define XBMC_UYVY\n"; -+ else if (RENDER_FMT_VDPAU_420) -+ m_defines += "#define XBMC_VDPAU_NV12\n"; - else - CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index e84e65f..64c5f5f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -34,7 +34,7 @@ - - namespace DXVA { class CSurfaceContext; } - namespace VAAPI { struct CHolder; } --class CVDPAU; -+namespace VDPAU { class CVdpauRenderPicture; } - class COpenMax; - class COpenMaxVideo; - struct OpenMaxVideoBuffer; -@@ -55,7 +55,7 @@ struct DVDVideoPicture - DXVA::CSurfaceContext* context; - }; - struct { -- CVDPAU* vdpau; -+ VDPAU::CVdpauRenderPicture* vdpau; - }; - struct { - VAAPI::CHolder* vaapi; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index 2c2353d..e0c0f84 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -71,14 +71,14 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx +@@ -71,14 +74,14 @@ while(*cur != PIX_FMT_NONE) { #ifdef HAVE_LIBVDPAU @@ -4289,7 +1234,43 @@ index 2c2353d..e0c0f84 100644 { ctx->SetHardware(vdp); return *cur; -@@ -205,14 +205,27 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options +@@ -100,13 +103,26 @@ + dec->Release(); + } + #endif ++#ifdef HAVE_LIBXVBA ++ if(*cur == PIX_FMT_XVBA_VLD && g_guiSettings.GetBool("videoplayer.usexvba")) ++ { ++ XVBA::CDecoder* dec = new XVBA::CDecoder(); ++ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) ++ { ++ ctx->SetHardware(dec); ++ return *cur; ++ } ++ else ++ dec->Release(); ++ } ++#endif + #ifdef HAVE_LIBVA + // mpeg4 vaapi decoding is disabled + if(*cur == PIX_FMT_VAAPI_VLD && g_guiSettings.GetBool("videoplayer.usevaapi") + && (avctx->codec_id != CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) + { + VAAPI::CDecoder* dec = new VAAPI::CDecoder(); +- if(dec->Open(avctx, *cur)) ++ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) + { + ctx->SetHardware(dec); + return *cur; +@@ -142,6 +158,7 @@ + m_iLastKeyframe = 0; + m_dts = DVD_NOPTS_VALUE; + m_started = false; ++ m_decoderPts = DVD_NOPTS_VALUE; + } + + CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg() +@@ -204,14 +221,27 @@ continue; CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Creating VDPAU(%ix%i, %d)",hints.width, hints.height, hints.codec); @@ -4319,10 +1300,75 @@ index 2c2353d..e0c0f84 100644 { m_pHardware = vdp; m_pCodecContext->codec_id = CODEC_ID_NONE; // ffmpeg will complain if this has been set -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index 3631f7f..17a12d0 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +@@ -340,6 +370,14 @@ + { + if( m_pCodecContext ) + { ++ if (bDrop && m_pHardware && m_pHardware->CanSkipDeint()) ++ { ++ m_requestSkipDeint = true; ++ bDrop = false; ++ } ++ else ++ m_requestSkipDeint = false; ++ + // i don't know exactly how high this should be set + // couldn't find any good docs on it. think it varies + // from codec to codec on what it does +@@ -541,6 +579,7 @@ + void CDVDVideoCodecFFmpeg::Reset() + { + m_started = false; ++ m_decoderPts = DVD_NOPTS_VALUE; + m_iLastKeyframe = m_pCodecContext->has_b_frames; + m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext); + +@@ -639,6 +678,22 @@ + else + pDvdVideoPicture->pts = DVD_NOPTS_VALUE; + ++ if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE) ++ m_decoderPts = pDvdVideoPicture->pts; ++ else ++ m_decoderPts = m_dts; ++ ++ if (m_requestSkipDeint) ++ { ++ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPDEINT; ++ m_skippedDeint = 1; ++ } ++ else ++ m_skippedDeint = 0; ++ ++ m_requestSkipDeint = false; ++ pDvdVideoPicture->iFlags |= m_codecControlFlags; ++ + if(!m_started) + pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; + +@@ -861,3 +916,19 @@ + else + return 0; + } ++ ++bool CDVDVideoCodecFFmpeg::GetCodecStats(double &pts, int &skippedDeint, int &interlaced) ++{ ++ pts = m_decoderPts; ++ skippedDeint = m_skippedDeint; ++ if (m_pFrame) ++ interlaced = m_pFrame->interlaced_frame; ++ else ++ interlaced = 0; ++ return true; ++} ++ ++void CDVDVideoCodecFFmpeg::SetCodecControl(int flags) ++{ ++ m_codecControlFlags = flags; ++} +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h 2013-03-10 13:00:12.295988364 +0100 @@ -28,7 +28,6 @@ #include "DllSwScale.h" #include "DllAvFilter.h" @@ -4331,10 +1377,183 @@ index 3631f7f..17a12d0 100644 class CCriticalSection; class CDVDVideoCodecFFmpeg : public CDVDVideoCodec -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index f70a4f9..07cfc04 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -44,6 +43,7 @@ + virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) = 0; + virtual int Check (AVCodecContext* avctx) = 0; + virtual void Reset () {} ++ virtual bool CanSkipDeint() {return false; } + virtual const std::string Name() = 0; + virtual CCriticalSection* Section() { return NULL; } + }; +@@ -60,6 +60,8 @@ + virtual unsigned int SetFilters(unsigned int filters); + virtual const char* GetName() { return m_name.c_str(); }; // m_name is never changed after open + virtual unsigned GetConvergeCount(); ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced); ++ virtual void SetCodecControl(int flags); + + bool IsHardwareAllowed() { return !m_bSoftware; } + IHardwareDecoder * GetHardware() { return m_pHardware; }; +@@ -119,4 +121,8 @@ + double m_dts; + bool m_started; + std::vector m_formats; ++ double m_decoderPts, m_decoderInterval; ++ int m_skippedDeint; ++ bool m_requestSkipDeint; ++ int m_codecControlFlags; + }; +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2013-03-10 13:00:12.323988163 +0100 +@@ -34,7 +34,8 @@ + + namespace DXVA { class CSurfaceContext; } + namespace VAAPI { struct CHolder; } +-class CVDPAU; ++namespace VDPAU { class CVdpauRenderPicture; } ++namespace XVBA { class CXvbaRenderPicture; } + class COpenMax; + class COpenMaxVideo; + struct OpenMaxVideoBuffer; +@@ -55,11 +56,14 @@ + DXVA::CSurfaceContext* context; + }; + struct { +- CVDPAU* vdpau; ++ VDPAU::CVdpauRenderPicture* vdpau; + }; + struct { + VAAPI::CHolder* vaapi; + }; ++ struct { ++ XVBA::CXvbaRenderPicture* xvba; ++ }; + + struct { + COpenMax *openMax; +@@ -110,6 +114,10 @@ + #define DVP_FLAG_NOSKIP 0x00000010 // indicate this picture should never be dropped + #define DVP_FLAG_DROPPED 0x00000020 // indicate that this picture has been dropped in decoder stage, will have no data + ++#define DVP_FLAG_DROPDEINT 0x00000040 // indicate that this picture was requested to have been dropped in deint stage ++#define DVP_FLAG_NO_POSTPROC 0x00000100 ++#define DVP_FLAG_DRAIN 0x00000200 ++ + // DVP_FLAG 0x00000100 - 0x00000f00 is in use by libmpeg2! + + #define DVP_QSCALE_UNKNOWN 0 +@@ -127,6 +135,8 @@ + #define VC_PICTURE 0x00000004 // the decoder got a picture, call Decode(NULL, 0) again to parse the rest of the data + #define VC_USERDATA 0x00000008 // the decoder found some userdata, call Decode(NULL, 0) again to parse the rest of the data + #define VC_FLUSHED 0x00000010 // the decoder lost it's state, we need to restart decoding again ++#define VC_DROPPED 0x00000020 // needed to identify if a picture was dropped ++ + class CDVDVideoCodec + { + public: +@@ -237,4 +247,37 @@ + { + return 0; + } ++ ++ /** ++ * For calculation of dropping requirements player asks for some information. ++ * ++ * - pts : right after decoder, used to detect gaps (dropped frames in decoder) ++ * - skippedDeint : indicates if decoder has just skipped a deinterlacing cycle ++ * instead of dropping a full frame ++ * - interlaced : when detecting gaps in pts, player needs to know whether ++ * it's interlaced or not ++ * ++ * If codec does not implement this method, pts of decoded frame at input ++ * video player is used. In case coded does post-proc and de-interlacing there ++ * may be quite some frames queued up between exit decoder and entry player. ++ */ ++ virtual bool GetCodecStats(double &pts, int &skippedDeint, int &interlaced) ++ { ++ return false; ++ } ++ ++ /** ++ * Codec can be informed by player with the following flags: ++ * ++ * DVP_FLAG_NO_POSTPROC : if speed is not normal the codec can switch off ++ * postprocessing and de-interlacing ++ * ++ * DVP_FLAG_DRAIN : codecs may do postprocessing and de-interlacing. ++ * If video buffers in RenderManager are about to run dry, ++ * this is signaled to codec. Codec can wait for post-proc ++ * to be finished instead of returning empty and getting another ++ * packet. ++ * ++ */ ++ virtual void SetCodecControl(int flags) {} + }; +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2013-03-10 13:00:12.323988163 +0100 +@@ -14,6 +14,10 @@ + SRCS += CrystalHD.cpp + SRCS += DVDVideoCodecCrystalHD.cpp + endif ++ifeq (@USE_XVBA@,1) ++SRCS+= XVBA.cpp \ ++ ++endif + ifeq (@USE_VDA@,1) + SRCS += DVDVideoCodecVDA.cpp + endif +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp 2013-03-10 13:00:12.325988148 +0100 +@@ -261,6 +261,15 @@ + + bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces) + { ++#ifdef HAVE_LIBXVBA ++ std::string Vendor = g_Windowing.GetRenderVendor(); ++ std::transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); ++ if (Vendor.compare(0, 3, "ati") == 0) ++ { ++ return false; ++ } ++#endif ++ + VAEntrypoint entrypoint = VAEntrypointVLD; + VAProfile profile; + +@@ -357,6 +366,7 @@ + CHECK(vaCreateConfig(m_display->get(), profile, entrypoint, &attrib, 1, &m_hwaccel->config_id)) + m_config = m_hwaccel->config_id; + ++ m_renderbuffers_count = surfaces; + if (!EnsureContext(avctx)) + return false; + +@@ -388,7 +398,7 @@ + else + m_refs = 2; + } +- return EnsureSurfaces(avctx, m_refs + 3); ++ return EnsureSurfaces(avctx, m_refs + m_renderbuffers_count + 1); + } + + bool CDecoder::EnsureSurfaces(AVCodecContext *avctx, unsigned n_surfaces_count) +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.h 2013-03-10 13:00:12.284988442 +0100 +@@ -122,6 +122,7 @@ + static const unsigned m_surfaces_max = 32; + unsigned m_surfaces_count; + VASurfaceID m_surfaces[m_surfaces_max]; ++ unsigned m_renderbuffers_count; + + int m_refs; + std::list m_surfaces_used; +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp 2013-03-10 13:00:12.333988091 +0100 @@ -32,11 +32,16 @@ #include "settings/AdvancedSettings.h" #include "Application.h" @@ -4353,31 +1572,23 @@ index f70a4f9..07cfc04 100644 {"MPEG1", VDP_DECODER_PROFILE_MPEG1}, {"MPEG2_SIMPLE", VDP_DECODER_PROFILE_MPEG2_SIMPLE}, {"MPEG2_MAIN", VDP_DECODER_PROFILE_MPEG2_MAIN}, -@@ -50,14 +55,16 @@ +@@ -50,14 +55,7 @@ {"MPEG4_PART2_ASP", VDP_DECODER_PROFILE_MPEG4_PART2_ASP}, #endif }; -const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CVDPAU::Desc); -+const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); - +- -static float studioCSC[3][4] = -{ - { 1.0f, 0.0f, 1.57480000f,-0.78740000f}, - { 1.0f,-0.18737736f,-0.46813736f, 0.32775736f}, - { 1.0f, 1.85556000f, 0.0f,-0.92780000f} -}; -+//static float studioCSC[3][4] = -+//{ -+// { 1.0f, 0.0f, 1.57480000f,-0.78740000f}, -+// { 1.0f,-0.18737736f,-0.46813736f, 0.32775736f}, -+// { 1.0f, 1.85556000f, 0.0f,-0.92780000f} -+//}; -+static float studioCSCKCoeffs601[3] = {0.299, 0.587, 0.114}; //BT601 {Kr, Kg, Kb} -+static float studioCSCKCoeffs709[3] = {0.2126, 0.7152, 0.0722}; //BT709 {Kr, Kg, Kb} ++const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); static struct SInterlaceMapping { -@@ -68,88 +75,30 @@ +@@ -68,88 +66,30 @@ , {VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF , VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL} , {VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL , VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL} , {VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF, VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL} @@ -4391,14 +1602,9 @@ index f70a4f9..07cfc04 100644 //so we just keep a static handle to libvdpau around -void* CVDPAU::dl_handle; +void* CDecoder::dl_handle; -+ -+//----------------------------------------------------------------------------- -+// CVDPAU -+//----------------------------------------------------------------------------- -CVDPAU::CVDPAU() -+CDecoder::CDecoder() : m_vdpauOutput(&m_inMsgEvent) - { +-{ - glXBindTexImageEXT = NULL; - glXReleaseTexImageEXT = NULL; - vdp_device = VDP_INVALID_HANDLE; @@ -4408,9 +1614,9 @@ index f70a4f9..07cfc04 100644 - m_DisplayState = VDPAU_OPEN; - m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; - m_mixerstep = 0; -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; -+ m_vdpauConfig.videoSurfaces = &m_videoSurfaces; -+ m_vdpauConfig.videoSurfaceSec = &m_videoSurfaceSec; ++//----------------------------------------------------------------------------- ++// CVDPAU ++//----------------------------------------------------------------------------- - m_glPixmap = 0; - m_Pixmap = 0; @@ -4418,9 +1624,11 @@ index f70a4f9..07cfc04 100644 - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); - if (!glXReleaseTexImageEXT) - glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); -+ m_vdpauConfigured = false; -+ m_DisplayState = VDPAU_OPEN; -+} ++CDecoder::CDecoder() : m_vdpauOutput(&m_inMsgEvent) ++{ ++ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; ++ m_vdpauConfig.videoSurfaces = &m_videoSurfaces; ++ m_vdpauConfig.videoSurfaceSec = &m_videoSurfaceSec; - totalAvailableOutputSurfaces = 0; - outputSurface = presentSurface = VDP_INVALID_HANDLE; @@ -4473,14 +1681,16 @@ index f70a4f9..07cfc04 100644 - dl_vdp_device_create_x11 = NULL; - dl_vdp_get_proc_address = NULL; - dl_vdp_preemption_callback_register = NULL; --} -- ++ m_vdpauConfigured = false; ++ m_DisplayState = VDPAU_OPEN; + } + -bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) +bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) { if(avctx->coded_width == 0 || avctx->coded_height == 0) -@@ -157,6 +106,8 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su +@@ -157,6 +97,8 @@ CLog::Log(LOGWARNING,"(VDPAU) no width/height available, can't init"); return false; } @@ -4489,7 +1699,7 @@ index f70a4f9..07cfc04 100644 if (!dl_handle) { -@@ -168,8 +119,6 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su +@@ -168,8 +110,6 @@ error = "dlerror() returned NULL"; CLog::Log(LOGNOTICE,"(VDPAU) Unable to get handle to libvdpau: %s", error); @@ -4498,7 +1708,7 @@ index f70a4f9..07cfc04 100644 return false; } } -@@ -178,8 +127,9 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su +@@ -178,18 +118,18 @@ return false; InitVDPAUProcs(); @@ -4509,7 +1719,18 @@ index f70a4f9..07cfc04 100644 { SpewHardwareAvailable(); -@@ -197,25 +147,23 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su + VdpDecoderProfile profile = 0; + if(avctx->codec_id == CODEC_ID_H264) + profile = VDP_DECODER_PROFILE_H264_HIGH; +-#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP + else if(avctx->codec_id == CODEC_ID_MPEG4) + profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; +-#endif ++ + if(profile) + { + if (!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width)) +@@ -197,25 +137,23 @@ /* attempt to create a decoder with this width/height, some sizes are not supported by hw */ VdpStatus vdp_st; @@ -4541,7 +1762,7 @@ index f70a4f9..07cfc04 100644 avctx->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; g_Windowing.Register(this); -@@ -224,17 +172,20 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su +@@ -224,17 +162,20 @@ return false; } @@ -4564,7 +1785,7 @@ index f70a4f9..07cfc04 100644 while (!m_videoSurfaces.empty()) { -@@ -250,188 +201,111 @@ void CVDPAU::Close() +@@ -250,188 +191,111 @@ m_dllAvUtil.Unload(); } @@ -4598,20 +1819,22 @@ index f70a4f9..07cfc04 100644 - GLXFBConfig *fbConfigs; - fbConfigs = glXChooseFBConfig(m_Display, DefaultScreen(m_Display), doubleVisAttributes, &num); - if (fbConfigs==NULL) -+ // check if we should do some pre-cleanup here -+ // a second decoder might need resources -+ if (m_vdpauConfigured == true) - { +- { - CLog::Log(LOGERROR, "GLX Error: MakePixmap: No compatible framebuffers found"); - return false; - } - CLog::Log(LOGDEBUG, "Found %d fbconfigs.", num); - fbConfigIndex = 0; - CLog::Log(LOGDEBUG, "Using fbconfig index %d.", fbConfigIndex); +- +- m_glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], m_Pixmap, pixmapAttribs); ++ // check if we should do some pre-cleanup here ++ // a second decoder might need resources ++ if (m_vdpauConfigured == true) ++ { + CSingleLock lock(m_DecoderSection); + CLog::Log(LOGNOTICE,"CVDPAU::Release pre-cleanup"); - -- m_glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], m_Pixmap, pixmapAttribs); ++ + Message *reply; + if (m_vdpauOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::PRECLEANUP, + &reply, @@ -4810,7 +2033,7 @@ index f70a4f9..07cfc04 100644 state = m_DisplayState; } -@@ -445,16 +319,13 @@ int CVDPAU::Check(AVCodecContext* avctx) +@@ -445,16 +309,13 @@ } else { @@ -4829,7 +2052,7 @@ index f70a4f9..07cfc04 100644 FiniVDPAUOutput(); FiniVDPAUProcs(); -@@ -469,7 +340,7 @@ int CVDPAU::Check(AVCodecContext* avctx) +@@ -469,7 +330,7 @@ return 0; } @@ -4838,7 +2061,7 @@ index f70a4f9..07cfc04 100644 { if ((format >= PIX_FMT_VDPAU_H264) && (format <= PIX_FMT_VDPAU_VC1)) return true; #if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) -@@ -478,91 +349,28 @@ bool CVDPAU::IsVDPAUFormat(PixelFormat format) +@@ -478,255 +339,45 @@ else return false; } @@ -4932,19 +2155,14 @@ index f70a4f9..07cfc04 100644 + || method == VS_INTERLACEMETHOD_AUTO) return true; -+ if (g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv")) -+ { -+ if (method == VS_INTERLACEMETHOD_RENDER_BOB) -+ return true; -+ } -+ - for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) - { - if(p->method == method) -@@ -571,162 +379,12 @@ bool CVDPAU::Supports(EINTERLACEMETHOD method) - return false; - } - +- for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) +- { +- if(p->method == method) +- return Supports(p->feature); +- } +- return false; +-} +- -EINTERLACEMETHOD CVDPAU::AutoInterlaceMethod() -{ - return VS_INTERLACEMETHOD_VDPAU_TEMPORAL; @@ -4988,12 +2206,15 @@ index f70a4f9..07cfc04 100644 - VdpStatus vdp_st; - - if (!g_settings.m_currentVideoSettings.m_NoiseReduction) -- { ++ if (!m_vdpauConfig.usePixmaps) + { - VdpBool enabled[]= {0}; - vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); - CheckStatus(vdp_st, __LINE__); - return; -- } ++ if (method == VS_INTERLACEMETHOD_RENDER_BOB) ++ return true; + } - VdpBool enabled[]={1}; - vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); - CheckStatus(vdp_st, __LINE__); @@ -5002,7 +2223,7 @@ index f70a4f9..07cfc04 100644 - vdp_st = vdp_video_mixer_set_attribute_values(videoMixer, ARSIZE(attributes), attributes, nr); - CheckStatus(vdp_st, __LINE__); -} -- + -void CVDPAU::SetSharpness() -{ - if(!Supports(VDP_VIDEO_MIXER_FEATURE_SHARPNESS)) @@ -5011,14 +2232,19 @@ index f70a4f9..07cfc04 100644 - VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_SHARPNESS }; - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL }; - VdpStatus vdp_st; -- ++ if (method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE) ++ return false; + - if (!g_settings.m_currentVideoSettings.m_Sharpness) -- { ++ for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) + { - VdpBool enabled[]={0}; - vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); - CheckStatus(vdp_st, __LINE__); - return; -- } ++ if(p->method == method) ++ return Supports(p->feature); + } - VdpBool enabled[]={1}; - vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); - CheckStatus(vdp_st, __LINE__); @@ -5040,8 +2266,9 @@ index f70a4f9..07cfc04 100644 - vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); - CheckStatus(vdp_st, __LINE__); -#endif --} -- ++ return false; + } + -void CVDPAU::SetDeinterlacing() +EINTERLACEMETHOD CDecoder::AutoInterlaceMethod() { @@ -5107,7 +2334,7 @@ index f70a4f9..07cfc04 100644 { char* error; -@@ -736,151 +394,115 @@ void CVDPAU::InitVDPAUProcs() +@@ -736,151 +387,115 @@ if (error) { CLog::Log(LOGERROR,"(VDPAU) - %s in %s",error,__FUNCTION__); @@ -5257,28 +2484,17 @@ index f70a4f9..07cfc04 100644 +void CDecoder::FiniVDPAUProcs() { - if (vdp_device == VDP_INVALID_HANDLE) return; -+ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE) return; - - VdpStatus vdp_st; +- +- VdpStatus vdp_st; - vdp_st = vdp_device_destroy(vdp_device); -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_device_destroy(m_vdpauConfig.vdpDevice); - CheckStatus(vdp_st, __LINE__); +- CheckStatus(vdp_st, __LINE__); - vdp_device = VDP_INVALID_HANDLE; - vdpauConfigured = false; -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; - } +-} ++ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE) return; -void CVDPAU::InitCSCMatrix(int Height) -+void CDecoder::FiniVDPAUOutput() - { -+ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE || !m_vdpauConfigured) return; -+ -+ CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); -+ -+ // uninit output -+ m_vdpauOutput.Dispose(); -+ m_vdpauConfigured = false; -+ +-{ VdpStatus vdp_st; - m_Procamp.struct_version = VDP_PROCAMP_VERSION; - m_Procamp.brightness = 0.0; @@ -5288,19 +2504,27 @@ index f70a4f9..07cfc04 100644 - vdp_st = vdp_generate_csc_matrix(&m_Procamp, - (Height < 720)? VDP_COLOR_STANDARD_ITUR_BT_601 : VDP_COLOR_STANDARD_ITUR_BT_709, - &m_CSCMatrix); -- CheckStatus(vdp_st, __LINE__); --} -- --void CVDPAU::FiniVDPAUOutput() --{ -- FiniOutputMethod(); ++ vdp_st = m_vdpauConfig.vdpProcs.vdp_device_destroy(m_vdpauConfig.vdpDevice); + CheckStatus(vdp_st, __LINE__); ++ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; + } +-void CVDPAU::FiniVDPAUOutput() ++void CDecoder::FiniVDPAUOutput() + { +- FiniOutputMethod(); +- - if (vdp_device == VDP_INVALID_HANDLE || !vdpauConfigured) return; -- -- CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); -- -- VdpStatus vdp_st; -- ++ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE || !m_vdpauConfigured) return; + + CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); + ++ // uninit output ++ m_vdpauOutput.Dispose(); ++ m_vdpauConfigured = false; ++ + VdpStatus vdp_st; + - vdp_st = vdp_decoder_destroy(decoder); + vdp_st = m_vdpauConfig.vdpProcs.vdp_decoder_destroy(m_vdpauConfig.vdpDecoder); if (CheckStatus(vdp_st, __LINE__)) @@ -5322,7 +2546,7 @@ index f70a4f9..07cfc04 100644 render->surface = VDP_INVALID_HANDLE; } if (CheckStatus(vdp_st, __LINE__)) -@@ -888,8 +510,7 @@ void CVDPAU::FiniVDPAUOutput() +@@ -888,8 +503,7 @@ } } @@ -5332,19 +2556,21 @@ index f70a4f9..07cfc04 100644 , VdpDecoderProfile &vdp_decoder_profile , VdpChromaType &vdp_chroma_type) { -@@ -916,9 +537,9 @@ void CVDPAU::ReadFormatOf( PixelFormat fmt +@@ -915,13 +529,10 @@ + vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; vdp_chroma_type = VDP_CHROMA_TYPE_420; break; - #if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) && \ +-#if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) && \ - (defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP) -+ (defined VDP_DECODER_PROFILE_MP) case PIX_FMT_VDPAU_MPEG4: -- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; -+ vdp_decoder_profile = VDP_DECOPEG4_PART2_ASP; + vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; vdp_chroma_type = VDP_CHROMA_TYPE_420; break; - #endif -@@ -929,170 +550,78 @@ void CVDPAU::ReadFormatOf( PixelFormat fmt +-#endif + default: + vdp_decoder_profile = 0; + vdp_chroma_type = 0; +@@ -929,170 +540,78 @@ } } @@ -5360,11 +2586,12 @@ index f70a4f9..07cfc04 100644 - vid_height = avctx->height; - surface_width = avctx->coded_width; - surface_height = avctx->coded_height; - +- - past[1] = past[0] = current = future = NULL; - CLog::Log(LOGNOTICE, " (VDPAU) screenWidth:%i vidWidth:%i surfaceWidth:%i",OutWidth,vid_width,surface_width); - CLog::Log(LOGNOTICE, " (VDPAU) screenHeight:%i vidHeight:%i surfaceHeight:%i",OutHeight,vid_height,surface_height); - ReadFormatOf(avctx->pix_fmt, vdp_decoder_profile, vdp_chroma_type); ++ + m_vdpauConfig.vidWidth = avctx->width; + m_vdpauConfig.vidHeight = avctx->height; + m_vdpauConfig.surfaceWidth = avctx->coded_width; @@ -5563,7 +2790,7 @@ index f70a4f9..07cfc04 100644 { VdpStatus rv; CLog::Log(LOGNOTICE,"VDPAU Decoder capabilities:"); -@@ -1102,7 +631,7 @@ void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der L +@@ -1102,7 +621,7 @@ { VdpBool is_supported = false; uint32_t max_level, max_macroblocks, max_width, max_height; @@ -5572,7 +2799,7 @@ index f70a4f9..07cfc04 100644 &is_supported, &max_level, &max_macroblocks, &max_width, &max_height); if(rv == VDP_STATUS_OK && is_supported) { -@@ -1111,13 +640,13 @@ void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der L +@@ -1111,13 +630,13 @@ } } CLog::Log(LOGNOTICE,"------------------------------------"); @@ -5589,7 +2816,7 @@ index f70a4f9..07cfc04 100644 } \ } while(false) -@@ -1141,7 +670,7 @@ void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der L +@@ -1141,7 +660,7 @@ } @@ -5598,7 +2825,7 @@ index f70a4f9..07cfc04 100644 { // find render state in queue bool found(false); -@@ -1168,34 +697,33 @@ bool CVDPAU::IsSurfaceValid(vdpau_render_state *render) +@@ -1168,34 +687,33 @@ return true; } @@ -5648,7 +2875,7 @@ index f70a4f9..07cfc04 100644 } } -@@ -1204,21 +732,22 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) +@@ -1204,21 +722,22 @@ { // create a new surface VdpDecoderProfile profile; @@ -5674,7 +2901,7 @@ index f70a4f9..07cfc04 100644 avctx->coded_width, avctx->coded_height, &render->surface); -@@ -1239,18 +768,6 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) +@@ -1239,18 +758,6 @@ pic->linesize[0] = pic->linesize[1] = pic->linesize[2] = 0; @@ -5693,7 +2920,7 @@ index f70a4f9..07cfc04 100644 pic->type= FF_BUFFER_TYPE_USER; render->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE; -@@ -1258,15 +775,16 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) +@@ -1258,15 +765,16 @@ return 0; } @@ -5713,7 +2940,7 @@ index f70a4f9..07cfc04 100644 render=(vdpau_render_state*)pic->data[0]; if(!render) -@@ -1275,6 +793,8 @@ void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) +@@ -1275,6 +783,8 @@ return; } @@ -5722,7 +2949,7 @@ index f70a4f9..07cfc04 100644 for(i=0; i<4; i++) pic->data[i]= NULL; -@@ -1289,21 +809,18 @@ void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) +@@ -1289,21 +799,18 @@ } @@ -5749,7 +2976,7 @@ index f70a4f9..07cfc04 100644 if(src->linesize[0] || src->linesize[1] || src->linesize[2] || offset[0] || offset[1] || offset[2]) -@@ -1333,59 +850,41 @@ void CVDPAU::FFDrawSlice(struct AVCodecContext *s, +@@ -1333,59 +840,41 @@ if(s->pix_fmt == PIX_FMT_VDPAU_H264) max_refs = render->info.h264.num_ref_frames; @@ -5824,7 +3051,7 @@ index f70a4f9..07cfc04 100644 if(pFrame) { // we have a new frame from decoder -@@ -1393,7 +892,10 @@ int CVDPAU::Decode(AVCodecContext *avctx, AVFrame *pFrame) +@@ -1393,7 +882,10 @@ if(!render) // old style ffmpeg gave data on plane 0 render = (vdpau_render_state*)pFrame->data[0]; if(!render) @@ -5835,59 +3062,63 @@ index f70a4f9..07cfc04 100644 // ffmpeg vc-1 decoder does not flush, make sure the data buffer is still valid if (!IsSurfaceValid(render)) -@@ -1402,258 +904,166 @@ int CVDPAU::Decode(AVCodecContext *avctx, AVFrame *pFrame) +@@ -1402,258 +894,167 @@ return VC_BUFFER; } + CSingleLock lock(m_videoSurfaceSec); render->state |= FF_VDPAU_STATE_USED_FOR_RENDER; + lock.Leave(); ++ ++ // send frame to output for processing ++ CVdpauDecodedPicture pic; ++ memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); ++ ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); ++ pic.render = render; ++ pic.DVDPic.color_matrix = avctx->colorspace; ++ m_bufferStats.IncDecoded(); ++ m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - ClearUsedForRender(&past[0]); - past[0] = past[1]; - past[1] = current; - current = future; - future = render; -+ // send frame to output for processing -+ CVdpauDecodedPicture pic; -+ memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); -+ ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); -+ pic.render = render; -+ m_bufferStats.IncDecoded(); -+ m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - +- - DVDVideoPicture DVDPic; - memset(&DVDPic, 0, sizeof(DVDVideoPicture)); - ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&DVDPic); - m_DVDVideoPics.push(DVDPic); -+ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); -+ } - +- - int pics = m_DVDVideoPics.size(); - if (pics < 2) - return VC_BUFFER; - else if (pics > 2) +- { +- // this should not normally happen +- CLog::Log(LOGERROR, "CVDPAU::Decode - invalid number of pictures in queue"); +- while (pics-- != 2) +- m_DVDVideoPics.pop(); ++ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); ++ } ++ + int retval = 0; + uint16_t decoded, processed, render; + Message *msg; + while (m_vdpauOutput.m_controlPort.ReceiveInMessage(&msg)) + { + if (msg->signal == COutputControlProtocol::ERROR) - { -- // this should not normally happen -- CLog::Log(LOGERROR, "CVDPAU::Decode - invalid number of pictures in queue"); -- while (pics-- != 2) -- m_DVDVideoPics.pop(); ++ { + m_DisplayState = VDPAU_ERROR; + retval |= VC_ERROR; } + msg->Release(); + } ++ ++ m_bufferStats.Get(decoded, processed, render); - if (mode == VS_DEINTERLACEMODE_FORCE - || (mode == VS_DEINTERLACEMODE_AUTO && m_DVDVideoPics.front().iFlags & DVP_FLAG_INTERLACED)) -+ m_bufferStats.Get(decoded, processed, render); -+ + uint64_t startTime = CurrentHostCounter(); + while (!retval) + { @@ -5996,19 +3227,16 @@ index f70a4f9..07cfc04 100644 - VdpVideoSurface futu_surfaces[1] = { VDP_INVALID_HANDLE }; - - if(m_mixerfield == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME) -+ if (!retval) - { +- { - if (past[0]) - past_surfaces[1] = past[0]->surface; - if (past[1]) - past_surfaces[0] = past[1]->surface; - futu_surfaces[0] = future->surface; -+ CLog::Log(LOGERROR, "VDPAU::%s - timed out waiting for output message", __FUNCTION__); -+ m_DisplayState = VDPAU_ERROR; -+ retval |= VC_ERROR; - } +- } - else -- { ++ if (!retval) + { - if(m_mixerstep == 1) - { // first field - if (past[1]) @@ -6025,8 +3253,11 @@ index f70a4f9..07cfc04 100644 - past_surfaces[0] = current->surface; - futu_surfaces[0] = future->surface; - } -- } -- ++ CLog::Log(LOGERROR, "VDPAU::%s - timed out waiting for output message", __FUNCTION__); ++ m_DisplayState = VDPAU_ERROR; ++ retval |= VC_ERROR; + } + - vdp_st = vdp_presentation_queue_block_until_surface_idle(vdp_flip_queue,outputSurface,&time); - - VdpRect sourceRect = {0,0,vid_width, vid_height}; @@ -6047,7 +3278,7 @@ index f70a4f9..07cfc04 100644 - 0, - NULL); - CheckStatus(vdp_st, __LINE__); - +- - surfaceNum++; - if (surfaceNum >= totalAvailableOutputSurfaces) surfaceNum = 0; + return retval; @@ -6105,7 +3336,8 @@ index f70a4f9..07cfc04 100644 +void CDecoder::Reset() { - CSharedLock lock(m_DecoderSection); -- ++ CSingleLock lock(m_DecoderSection); + - { CSharedLock dLock(m_DisplaySection); - if (m_DisplayState != VDPAU_OPEN) - return false; @@ -6116,8 +3348,7 @@ index f70a4f9..07cfc04 100644 - // this same picture for the second field later - if (m_mixerstep != 1) - m_DVDVideoPics.pop(); -+ CSingleLock lock(m_DecoderSection); - +- - picture->format = RENDER_FMT_VDPAU; - picture->iFlags &= DVP_FLAG_DROPPED; - picture->iWidth = OutWidth; @@ -6127,13 +3358,14 @@ index f70a4f9..07cfc04 100644 + return; - if(m_mixerstep) +- { +- picture->iRepeatPicture = -0.5; +- if(m_mixerstep > 1) + Message *reply; + if (m_vdpauOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::FLUSH, + &reply, + 2000)) - { -- picture->iRepeatPicture = -0.5; -- if(m_mixerstep > 1) ++ { + bool success = reply->signal == COutputControlProtocol::ACC ? true : false; + reply->Release(); + if (!success) @@ -6204,7 +3436,7 @@ index f70a4f9..07cfc04 100644 if(m_DisplayState == VDPAU_OPEN) { -@@ -1671,4 +1081,2424 @@ bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line) +@@ -1671,4 +1072,2423 @@ return false; } @@ -6278,6 +3510,11 @@ index f70a4f9..07cfc04 100644 + m_dataPort.Purge(); +} + ++bool CMixer::IsActive() ++{ ++ return IsRunning(); ++} ++ +void CMixer::OnStartup() +{ + CLog::Log(LOGNOTICE, "CMixer::OnStartup: Output Thread created"); @@ -6646,10 +3883,6 @@ index f70a4f9..07cfc04 100644 + m_Procamp.contrast = 1.0; + m_Procamp.saturation = 1.0; + m_Procamp.hue = 0; -+ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, -+ (Width < 1000)? VDP_COLOR_STANDARD_ITUR_BT_601 : VDP_COLOR_STANDARD_ITUR_BT_709, -+ &m_CSCMatrix); -+ CheckStatus(vdp_st, __LINE__); +} + +void CMixer::CheckFeatures() @@ -6660,11 +3893,13 @@ index f70a4f9..07cfc04 100644 + m_Upscale = m_config.upscale; + } + if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness || -+ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) ++ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast || ++ m_ColorMatrix != m_mixerInput[1].DVDPic.color_matrix) + { + SetColor(); + m_Brightness = g_settings.m_currentVideoSettings.m_Brightness; + m_Contrast = g_settings.m_currentVideoSettings.m_Contrast; ++ m_ColorMatrix = m_mixerInput[1].DVDPic.color_matrix; + } + if (m_NoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) + { @@ -6738,74 +3973,6 @@ index f70a4f9..07cfc04 100644 + DisableHQScaling(); +} + -+ -+bool CMixer::GenerateStudioCSCMatrix(VdpColorStandard colorStandard, VdpCSCMatrix &studioCSCMatrix) -+{ -+ // instead use studioCSCKCoeffs601[3], studioCSCKCoeffs709[3] to generate float[3][4] matrix (float studioCSC[3][4]) -+ // m00 = mRY = red: luma factor (contrast factor) (1.0) -+ // m10 = mGY = green: luma factor (contrast factor) (1.0) -+ // m20 = mBY = blue: luma factor (contrast factor) (1.0) -+ // -+ // m01 = mRB = red: blue color diff coeff (0.0) -+ // m11 = mGB = green: blue color diff coeff (-2Kb(1-Kb)/(Kg)) -+ // m21 = mBB = blue: blue color diff coeff ((1-Kb)/0.5) -+ // -+ // m02 = mRR = red: red color diff coeff ((1-Kr)/0.5) -+ // m12 = mGR = green: red color diff coeff (-2Kr(1-Kr)/(Kg)) -+ // m22 = mBR = blue: red color diff coeff (0.0) -+ // -+ // m03 = mRC = red: colour zero offset (brightness factor) (-(1-Kr)/0.5 * (128/255)) -+ // m13 = mGC = green: colour zero offset (brightness factor) ((256/255) * (Kb(1-Kb) + Kr(1-Kr)) / Kg) -+ // m23 = mBC = blue: colour zero offset (brightness factor) (-(1-Kb)/0.5 * (128/255)) -+ -+ // columns -+ int Y = 0; -+ int Cb = 1; -+ int Cr = 2; -+ int C = 3; -+ // rows -+ int R = 0; -+ int G = 1; -+ int B = 2; -+ // colour standard coefficients for red, geen, blue -+ double Kr, Kg, Kb; -+ // colour diff zero position (use standard 8-bit coding precision) -+ double CDZ = 128; //256*0.5 -+ // range excursion (use standard 8-bit coding precision) -+ double EXC = 255; //256-1 -+ -+ if (colorStandard == VDP_COLOR_STANDARD_ITUR_BT_601) -+ { -+ Kr = studioCSCKCoeffs601[0]; -+ Kg = studioCSCKCoeffs601[1]; -+ Kb = studioCSCKCoeffs601[2]; -+ } -+ else // assume VDP_COLOR_STANDARD_ITUR_BT_709 -+ { -+ Kr = studioCSCKCoeffs709[0]; -+ Kg = studioCSCKCoeffs709[1]; -+ Kb = studioCSCKCoeffs709[2]; -+ } -+ // we keep luma unscaled to retain the levels present in source so that 16-235 luma is converted to RGB 16-235 -+ studioCSCMatrix[R][Y] = 1.0; -+ studioCSCMatrix[G][Y] = 1.0; -+ studioCSCMatrix[B][Y] = 1.0; -+ -+ studioCSCMatrix[R][Cb] = 0.0; -+ studioCSCMatrix[G][Cb] = (double)-2 * Kb * (1 - Kb) / Kg; -+ studioCSCMatrix[B][Cb] = (double)(1 - Kb) / 0.5; -+ -+ studioCSCMatrix[R][Cr] = (double)(1 - Kr) / 0.5; -+ studioCSCMatrix[G][Cr] = (double)-2 * Kr * (1 - Kr) / Kg; -+ studioCSCMatrix[B][Cr] = 0.0; -+ -+ studioCSCMatrix[R][C] = (double)-1 * studioCSCMatrix[R][Cr] * CDZ/EXC; -+ studioCSCMatrix[G][C] = (double)-1 * (studioCSCMatrix[G][Cb] + studioCSCMatrix[G][Cr]) * CDZ/EXC; -+ studioCSCMatrix[B][C] = (double)-1 * studioCSCMatrix[B][Cb] * CDZ/EXC; -+ -+ return true; -+} -+ +void CMixer::SetColor() +{ + VdpStatus vdp_st; @@ -6816,28 +3983,33 @@ index f70a4f9..07cfc04 100644 + m_Procamp.contrast = (float)((g_settings.m_currentVideoSettings.m_Contrast)+50) / 100; + + VdpColorStandard colorStandard; -+// if(vid_height >= 600 || vid_width > 1024) -+ if(m_config.surfaceWidth > 1000) -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); -+ else -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); ++ switch(m_mixerInput[1].DVDPic.color_matrix) ++ { ++ case AVCOL_SPC_BT709: ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; ++ break; ++ case AVCOL_SPC_BT470BG: ++ case AVCOL_SPC_SMPTE170M: ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; ++ break; ++ case AVCOL_SPC_SMPTE240M: ++ colorStandard = VDP_COLOR_STANDARD_SMPTE_240M; ++ break; ++ case AVCOL_SPC_FCC: ++ case AVCOL_SPC_UNSPECIFIED: ++ case AVCOL_SPC_RGB: ++ default: ++ if(m_config.surfaceWidth > 1000) ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; ++ else ++ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; ++ } + + VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; -+ if (g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -+ { -+ float studioCSC[3][4]; -+ GenerateStudioCSCMatrix(colorStandard, studioCSC); -+ void const * pm_CSCMatix[] = { &studioCSC }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -+ } -+ else -+ { -+ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -+ void const * pm_CSCMatix[] = { &m_CSCMatrix }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -+ } ++ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); ++ void const * pm_CSCMatix[] = { &m_CSCMatrix }; ++ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); ++ + CheckStatus(vdp_st, __LINE__); +} + @@ -6897,10 +4069,10 @@ index f70a4f9..07cfc04 100644 + 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) + { @@ -6974,7 +4146,7 @@ index f70a4f9..07cfc04 100644 + + SetDeintSkipChroma(); + -+ m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); ++ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); +} + +void CMixer::SetDeintSkipChroma() @@ -7162,11 +4334,12 @@ index f70a4f9..07cfc04 100644 + m_Sharpness = 0.0; + m_DeintMode = 0; + m_Deint = 0; ++ m_ColorMatrix = 0; + m_PostProc = false; + m_vdpError = false; + + m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; -+ m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); ++ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); + + CreateVdpauMixer(); +} @@ -7239,8 +4412,9 @@ index f70a4f9..07cfc04 100644 + EINTERLACEMETHOD method = GetDeinterlacingMethod(); + bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; + -+ if (mode == VS_DEINTERLACEMODE_FORCE || -+ (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) ++ if (!(flags & DVP_FLAG_NO_POSTPROC) && ++ (mode == VS_DEINTERLACEMODE_FORCE || ++ (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) + { + if((method == VS_INTERLACEMETHOD_AUTO && interlaced) + || method == VS_INTERLACEMETHOD_VDPAU_BOB @@ -7276,21 +4450,24 @@ index f70a4f9..07cfc04 100644 + DVP_FLAG_INTERLACED); + m_config.useInteropYuv = false; + } -+ else if (method == VS_INTERLACEMETHOD_RENDER_BOB && m_config.useInteropYuv) ++ else if (method == VS_INTERLACEMETHOD_RENDER_BOB) + { + m_mixersteps = 1; + m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; + m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; ++ m_config.useInteropYuv = true; + } + else + { -+ CLog::Log(LOGERROR, "CMixer::%s - interlace method not supported", __FUNCTION__); ++ CLog::Log(LOGERROR, "CMixer::%s - interlace method: %d not supported, setting to AUTO", __FUNCTION__, method); + m_mixersteps = 1; + m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; + m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU; + m_mixerInput[1].DVDPic.iFlags &= ~(DVP_FLAG_TOP_FIELD_FIRST | + DVP_FLAG_REPEAT_TOP_FIELD | + DVP_FLAG_INTERLACED); ++ ++ g_settings.m_currentVideoSettings.m_InterlaceMethod = VS_INTERLACEMETHOD_AUTO; + } + } + else @@ -7653,6 +4830,7 @@ index f70a4f9..07cfc04 100644 + return; + case COutputControlProtocol::PRECLEANUP: + Flush(); ++ PreCleanup(); + msg->Reply(COutputControlProtocol::ACC); + return; + default: @@ -7859,15 +5037,18 @@ index f70a4f9..07cfc04 100644 + +void COutput::Flush() +{ -+ Message *reply; -+ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, ++ if (m_mixer.IsActive()) ++ { ++ Message *reply; ++ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, + &reply, + 2000)) -+ { -+ reply->Release(); ++ { ++ reply->Release(); ++ } ++ else ++ CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); + } -+ else -+ CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); + + Message *msg; + while (m_mixer.m_dataPort.ReceiveInMessage(&msg)) @@ -8206,6 +5387,57 @@ index f70a4f9..07cfc04 100644 + } +} + ++void COutput::PreCleanup() ++{ ++ ++ VdpStatus vdp_st; ++ ++ m_mixer.Dispose(); ++ ++ CSingleLock lock(m_bufferPool.renderPicSec); ++ for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) ++ { ++ if (m_bufferPool.outputSurfaces[i] == VDP_INVALID_HANDLE) ++ continue; ++ ++ // check if output surface is in use ++ bool used = false; ++ std::deque::iterator it; ++ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) ++ { ++ if (((*it)->sourceIdx == m_bufferPool.outputSurfaces[i]) && (*it)->valid) ++ { ++ used = true; ++ break; ++ } ++ } ++ if (used) ++ continue; ++ ++#ifdef GL_NV_vdpau_interop ++ // unmap surface ++ std::map::iterator it_map; ++ it_map = m_bufferPool.glOutputSurfaceMap.find(m_bufferPool.outputSurfaces[i]); ++ if (it_map == m_bufferPool.glOutputSurfaceMap.end()) ++ { ++ CLog::Log(LOGERROR, "%s - could not find gl surface", __FUNCTION__); ++ continue; ++ } ++ glVDPAUUnregisterSurfaceNV(it_map->second.glVdpauSurface); ++ glDeleteTextures(1, it_map->second.texture); ++ m_bufferPool.glOutputSurfaceMap.erase(it_map); ++#endif ++ ++ vdp_st = m_config.vdpProcs.vdp_output_surface_destroy(m_bufferPool.outputSurfaces[i]); ++ CheckStatus(vdp_st, __LINE__); ++ ++ m_bufferPool.outputSurfaces[i] = VDP_INVALID_HANDLE; ++ ++ CLog::Log(LOGDEBUG, "VDPAU::PreCleanup - released output surface"); ++ } ++ ++} ++ +void COutput::InitMixer() +{ + for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) @@ -8312,7 +5544,7 @@ index f70a4f9..07cfc04 100644 + glVDPAUGetSurfaceivNV = NULL; +#endif + -+ m_config.usePixmaps = !g_guiSettings.GetBool("videoplayer.usevdpauinterop"); ++ m_config.usePixmaps = false; + +#ifdef GL_NV_vdpau_interop + if (glewIsSupported("GL_NV_vdpau_interop")) @@ -8344,8 +5576,7 @@ index f70a4f9..07cfc04 100644 +#endif + { + m_config.usePixmaps = true; -+ g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -+ g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); ++ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); + } + if (!glXBindTexImageEXT) + glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); @@ -8629,10 +5860,9 @@ index f70a4f9..07cfc04 100644 +} + #endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index 2f53edf..4d1559c 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h 2013-03-10 13:00:12.332988098 +0100 @@ -1,5 +1,3 @@ - -#pragma once @@ -8704,7 +5934,9 @@ index 2f53edf..4d1559c 100644 - uint32_t id; - uint32_t aux; /* optional extra parameter... */ - }; -- ++#include "threads/Thread.h" ++#include "utils/ActorProtocol.h" + - CVDPAU(); - virtual ~CVDPAU(); - @@ -8713,11 +5945,12 @@ index 2f53edf..4d1559c 100644 - virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); - virtual void Reset(); - virtual void Close(); -- ++using namespace Actor; + - virtual int Check(AVCodecContext* avctx); - - virtual const std::string Name() { return "vdpau"; } -- + - bool MakePixmap(int width, int height); - bool MakePixmapGL(); - @@ -8741,16 +5974,15 @@ index 2f53edf..4d1559c 100644 - void InitCSCMatrix(int Height); - bool CheckStatus(VdpStatus vdp_st, int line); - bool IsSurfaceValid(vdpau_render_state *render); -+#include "threads/Thread.h" -+#include "utils/ActorProtocol.h" - +- - void CheckFeatures(); - void SetColor(); - void SetNoiseReduction(); - void SetSharpness(); - void SetDeinterlacing(); - void SetHWUpscaling(); -+using namespace Actor; ++#define FULLHD_WIDTH 1920 ++#define MAX_PIC_Q_LENGTH 20 //for non-interop_yuv this controls the max length of the decoded pic to render completion Q - pictureAge picAge; - vdpau_render_state *past[2], *current, *future; @@ -8760,7 +5992,7 @@ index 2f53edf..4d1559c 100644 - int OutWidth, OutHeight; - bool upScale; - std::queue m_DVDVideoPics; - +- - static inline void ClearUsedForRender(vdpau_render_state **st) - { - if (*st) { @@ -8768,16 +6000,21 @@ index 2f53edf..4d1559c 100644 - *st = NULL; - } - } -- ++namespace VDPAU ++{ + - VdpProcamp m_Procamp; - VdpCSCMatrix m_CSCMatrix; - VdpDevice HasDevice() { return vdp_device != VDP_INVALID_HANDLE; }; - VdpChromaType vdp_chroma_type; -+#define FULLHD_WIDTH 1920 -+#define MAX_PIC_Q_LENGTH 20 //for non-interop_yuv this controls the max length of the decoded pic to render completion Q ++/** ++ * VDPAU interface to driver ++ */ -+namespace VDPAU ++struct VDPAU_procs +{ ++ VdpGetProcAddress * vdp_get_proc_address; ++ VdpDeviceDestroy * vdp_device_destroy; - // protected: - void InitVDPAUProcs(); @@ -8785,20 +6022,13 @@ index 2f53edf..4d1559c 100644 - void FiniVDPAUOutput(); - bool ConfigOutputMethod(AVCodecContext *avctx, AVFrame *pFrame); - bool FiniOutputMethod(); -+/** -+ * VDPAU interface to driver -+ */ - +- - VdpDevice vdp_device; - VdpGetProcAddress * vdp_get_proc_address; - VdpPresentationQueueTarget vdp_flip_target; - VdpPresentationQueue vdp_flip_queue; - VdpDeviceDestroy * vdp_device_destroy; -+struct VDPAU_procs -+{ -+ VdpGetProcAddress * vdp_get_proc_address; -+ VdpDeviceDestroy * vdp_device_destroy; - +- - VdpVideoSurfaceCreate * vdp_video_surface_create; - VdpVideoSurfaceDestroy * vdp_video_surface_destroy; - VdpVideoSurfacePutBitsYCbCr * vdp_video_surface_put_bits_y_cb_cr; @@ -8810,7 +6040,7 @@ index 2f53edf..4d1559c 100644 VdpOutputSurfacePutBitsYCbCr * vdp_output_surface_put_bits_y_cb_cr; VdpOutputSurfacePutBitsNative * vdp_output_surface_put_bits_native; -@@ -158,15 +92,15 @@ class CVDPAU +@@ -158,15 +92,15 @@ VdpOutputSurfaceRenderOutputSurface * vdp_output_surface_render_output_surface; VdpOutputSurfacePutBitsIndexed * vdp_output_surface_put_bits_indexed; @@ -8834,7 +6064,7 @@ index 2f53edf..4d1559c 100644 VdpPresentationQueueTargetDestroy * vdp_presentation_queue_target_destroy; VdpPresentationQueueCreate * vdp_presentation_queue_create; -@@ -179,64 +113,459 @@ class CVDPAU +@@ -179,64 +113,462 @@ VdpGetErrorString * vdp_get_error_string; @@ -8852,21 +6082,20 @@ index 2f53edf..4d1559c 100644 - VdpOutputSurface outputSurfaces[NUM_OUTPUT_SURFACES]; - VdpOutputSurface outputSurface; - VdpOutputSurface presentSurface; -+}; - +- - VdpDecoder decoder; - VdpVideoMixer videoMixer; - VdpRect outRect; - VdpRect outRectVid; -+//----------------------------------------------------------------------------- -+// VDPAU data structs -+//----------------------------------------------------------------------------- ++}; - static void* dl_handle; - VdpStatus (*dl_vdp_device_create_x11)(Display* display, int screen, VdpDevice* device, VdpGetProcAddress **get_proc_address); - VdpStatus (*dl_vdp_get_proc_address)(VdpDevice device, VdpFuncId function_id, void** function_pointer); - VdpStatus (*dl_vdp_preemption_callback_register)(VdpDevice device, VdpPreemptionCallback callback, void* context); -+class CDecoder; ++//----------------------------------------------------------------------------- ++// VDPAU data structs ++//----------------------------------------------------------------------------- - int surfaceNum; - int presentSurfaceNum; @@ -8877,10 +6106,12 @@ index 2f53edf..4d1559c 100644 - Display* m_Display; - bool vdpauConfigured; - uint32_t *m_BlackBar; ++class CDecoder; ++ +/** + * Buffer statistics used to control number of frames in queue + */ - ++ +class CVdpauBufferStats +{ +public: @@ -8915,7 +6146,7 @@ index 2f53edf..4d1559c 100644 + * The structure is sent to the internal classes CMixer and COutput + * for init. + */ - ++ +struct CVdpauConfig +{ + int surfaceWidth; @@ -8940,7 +6171,7 @@ index 2f53edf..4d1559c 100644 + uint32_t maxReferences; + bool useInteropYuv; +}; -+ + +/** + * Holds a decoded frame + * Input to COutput for further processing @@ -9022,7 +6253,7 @@ index 2f53edf..4d1559c 100644 + PICTURE, + }; +}; -+ + +/** + * Embeds the vdpau video mixer + * Embedded by COutput class, gets decoded frames from COutput, processes @@ -9035,6 +6266,7 @@ index 2f53edf..4d1559c 100644 + virtual ~CMixer(); + void Start(); + void Dispose(); ++ bool IsActive(); + CMixerControlProtocol m_controlPort; + CMixerDataProtocol m_dataPort; +protected: @@ -9083,6 +6315,7 @@ index 2f53edf..4d1559c 100644 + int m_DeintMode; + int m_Deint; + int m_Upscale; ++ unsigned int m_ColorMatrix : 4; + uint32_t *m_BlackBar; VdpVideoMixerPictureStructure m_mixerfield; - int m_mixerstep; @@ -9203,6 +6436,7 @@ index 2f53edf..4d1559c 100644 + bool DestroyGlxContext(); + bool EnsureBufferPool(); + void ReleaseBufferPool(); ++ void PreCleanup(); + void InitMixer(); + bool GLInit(); + void GLMapSurfaces(); @@ -9333,7 +6567,7 @@ index 2f53edf..4d1559c 100644 // OnLostDevice triggers transition from all states to LOST // internal errors trigger transition from OPEN to RESET -@@ -247,9 +576,24 @@ class CVDPAU +@@ -247,9 +579,24 @@ , VDPAU_LOST , VDPAU_ERROR } m_DisplayState; @@ -9362,7357 +6596,9 @@ index 2f53edf..4d1559c 100644 }; + +} -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index d004153..92f62bb 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1146,6 +1146,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - formatstr = "VDPAU"; - buffering = true; - break; -+ case RENDER_FMT_VDPAU_420: -+ formatstr = "VDPAU_420"; -+ buffering = true; -+ break; - case RENDER_FMT_DXVA: - formatstr = "DXVA"; - buffering = true; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 16800b7..844f8e8 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -98,7 +98,7 @@ void CAdvancedSettings::Initialize() - m_videoIgnoreSecondsAtStart = 3*60; - m_videoIgnorePercentAtEnd = 8.0f; - m_videoPlayCountMinimumPercent = 90.0f; -- m_videoVDPAUScaling = false; -+ m_videoVDPAUScaling = -1; - m_videoNonLinStretchRatio = 0.5f; - m_videoEnableHighQualityHwScalers = false; - m_videoAutoScaleMaxFps = 30.0f; -@@ -106,6 +106,8 @@ void CAdvancedSettings::Initialize() - m_videoAllowMpeg4VAAPI = false; - m_videoDisableBackgroundDeinterlace = false; - m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect -+ m_videoVDPAUtelecine = false; -+ m_videoVDPAUdeintSkipChromaHD = false; - m_DXVACheckCompatibility = false; - m_DXVACheckCompatibilityPresent = false; - m_DXVAForceProcessorRenderer = true; -@@ -493,7 +495,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp); - XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint); - XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc); -- XMLUtils::GetBoolean(pElement,"vdpauscaling",m_videoVDPAUScaling); -+ XMLUtils::GetInt(pElement,"vdpauscaling",m_videoVDPAUScaling); - XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f); - XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); - XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); -@@ -501,6 +503,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI); - XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); - XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); -+ XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine); -+ XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); - - TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate"); - if (pAdjustRefreshrate) -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index 27887d4..72718e5 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -133,6 +133,8 @@ class CAdvancedSettings - int m_videoPercentSeekBackwardBig; - CStdString m_videoPPFFmpegDeint; - CStdString m_videoPPFFmpegPostProc; -+ bool m_videoVDPAUtelecine; -+ bool m_videoVDPAUdeintSkipChromaHD; - bool m_musicUseTimeSeeking; - int m_musicTimeSeekForward; - int m_musicTimeSeekBackward; -@@ -148,7 +150,7 @@ class CAdvancedSettings - CStdString m_audioHost; - bool m_audioApplyDrc; - -- bool m_videoVDPAUScaling; -+ int m_videoVDPAUScaling; - float m_videoNonLinStretchRatio; - bool m_videoEnableHighQualityHwScalers; - float m_videoAutoScaleMaxFps; -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 76ec0cc..4cdb093 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -685,6 +685,8 @@ void CGUISettings::Initialize() - - #ifdef HAVE_LIBVDPAU - AddBool(vp, "videoplayer.usevdpau", 13425, true); -+ AddBool(vp, "videoplayer.usevdpauinterop", 13435, true); -+ AddBool(vp, "videoplayer.usevdpauinteropyuv", 13436, false); - #endif - #ifdef HAVE_LIBVA - AddBool(vp, "videoplayer.usevaapi", 13426, true); -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index 4ac2663..d988598 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -596,6 +596,40 @@ void CGUIWindowSettingsCategory::UpdateSettings() - pControl->SetEnabled(true); - } - } -+ else if (strSetting.Equals("videoplayer.usevdpauinteropyuv")) -+ { -+ bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+#ifndef GL_NV_vdpau_interop -+ hasInterop = false; -+#endif -+ CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); -+ if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) -+ { -+ pControl->SetEnabled(true); -+ } -+ else -+ { -+ pControl->SetEnabled(false); -+ g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -+ } -+ } -+ else if (strSetting.Equals("videoplayer.usevdpauinterop")) -+ { -+ bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpau"); -+#ifndef GL_NV_vdpau_interop -+ hasInterop = false; -+#endif -+ CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); -+ if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) -+ { -+ pControl->SetEnabled(true); -+ } -+ else -+ { -+ pControl->SetEnabled(false); -+ g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -+ } -+ } - else - #endif - if (strSetting.Equals("videoscreen.resolution")) -diff --git a/xbmc/utils/ActorProtocol.cpp b/xbmc/utils/ActorProtocol.cpp -new file mode 100644 -index 0000000..e0cfd0e ---- /dev/null -+++ b/xbmc/utils/ActorProtocol.cpp -@@ -0,0 +1,253 @@ -+/* -+ * Copyright (C) 2005-2012 Team XBMC -+ * http://www.xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "ActorProtocol.h" -+ -+using namespace Actor; -+ -+void Message::Release() -+{ -+ bool skip; -+ origin->Lock(); -+ skip = isSync ? !isSyncFini : false; -+ isSyncFini = true; -+ origin->Unlock(); -+ -+ if (skip) -+ return; -+ -+ // free data buffer -+ if (data != buffer) -+ delete [] data; -+ -+ // delete event in case of sync message -+ if (event) -+ delete event; -+ -+ origin->ReturnMessage(this); -+} -+ -+bool Message::Reply(int sig, void *data /* = NULL*/, int size /* = 0 */) -+{ -+ if (!isSync) -+ { -+ if (isOut) -+ return origin->SendInMessage(sig, data, size); -+ else -+ return origin->SendOutMessage(sig, data, size); -+ } -+ -+ origin->Lock(); -+ -+ if (!isSyncTimeout) -+ { -+ Message *msg = origin->GetMessage(); -+ msg->signal = sig; -+ msg->isOut = !isOut; -+ replyMessage = msg; -+ if (data) -+ { -+ if (size > MSG_INTERNAL_BUFFER_SIZE) -+ msg->data = new uint8_t[size]; -+ else -+ msg->data = msg->buffer; -+ memcpy(msg->data, data, size); -+ } -+ } -+ -+ origin->Unlock(); -+ -+ if (event) -+ event->Set(); -+ -+ return true; -+} -+ -+Protocol::~Protocol() -+{ -+ Message *msg; -+ Purge(); -+ while (!freeMessageQueue.empty()) -+ { -+ msg = freeMessageQueue.front(); -+ freeMessageQueue.pop(); -+ delete msg; -+ } -+} -+ -+Message *Protocol::GetMessage() -+{ -+ Message *msg; -+ -+ CSingleLock lock(criticalSection); -+ -+ if (!freeMessageQueue.empty()) -+ { -+ msg = freeMessageQueue.front(); -+ freeMessageQueue.pop(); -+ } -+ else -+ msg = new Message(); -+ -+ msg->isSync = false; -+ msg->isSyncFini = false; -+ msg->isSyncTimeout = false; -+ msg->event = NULL; -+ msg->data = NULL; -+ msg->payloadSize = 0; -+ msg->replyMessage = NULL; -+ msg->origin = this; -+ -+ return msg; -+} -+ -+void Protocol::ReturnMessage(Message *msg) -+{ -+ CSingleLock lock(criticalSection); -+ -+ freeMessageQueue.push(msg); -+} -+ -+bool Protocol::SendOutMessage(int signal, void *data /* = NULL */, int size /* = 0 */, Message *outMsg /* = NULL */) -+{ -+ Message *msg; -+ if (outMsg) -+ msg = outMsg; -+ else -+ msg = GetMessage(); -+ -+ msg->signal = signal; -+ msg->isOut = true; -+ -+ if (data) -+ { -+ if (size > MSG_INTERNAL_BUFFER_SIZE) -+ msg->data = new uint8_t[size]; -+ else -+ msg->data = msg->buffer; -+ memcpy(msg->data, data, size); -+ } -+ -+ { CSingleLock lock(criticalSection); -+ outMessages.push(msg); -+ } -+ containerOutEvent->Set(); -+ -+ return true; -+} -+ -+bool Protocol::SendInMessage(int signal, void *data /* = NULL */, int size /* = 0 */, Message *outMsg /* = NULL */) -+{ -+ Message *msg; -+ if (outMsg) -+ msg = outMsg; -+ else -+ msg = GetMessage(); -+ -+ msg->signal = signal; -+ msg->isOut = false; -+ -+ if (data) -+ { -+ if (size > MSG_INTERNAL_BUFFER_SIZE) -+ msg->data = new uint8_t[size]; -+ else -+ msg->data = msg->buffer; -+ memcpy(msg->data, data, size); -+ } -+ -+ { CSingleLock lock(criticalSection); -+ inMessages.push(msg); -+ } -+ containerInEvent->Set(); -+ -+ return true; -+} -+ -+ -+bool Protocol::SendOutMessageSync(int signal, Message **retMsg, int timeout, void *data /* = NULL */, int size /* = 0 */) -+{ -+ Message *msg = GetMessage(); -+ msg->isOut = true; -+ msg->isSync = true; -+ msg->event = new CEvent; -+ msg->event->Reset(); -+ SendOutMessage(signal, data, size, msg); -+ -+ if (!msg->event->WaitMSec(timeout)) -+ { -+ msg->origin->Lock(); -+ if (msg->replyMessage) -+ *retMsg = msg->replyMessage; -+ else -+ { -+ *retMsg = NULL; -+ msg->isSyncTimeout = true; -+ } -+ msg->origin->Unlock(); -+ } -+ else -+ *retMsg = msg->replyMessage; -+ -+ msg->Release(); -+ -+ if (*retMsg) -+ return true; -+ else -+ return false; -+} -+ -+bool Protocol::ReceiveOutMessage(Message **msg) -+{ -+ CSingleLock lock(criticalSection); -+ -+ if (outMessages.empty() || outDefered) -+ return false; -+ -+ *msg = outMessages.front(); -+ outMessages.pop(); -+ -+ return true; -+} -+ -+bool Protocol::ReceiveInMessage(Message **msg) -+{ -+ CSingleLock lock(criticalSection); -+ -+ if (inMessages.empty() || inDefered) -+ return false; -+ -+ *msg = inMessages.front(); -+ inMessages.pop(); -+ -+ return true; -+} -+ -+ -+void Protocol::Purge() -+{ -+ Message *msg; -+ -+ while (ReceiveInMessage(&msg)) -+ msg->Release(); -+ -+ while (ReceiveOutMessage(&msg)) -+ msg->Release(); -+} -diff --git a/xbmc/utils/ActorProtocol.h b/xbmc/utils/ActorProtocol.h -new file mode 100644 -index 0000000..e7108ac ---- /dev/null -+++ b/xbmc/utils/ActorProtocol.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2005-2012 Team XBMC -+ * http://www.xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#pragma once -+ -+#include "threads/Thread.h" -+#include "utils/log.h" -+#include -+#include "memory.h" -+ -+#define MSG_INTERNAL_BUFFER_SIZE 32 -+ -+namespace Actor -+{ -+ -+class Protocol; -+ -+class Message -+{ -+ friend class Protocol; -+public: -+ int signal; -+ bool isSync; -+ bool isSyncFini; -+ bool isOut; -+ bool isSyncTimeout; -+ int payloadSize; -+ uint8_t buffer[MSG_INTERNAL_BUFFER_SIZE]; -+ uint8_t *data; -+ Message *replyMessage; -+ Protocol *origin; -+ CEvent *event; -+ -+ void Release(); -+ bool Reply(int sig, void *data = NULL, int size = 0); -+ -+private: -+ Message() {isSync = false; data = NULL; event = NULL; replyMessage = NULL;}; -+}; -+ -+class Protocol -+{ -+public: -+ Protocol(std::string name, CEvent* inEvent, CEvent *outEvent) -+ : portName(name), inDefered(false), outDefered(false) {containerInEvent = inEvent; containerOutEvent = outEvent;}; -+ virtual ~Protocol(); -+ Message *GetMessage(); -+ void ReturnMessage(Message *msg); -+ bool SendOutMessage(int signal, void *data = NULL, int size = 0, Message *outMsg = NULL); -+ bool SendInMessage(int signal, void *data = NULL, int size = 0, Message *outMsg = NULL); -+ bool SendOutMessageSync(int signal, Message **retMsg, int timeout, void *data = NULL, int size = 0); -+ bool ReceiveOutMessage(Message **msg); -+ bool ReceiveInMessage(Message **msg); -+ void Purge(); -+ void DeferIn(bool value) {inDefered = value;}; -+ void DeferOut(bool value) {outDefered = value;}; -+ void Lock() {criticalSection.lock();}; -+ void Unlock() {criticalSection.unlock();}; -+ std::string portName; -+ -+protected: -+ CEvent *containerInEvent, *containerOutEvent; -+ CCriticalSection criticalSection; -+ std::queue outMessages; -+ std::queue inMessages; -+ std::queue freeMessageQueue; -+ bool inDefered, outDefered; -+}; -+ -+} -diff --git a/xbmc/utils/Makefile b/xbmc/utils/Makefile -index d201884..7d1f9f0 100644 ---- a/xbmc/utils/Makefile -+++ b/xbmc/utils/Makefile -@@ -70,6 +70,7 @@ SRCS=AlarmClock.cpp \ - Weather.cpp \ - XBMCTinyXML.cpp \ - XMLUtils.cpp \ -+ ActorProtocol.cpp \ - - LIB=utils.a - -diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -index ac5f007..f25d10d 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -@@ -103,7 +103,7 @@ void CGUIDialogVideoSettings::CreateSettings() - entries.push_back(make_pair(VS_INTERLACEMETHOD_INVERSE_TELECINE , 16314)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL , 16311)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL , 16310)); -- entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_BOB , 16021)); -+ entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_BOB , 16325)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF, 16318)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF , 16317)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE , 16314)); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index e7af3cb..2dd8a9f 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -63,6 +63,7 @@ class CWinSystemX11 : public CWinSystemBase - // Local to WinSystemX11 only - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } -+ GLXContext GetGlxContext() { return m_glContext; } - - protected: - bool RefreshGlxContext(); --- -1.7.10 - - -From 999408daf66880f2efca154bf70bf2b778a5b67b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 09:52:17 +0100 -Subject: [PATCH 28/88] vdpau: make interop gl default and remove setting, - rename and intvert interop yuv - ---- - language/English/strings.po | 2 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 17 ++++++++++------- - xbmc/settings/GUISettings.cpp | 3 +-- - xbmc/settings/GUIWindowSettingsCategory.cpp | 23 +++-------------------- - 4 files changed, 15 insertions(+), 30 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 88292d3..4094fd0 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5119,7 +5119,7 @@ msgid "Allow Vdpau OpenGL interop" - msgstr "" - - msgctxt "#13436" --msgid "Allow Vdpau OpenGL interop YUV" -+msgid "Prefer VDPAU Video Mixer" - msgstr "" - - #empty strings from id 13437 to 13499 -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 07cfc04..0381c44 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -365,12 +365,15 @@ bool CDecoder::Supports(EINTERLACEMETHOD method) - || method == VS_INTERLACEMETHOD_AUTO) - return true; - -- if (g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv")) -+ if (!m_vdpauConfig.usePixmaps) - { - if (method == VS_INTERLACEMETHOD_RENDER_BOB) - return true; - } - -+ if (method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE) -+ return false; -+ - for(SInterlaceMapping* p = g_interlace_mapping; p->method != VS_INTERLACEMETHOD_NONE; p++) - { - if(p->method == method) -@@ -1847,7 +1850,7 @@ void CMixer::SetDeinterlacing() - - SetDeintSkipChroma(); - -- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); - } - - void CMixer::SetDeintSkipChroma() -@@ -2039,7 +2042,7 @@ void CMixer::Init() - m_vdpError = false; - - m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; -- m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !g_guiSettings.GetBool("videoplayer.usevdpaumixer"); - - CreateVdpauMixer(); - } -@@ -2149,11 +2152,12 @@ void CMixer::InitCycle() - DVP_FLAG_INTERLACED); - m_config.useInteropYuv = false; - } -- else if (method == VS_INTERLACEMETHOD_RENDER_BOB && m_config.useInteropYuv) -+ else if (method == VS_INTERLACEMETHOD_RENDER_BOB) - { - m_mixersteps = 1; - m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; - m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; -+ m_config.useInteropYuv = true; - } - else - { -@@ -3185,7 +3189,7 @@ bool COutput::GLInit() - glVDPAUGetSurfaceivNV = NULL; - #endif - -- m_config.usePixmaps = !g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+ m_config.usePixmaps = false; - - #ifdef GL_NV_vdpau_interop - if (glewIsSupported("GL_NV_vdpau_interop")) -@@ -3217,8 +3221,7 @@ bool COutput::GLInit() - #endif - { - m_config.usePixmaps = true; -- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -+ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); - } - if (!glXBindTexImageEXT) - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 4cdb093..33467d9 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -685,8 +685,7 @@ void CGUISettings::Initialize() - - #ifdef HAVE_LIBVDPAU - AddBool(vp, "videoplayer.usevdpau", 13425, true); -- AddBool(vp, "videoplayer.usevdpauinterop", 13435, true); -- AddBool(vp, "videoplayer.usevdpauinteropyuv", 13436, false); -+ AddBool(vp, "videoplayer.usevdpaumixer", 13436, true); - #endif - #ifdef HAVE_LIBVA - AddBool(vp, "videoplayer.usevaapi", 13426, true); -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index d988598..2af9315 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -596,9 +596,9 @@ void CGUIWindowSettingsCategory::UpdateSettings() - pControl->SetEnabled(true); - } - } -- else if (strSetting.Equals("videoplayer.usevdpauinteropyuv")) -+ else if (strSetting.Equals("videoplayer.usevdpaumixer")) - { -- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+ bool hasInterop = true; - #ifndef GL_NV_vdpau_interop - hasInterop = false; - #endif -@@ -610,24 +610,7 @@ void CGUIWindowSettingsCategory::UpdateSettings() - else - { - pControl->SetEnabled(false); -- g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -- } -- } -- else if (strSetting.Equals("videoplayer.usevdpauinterop")) -- { -- bool hasInterop = g_guiSettings.GetBool("videoplayer.usevdpau"); --#ifndef GL_NV_vdpau_interop -- hasInterop = false; --#endif -- CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); -- if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) -- { -- pControl->SetEnabled(true); -- } -- else -- { -- pControl->SetEnabled(false); -- g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -+ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); - } - } - else --- -1.7.10 - - -From 9a26e5a08777c1d928bc3e9e9f8cdb2bb9258917 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 18:34:47 +0100 -Subject: [PATCH 29/88] vdpau: drop studio level conversion - ---- - language/English/strings.po | 6 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 4 +- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 94 +----------------------- - xbmc/settings/GUISettings.cpp | 1 - - 4 files changed, 7 insertions(+), 98 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index 4094fd0..c3ba92f 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -4369,11 +4369,7 @@ msgctxt "#13121" - msgid "VDPAU HQ Upscaling level" - msgstr "" - --msgctxt "#13122" --msgid "VDPAU Studio level color conversion" --msgstr "" -- --#empty strings from id 13123 to 13129 -+#empty strings from id 13122 to 13129 - - msgctxt "#13130" - msgid "Blank other displays" -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 4ee50c1..d2ba962 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -3344,7 +3344,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - { - if(feature == RENDERFEATURE_BRIGHTNESS) - { -- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -+ if (m_renderMethod & RENDER_VDPAU) - return true; - - if (m_renderMethod & RENDER_VAAPI) -@@ -3357,7 +3357,7 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - - if(feature == RENDERFEATURE_CONTRAST) - { -- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -+ if (m_renderMethod & RENDER_VDPAU) - return true; - - if (m_renderMethod & RENDER_VAAPI) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 0381c44..15c58b8 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -57,15 +57,6 @@ - }; - const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); - --//static float studioCSC[3][4] = --//{ --// { 1.0f, 0.0f, 1.57480000f,-0.78740000f}, --// { 1.0f,-0.18737736f,-0.46813736f, 0.32775736f}, --// { 1.0f, 1.85556000f, 0.0f,-0.92780000f} --//}; --static float studioCSCKCoeffs601[3] = {0.299, 0.587, 0.114}; //BT601 {Kr, Kg, Kb} --static float studioCSCKCoeffs709[3] = {0.2126, 0.7152, 0.0722}; //BT709 {Kr, Kg, Kb} -- - static struct SInterlaceMapping - { - const EINTERLACEMETHOD method; -@@ -1614,74 +1605,6 @@ void CMixer::PostProcOff() - DisableHQScaling(); - } - -- --bool CMixer::GenerateStudioCSCMatrix(VdpColorStandard colorStandard, VdpCSCMatrix &studioCSCMatrix) --{ -- // instead use studioCSCKCoeffs601[3], studioCSCKCoeffs709[3] to generate float[3][4] matrix (float studioCSC[3][4]) -- // m00 = mRY = red: luma factor (contrast factor) (1.0) -- // m10 = mGY = green: luma factor (contrast factor) (1.0) -- // m20 = mBY = blue: luma factor (contrast factor) (1.0) -- // -- // m01 = mRB = red: blue color diff coeff (0.0) -- // m11 = mGB = green: blue color diff coeff (-2Kb(1-Kb)/(Kg)) -- // m21 = mBB = blue: blue color diff coeff ((1-Kb)/0.5) -- // -- // m02 = mRR = red: red color diff coeff ((1-Kr)/0.5) -- // m12 = mGR = green: red color diff coeff (-2Kr(1-Kr)/(Kg)) -- // m22 = mBR = blue: red color diff coeff (0.0) -- // -- // m03 = mRC = red: colour zero offset (brightness factor) (-(1-Kr)/0.5 * (128/255)) -- // m13 = mGC = green: colour zero offset (brightness factor) ((256/255) * (Kb(1-Kb) + Kr(1-Kr)) / Kg) -- // m23 = mBC = blue: colour zero offset (brightness factor) (-(1-Kb)/0.5 * (128/255)) -- -- // columns -- int Y = 0; -- int Cb = 1; -- int Cr = 2; -- int C = 3; -- // rows -- int R = 0; -- int G = 1; -- int B = 2; -- // colour standard coefficients for red, geen, blue -- double Kr, Kg, Kb; -- // colour diff zero position (use standard 8-bit coding precision) -- double CDZ = 128; //256*0.5 -- // range excursion (use standard 8-bit coding precision) -- double EXC = 255; //256-1 -- -- if (colorStandard == VDP_COLOR_STANDARD_ITUR_BT_601) -- { -- Kr = studioCSCKCoeffs601[0]; -- Kg = studioCSCKCoeffs601[1]; -- Kb = studioCSCKCoeffs601[2]; -- } -- else // assume VDP_COLOR_STANDARD_ITUR_BT_709 -- { -- Kr = studioCSCKCoeffs709[0]; -- Kg = studioCSCKCoeffs709[1]; -- Kb = studioCSCKCoeffs709[2]; -- } -- // we keep luma unscaled to retain the levels present in source so that 16-235 luma is converted to RGB 16-235 -- studioCSCMatrix[R][Y] = 1.0; -- studioCSCMatrix[G][Y] = 1.0; -- studioCSCMatrix[B][Y] = 1.0; -- -- studioCSCMatrix[R][Cb] = 0.0; -- studioCSCMatrix[G][Cb] = (double)-2 * Kb * (1 - Kb) / Kg; -- studioCSCMatrix[B][Cb] = (double)(1 - Kb) / 0.5; -- -- studioCSCMatrix[R][Cr] = (double)(1 - Kr) / 0.5; -- studioCSCMatrix[G][Cr] = (double)-2 * Kr * (1 - Kr) / Kg; -- studioCSCMatrix[B][Cr] = 0.0; -- -- studioCSCMatrix[R][C] = (double)-1 * studioCSCMatrix[R][Cr] * CDZ/EXC; -- studioCSCMatrix[G][C] = (double)-1 * (studioCSCMatrix[G][Cb] + studioCSCMatrix[G][Cr]) * CDZ/EXC; -- studioCSCMatrix[B][C] = (double)-1 * studioCSCMatrix[B][Cb] * CDZ/EXC; -- -- return true; --} -- - void CMixer::SetColor() - { - VdpStatus vdp_st; -@@ -1701,19 +1624,10 @@ void CMixer::SetColor() - //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); - - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; -- if (g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) -- { -- float studioCSC[3][4]; -- GenerateStudioCSCMatrix(colorStandard, studioCSC); -- void const * pm_CSCMatix[] = { &studioCSC }; -- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -- else -- { -- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -- void const * pm_CSCMatix[] = { &m_CSCMatrix }; -- vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -+ vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -+ void const * pm_CSCMatix[] = { &m_CSCMatrix }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -+ - CheckStatus(vdp_st, __LINE__); - } - -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 33467d9..4cec1b3 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -764,7 +764,6 @@ void CGUISettings::Initialize() - AddSeparator(vp, "videoplayer.sep1.5"); - #ifdef HAVE_LIBVDPAU - AddBool(NULL, "videoplayer.vdpauUpscalingLevel", 13121, false); -- AddBool(vp, "videoplayer.vdpaustudiolevel", 13122, false); - #endif - #endif - AddSeparator(vp, "videoplayer.sep5"); --- -1.7.10 - - -From cf77997579bf3f5a46e17b6c1f9753f68ad49ce5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 20:28:49 +0100 -Subject: [PATCH 30/88] vdpau: observe ffmpeg tags for color space - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 38 ++++++++++++++++-------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 1 + - 2 files changed, 27 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 15c58b8..34cc320 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -907,6 +907,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) - memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); - ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); - pic.render = render; -+ pic.DVDPic.color_matrix = avctx->colorspace; - m_bufferStats.IncDecoded(); - m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - -@@ -1513,10 +1514,6 @@ void CMixer::InitCSCMatrix(int Width) - m_Procamp.contrast = 1.0; - m_Procamp.saturation = 1.0; - m_Procamp.hue = 0; -- vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, -- (Width < 1000)? VDP_COLOR_STANDARD_ITUR_BT_601 : VDP_COLOR_STANDARD_ITUR_BT_709, -- &m_CSCMatrix); -- CheckStatus(vdp_st, __LINE__); - } - - void CMixer::CheckFeatures() -@@ -1527,11 +1524,13 @@ void CMixer::CheckFeatures() - m_Upscale = m_config.upscale; - } - if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness || -- m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) -+ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast || -+ m_ColorMatrix != m_mixerInput[1].DVDPic.color_matrix) - { - SetColor(); - m_Brightness = g_settings.m_currentVideoSettings.m_Brightness; - m_Contrast = g_settings.m_currentVideoSettings.m_Contrast; -+ m_ColorMatrix = m_mixerInput[1].DVDPic.color_matrix; - } - if (m_NoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) - { -@@ -1615,13 +1614,27 @@ void CMixer::SetColor() - m_Procamp.contrast = (float)((g_settings.m_currentVideoSettings.m_Contrast)+50) / 100; - - VdpColorStandard colorStandard; --// if(vid_height >= 600 || vid_width > 1024) -- if(m_config.surfaceWidth > 1000) -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); -- else -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); -+ switch(m_mixerInput[1].DVDPic.color_matrix) -+ { -+ case AVCOL_SPC_BT709: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ break; -+ case AVCOL_SPC_BT470BG: -+ case AVCOL_SPC_SMPTE170M: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ break; -+ case AVCOL_SPC_SMPTE240M: -+ colorStandard = VDP_COLOR_STANDARD_SMPTE_240M; -+ break; -+ case AVCOL_SPC_FCC: -+ case AVCOL_SPC_UNSPECIFIED: -+ case AVCOL_SPC_RGB: -+ default: -+ if(m_config.surfaceWidth > 1000) -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ else -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ } - - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; - vdp_st = m_config.vdpProcs.vdp_generate_csc_matrix(&m_Procamp, colorStandard, &m_CSCMatrix); -@@ -1952,6 +1965,7 @@ void CMixer::Init() - m_Sharpness = 0.0; - m_DeintMode = 0; - m_Deint = 0; -+ m_ColorMatrix = 0; - m_PostProc = false; - m_vdpError = false; - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index 4d1559c..471ad68 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -334,6 +334,7 @@ class CMixer : private CThread - int m_DeintMode; - int m_Deint; - int m_Upscale; -+ unsigned int m_ColorMatrix : 4; - uint32_t *m_BlackBar; - VdpVideoMixerPictureStructure m_mixerfield; - int m_mixerstep; --- -1.7.10 - - -From 4eef23adc7b4539fc8e1b87c7f2f6797b32b82ea Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 27 Jan 2013 12:10:19 +0100 -Subject: [PATCH 31/88] vdpau: switch off de-interlacing on ff - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 34cc320..5de75ab 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2043,8 +2043,9 @@ void CMixer::InitCycle() - EINTERLACEMETHOD method = GetDeinterlacingMethod(); - bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; - -- if (mode == VS_DEINTERLACEMODE_FORCE || -- (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) -+ if (!(flags & DVP_FLAG_NO_POSTPROC) && -+ (mode == VS_DEINTERLACEMODE_FORCE || -+ (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) - { - if((method == VS_INTERLACEMETHOD_AUTO && interlaced) - || method == VS_INTERLACEMETHOD_VDPAU_BOB --- -1.7.10 - - -From 96ef99611c9cd1740faf8dd02b09e4cbb5e9cdc0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Feb 2013 13:17:09 +0100 -Subject: [PATCH 32/88] vdpau: fix mp4 part2 decoding, activate by default - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++------ - xbmc/settings/AdvancedSettings.cpp | 2 +- - 2 files changed, 3 insertions(+), 7 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 5de75ab..68cf36a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -127,10 +127,9 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int - VdpDecoderProfile profile = 0; - if(avctx->codec_id == CODEC_ID_H264) - profile = VDP_DECODER_PROFILE_H264_HIGH; --#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP - else if(avctx->codec_id == CODEC_ID_MPEG4) - profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; --#endif -+ - if(profile) - { - if (!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width)) -@@ -530,13 +529,10 @@ void CDecoder::ReadFormatOf( PixelFormat fmt - vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; --#if (defined PIX_FMT_VDPAU_MPEG4_IN_AVUTIL) && \ -- (defined VDP_DECODER_PROFILE_MP) - case PIX_FMT_VDPAU_MPEG4: -- vdp_decoder_profile = VDP_DECOPEG4_PART2_ASP; -+ vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; --#endif - default: - vdp_decoder_profile = 0; - vdp_chroma_type = 0; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 844f8e8..04a7c7c 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -102,7 +102,7 @@ void CAdvancedSettings::Initialize() - m_videoNonLinStretchRatio = 0.5f; - m_videoEnableHighQualityHwScalers = false; - m_videoAutoScaleMaxFps = 30.0f; -- m_videoAllowMpeg4VDPAU = false; -+ m_videoAllowMpeg4VDPAU = true; - m_videoAllowMpeg4VAAPI = false; - m_videoDisableBackgroundDeinterlace = false; - m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect --- -1.7.10 - - -From 477502af4a70f4251652c955e6e048025bb32514 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 12:14:15 +0200 -Subject: [PATCH 33/88] linuxrenderer: drop method RenderMultiPass - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 9 ++------- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 1 - - 2 files changed, 2 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index d2ba962..62198f0 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -1205,7 +1205,8 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - break; - - case RQ_MULTIPASS: -- RenderMultiPass(renderBuffer, m_currentField); -+ RenderToFBO(renderBuffer, m_currentField); -+ RenderFromFBO(); - VerifyGLState(); - break; - } -@@ -1328,12 +1329,6 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field) - VerifyGLState(); - } - --void CLinuxRendererGL::RenderMultiPass(int index, int field) --{ -- RenderToFBO(index, field); -- RenderFromFBO(); --} -- - void CLinuxRendererGL::RenderToFBO(int index, int field) - { - YUVPLANES &planes = m_buffers[index].fields[field]; -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 329ddee..08f8234 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -216,7 +216,6 @@ class CLinuxRendererGL : public CBaseRenderer - void CalculateTextureSourceRects(int source, int num_planes); - - // renderers -- void RenderMultiPass(int renderBuffer, int field); // multi pass glsl renderer - void RenderToFBO(int renderBuffer, int field); - void RenderFromFBO(); - void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer --- -1.7.10 - - -From 48fb2351e755727506993d6fd0334c368fffbee6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 13:20:47 +0200 -Subject: [PATCH 34/88] linuxrenderer: implement progressive weave for vdpau - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 55 ++++++++++++++++++------- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 4 +- - 2 files changed, 41 insertions(+), 18 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 62198f0..6e6d97e 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -689,18 +689,6 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) - glDisable(GL_POLYGON_STIPPLE); - - } -- else if(m_format == RENDER_FMT_VDPAU_420 -- && !(flags & RENDER_FLAG_BOTH)) -- { -- glDisable(GL_BLEND); -- glColor4f(1.0f, 1.0f, 1.0f, 1.0f); -- Render(flags | RENDER_FLAG_TOP, index); -- -- glEnable(GL_BLEND); -- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -- glColor4f(1.0f, 1.0f, 1.0f, 128 / 255.0f); -- Render(flags | RENDER_FLAG_BOT , index); -- } - else - Render(flags, index); - -@@ -1200,13 +1188,21 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - { - case RQ_LOW: - case RQ_SINGLEPASS: -- RenderSinglePass(renderBuffer, m_currentField); -+ if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL) -+ RenderProgressiveWeave(renderBuffer, m_currentField); -+ else -+ RenderSinglePass(renderBuffer, m_currentField); - VerifyGLState(); - break; - - case RQ_MULTIPASS: -- RenderToFBO(renderBuffer, m_currentField); -- RenderFromFBO(); -+ if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL) -+ RenderProgressiveWeave(renderBuffer, m_currentField); -+ else -+ { -+ RenderToFBO(renderBuffer, m_currentField); -+ RenderFromFBO(); -+ } - VerifyGLState(); - break; - } -@@ -1329,7 +1325,7 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field) - VerifyGLState(); - } - --void CLinuxRendererGL::RenderToFBO(int index, int field) -+void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/) - { - YUVPLANES &planes = m_buffers[index].fields[field]; - -@@ -1431,6 +1427,8 @@ void CLinuxRendererGL::RenderToFBO(int index, int field) - } - m_fbo.width *= planes[0].pixpertex_x; - m_fbo.height *= planes[0].pixpertex_y; -+ if (weave) -+ m_fbo.height *= 2; - - // 1st Pass to video frame size - glBegin(GL_QUADS); -@@ -1549,6 +1547,31 @@ void CLinuxRendererGL::RenderFromFBO() - VerifyGLState(); - } - -+void CLinuxRendererGL::RenderProgressiveWeave(int index, int field) -+{ -+ bool scaleUp = (int)m_sourceHeight < g_graphicsContext.GetHeight() || (int)m_sourceWidth < g_graphicsContext.GetWidth(); -+ -+ if (m_fbo.fbo.IsSupported() && (scaleUp || m_renderQuality == RQ_MULTIPASS)) -+ { -+ glEnable(GL_POLYGON_STIPPLE); -+ glPolygonStipple(stipple_weave); -+ RenderToFBO(index, FIELD_TOP, true); -+ glPolygonStipple(stipple_weave+4); -+ RenderToFBO(index, FIELD_BOT, true); -+ glDisable(GL_POLYGON_STIPPLE); -+ RenderFromFBO(); -+ } -+ else -+ { -+ glEnable(GL_POLYGON_STIPPLE); -+ glPolygonStipple(stipple_weave); -+ RenderSinglePass(index, FIELD_TOP); -+ glPolygonStipple(stipple_weave+4); -+ RenderSinglePass(index, FIELD_BOT); -+ glDisable(GL_POLYGON_STIPPLE); -+ } -+} -+ - void CLinuxRendererGL::RenderVDPAU(int index, int field) - { - #ifdef HAVE_LIBVDPAU -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 08f8234..13217ce 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -216,12 +216,12 @@ class CLinuxRendererGL : public CBaseRenderer - void CalculateTextureSourceRects(int source, int num_planes); - - // renderers -- void RenderToFBO(int renderBuffer, int field); -+ void RenderToFBO(int renderBuffer, int field, bool weave = false); - void RenderFromFBO(); - void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer - void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer - void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware -- void RenderVDPAUYV12(int renderBuffer, int field); // render using vdpau hardware -+ void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware - void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware - - struct --- -1.7.10 - - -From 46d819fbe6386640cee6bf94b3c6df8b78addaa5 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 35/88] X11: ditch SDL for video and window events - ---- - xbmc/Application.cpp | 2 +- - xbmc/system.h | 5 + - xbmc/windowing/Makefile | 1 + - xbmc/windowing/WinEvents.h | 4 + - xbmc/windowing/WinEventsX11.cpp | 765 +++++++++++++++++++++++++++++++++++ - xbmc/windowing/WinEventsX11.h | 57 +++ - xbmc/windowing/X11/WinSystemX11.cpp | 370 ++++++++++++----- - xbmc/windowing/X11/WinSystemX11.h | 9 +- - 8 files changed, 1112 insertions(+), 101 deletions(-) - create mode 100644 xbmc/windowing/WinEventsX11.cpp - create mode 100644 xbmc/windowing/WinEventsX11.h - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 5c7017c..8259eba 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -794,7 +794,7 @@ bool CApplication::CreateGUI() - - uint32_t sdlFlags = 0; - --#if defined(HAS_SDL_OPENGL) || (HAS_GLES == 2) -+#if (defined(HAS_SDL_OPENGL) || (HAS_GLES == 2)) && !defined(HAS_GLX) - sdlFlags |= SDL_INIT_VIDEO; - #endif - -diff --git a/xbmc/system.h b/xbmc/system.h -index 4165c01..32584b1 100644 ---- a/xbmc/system.h -+++ b/xbmc/system.h -@@ -162,16 +162,21 @@ - #define HAS_GL - #ifdef HAVE_X11 - #define HAS_GLX -+#define HAS_X11_WIN_EVENTS - #endif - #ifdef HAVE_SDL - #define HAS_SDL - #ifndef HAS_SDL_OPENGL - #define HAS_SDL_OPENGL - #endif -+#ifndef HAVE_X11 - #define HAS_SDL_WIN_EVENTS -+#endif - #else -+#ifndef HAVE_X11 - #define HAS_LINUX_EVENTS - #endif -+#endif - #define HAS_LINUX_NETWORK - #define HAS_LIRC - #ifdef HAVE_LIBPULSE -diff --git a/xbmc/windowing/Makefile b/xbmc/windowing/Makefile -index f109bec..f981642 100644 ---- a/xbmc/windowing/Makefile -+++ b/xbmc/windowing/Makefile -@@ -1,6 +1,7 @@ - SRCS=WinEventsSDL.cpp \ - WinEventsLinux.cpp \ - WinSystem.cpp \ -+ WinEventsX11.cpp \ - - LIB=windowing.a - -diff --git a/xbmc/windowing/WinEvents.h b/xbmc/windowing/WinEvents.h -index 6d322a9..5a671cc 100644 ---- a/xbmc/windowing/WinEvents.h -+++ b/xbmc/windowing/WinEvents.h -@@ -58,6 +58,10 @@ class CWinEventsBase - #include "WinEventsSDL.h" - #define CWinEvents CWinEventsSDL - -+#elif defined(TARGET_LINUX) && defined(HAS_X11_WIN_EVENTS) -+#include "WinEventsX11.h" -+#define CWinEvents CWinEventsX11 -+ - #elif defined(TARGET_LINUX) && defined(HAS_LINUX_EVENTS) - #include "WinEventsLinux.h" - #define CWinEvents CWinEventsLinux -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -new file mode 100644 -index 0000000..24477ae ---- /dev/null -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -0,0 +1,765 @@ -+/* -+* Copyright (C) 2005-2012 Team XBMC -+* http://www.xbmc.org -+* -+* This Program is free software; you can redistribute it and/or modify -+* it under the terms of the GNU General Public License as published by -+* the Free Software Foundation; either version 2, or (at your option) -+* any later version. -+* -+* This Program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+* GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License -+* along with XBMC; see the file COPYING. If not, write to -+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+* http://www.gnu.org/copyleft/gpl.html -+* -+*/ -+ -+#include "system.h" -+ -+#ifdef HAS_X11_WIN_EVENTS -+ -+#include "WinEvents.h" -+#include "WinEventsX11.h" -+#include "Application.h" -+#include "ApplicationMessenger.h" -+#include -+#include "X11/WinSystemX11GL.h" -+#include "X11/keysymdef.h" -+#include "X11/XF86keysym.h" -+#include "utils/log.h" -+#include "guilib/GUIWindowManager.h" -+#include "input/MouseStat.h" -+ -+CWinEventsX11* CWinEventsX11::WinEvents = 0; -+ -+static uint32_t SymMappingsX11[][2] = -+{ -+ {XK_BackSpace, XBMCK_BACKSPACE} -+, {XK_Tab, XBMCK_TAB} -+, {XK_Clear, XBMCK_CLEAR} -+, {XK_Return, XBMCK_RETURN} -+, {XK_Pause, XBMCK_PAUSE} -+, {XK_Escape, XBMCK_ESCAPE} -+, {XK_Delete, XBMCK_DELETE} -+// multi-media keys -+, {XF86XK_Back, XBMCK_BROWSER_BACK} -+, {XF86XK_Forward, XBMCK_BROWSER_FORWARD} -+, {XF86XK_Refresh, XBMCK_BROWSER_REFRESH} -+, {XF86XK_Stop, XBMCK_BROWSER_STOP} -+, {XF86XK_Search, XBMCK_BROWSER_SEARCH} -+, {XF86XK_Favorites, XBMCK_BROWSER_FAVORITES} -+, {XF86XK_HomePage, XBMCK_BROWSER_HOME} -+, {XF86XK_AudioMute, XBMCK_VOLUME_MUTE} -+, {XF86XK_AudioLowerVolume, XBMCK_VOLUME_DOWN} -+, {XF86XK_AudioRaiseVolume, XBMCK_VOLUME_UP} -+, {XF86XK_AudioNext, XBMCK_MEDIA_NEXT_TRACK} -+, {XF86XK_AudioPrev, XBMCK_MEDIA_PREV_TRACK} -+, {XF86XK_AudioStop, XBMCK_MEDIA_STOP} -+, {XF86XK_AudioPause, XBMCK_MEDIA_PLAY_PAUSE} -+, {XF86XK_Mail, XBMCK_LAUNCH_MAIL} -+, {XF86XK_Select, XBMCK_LAUNCH_MEDIA_SELECT} -+, {XF86XK_Launch0, XBMCK_LAUNCH_APP1} -+, {XF86XK_Launch1, XBMCK_LAUNCH_APP2} -+, {XF86XK_WWW, XBMCK_LAUNCH_FILE_BROWSER} -+, {XF86XK_AudioMedia, XBMCK_LAUNCH_MEDIA_CENTER } -+ // Numeric keypad -+, {XK_KP_0, XBMCK_KP0} -+, {XK_KP_1, XBMCK_KP1} -+, {XK_KP_2, XBMCK_KP2} -+, {XK_KP_3, XBMCK_KP3} -+, {XK_KP_4, XBMCK_KP4} -+, {XK_KP_5, XBMCK_KP5} -+, {XK_KP_6, XBMCK_KP6} -+, {XK_KP_7, XBMCK_KP7} -+, {XK_KP_8, XBMCK_KP8} -+, {XK_KP_9, XBMCK_KP9} -+, {XK_KP_Separator, XBMCK_KP_PERIOD} -+, {XK_KP_Divide, XBMCK_KP_DIVIDE} -+, {XK_KP_Multiply, XBMCK_KP_MULTIPLY} -+, {XK_KP_Subtract, XBMCK_KP_MINUS} -+, {XK_KP_Add, XBMCK_KP_PLUS} -+, {XK_KP_Enter, XBMCK_KP_ENTER} -+, {XK_KP_Equal, XBMCK_KP_EQUALS} -+ // Arrows + Home/End pad -+, {XK_Up, XBMCK_UP} -+, {XK_Down, XBMCK_DOWN} -+, {XK_Right, XBMCK_RIGHT} -+, {XK_Left, XBMCK_LEFT} -+, {XK_Insert, XBMCK_INSERT} -+, {XK_Home, XBMCK_HOME} -+, {XK_End, XBMCK_END} -+, {XK_Page_Up, XBMCK_PAGEUP} -+, {XK_Page_Down, XBMCK_PAGEDOWN} -+ // Function keys -+, {XK_F1, XBMCK_F1} -+, {XK_F2, XBMCK_F2} -+, {XK_F3, XBMCK_F3} -+, {XK_F4, XBMCK_F4} -+, {XK_F5, XBMCK_F5} -+, {XK_F6, XBMCK_F6} -+, {XK_F7, XBMCK_F7} -+, {XK_F8, XBMCK_F8} -+, {XK_F9, XBMCK_F9} -+, {XK_F10, XBMCK_F10} -+, {XK_F11, XBMCK_F11} -+, {XK_F12, XBMCK_F12} -+, {XK_F13, XBMCK_F13} -+, {XK_F14, XBMCK_F14} -+, {XK_F15, XBMCK_F15} -+ // Key state modifier keys -+, {XK_Num_Lock, XBMCK_NUMLOCK} -+, {XK_Caps_Lock, XBMCK_CAPSLOCK} -+, {XK_Scroll_Lock, XBMCK_SCROLLOCK} -+, {XK_Shift_R, XBMCK_RSHIFT} -+, {XK_Shift_L, XBMCK_LSHIFT} -+, {XK_Control_R, XBMCK_RCTRL} -+, {XK_Control_L, XBMCK_LCTRL} -+, {XK_Alt_R, XBMCK_RALT} -+, {XK_Alt_L, XBMCK_LALT} -+, {XK_Meta_R, XBMCK_RMETA} -+, {XK_Meta_L, XBMCK_LMETA} -+, {XK_Super_L, XBMCK_LSUPER} -+, {XK_Super_R, XBMCK_RSUPER} -+, {XK_Mode_switch, XBMCK_MODE} -+, {XK_Multi_key, XBMCK_COMPOSE} -+ // Miscellaneous function keys -+, {XK_Help, XBMCK_HELP} -+, {XK_Print, XBMCK_PRINT} -+//, {0, XBMCK_SYSREQ} -+, {XK_Break, XBMCK_BREAK} -+, {XK_Menu, XBMCK_MENU} -+, {XF86XK_PowerOff, XBMCK_POWER} -+, {XK_EcuSign, XBMCK_EURO} -+, {XK_Undo, XBMCK_UNDO} -+ /* Media keys */ -+, {XF86XK_Eject, XBMCK_EJECT} -+, {XF86XK_Stop, XBMCK_STOP} -+, {XF86XK_AudioRecord, XBMCK_RECORD} -+, {XF86XK_AudioRewind, XBMCK_REWIND} -+, {XF86XK_Phone, XBMCK_PHONE} -+, {XF86XK_AudioPlay, XBMCK_PLAY} -+, {XF86XK_AudioRandomPlay, XBMCK_SHUFFLE} -+, {XF86XK_AudioForward, XBMCK_FASTFORWARD} -+}; -+ -+ -+CWinEventsX11::CWinEventsX11() -+{ -+ m_display = 0; -+ m_window = 0; -+ m_keybuf = 0; -+ m_utf16buf = 0; -+} -+ -+CWinEventsX11::~CWinEventsX11() -+{ -+ if (m_keybuf); -+ { -+ free(m_keybuf); -+ m_keybuf = 0; -+ } -+ -+ if (m_utf16buf) -+ { -+ free(m_utf16buf); -+ m_utf16buf = 0; -+ } -+ -+ if (m_xic) -+ { -+ XUnsetICFocus(m_xic); -+ XDestroyIC(m_xic); -+ m_xic = 0; -+ } -+ -+ if (m_xim) -+ { -+ XCloseIM(m_xim); -+ m_xim = 0; -+ } -+ -+ m_symLookupTable.clear(); -+} -+ -+bool CWinEventsX11::Init(Display *dpy, Window win) -+{ -+ if (WinEvents) -+ return true; -+ -+ WinEvents = new CWinEventsX11(); -+ WinEvents->m_display = dpy; -+ WinEvents->m_window = win; -+ WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -+ WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); -+ WinEvents->m_keymodState = 0; -+ WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -+ WinEvents->m_structureChanged = false; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); -+ -+ // open input method -+ char *old_locale = NULL, *old_modifiers = NULL; -+ char res_name[8]; -+ const char *p; -+ size_t n; -+ -+ // set resource name to xbmc, not used -+ strcpy(res_name, "xbmc"); -+ -+ // save current locale, this should be "C" -+ p = setlocale(LC_ALL, NULL); -+ if (p) -+ { -+ old_locale = (char*)malloc(strlen(p) +1); -+ strcpy(old_locale, p); -+ } -+ p = XSetLocaleModifiers(NULL); -+ if (p) -+ { -+ old_modifiers = (char*)malloc(strlen(p) +1); -+ strcpy(old_modifiers, p); -+ } -+ -+ // set users preferences and open input method -+ p = setlocale(LC_ALL, ""); -+ XSetLocaleModifiers(""); -+ WinEvents->m_xim = XOpenIM(WinEvents->m_display, NULL, res_name, res_name); -+ -+ // restore old locale -+ if (old_locale) -+ { -+ setlocale(LC_ALL, old_locale); -+ free(old_locale); -+ } -+ if (old_modifiers) -+ { -+ XSetLocaleModifiers(old_modifiers); -+ free(old_modifiers); -+ } -+ -+ WinEvents->m_xic = NULL; -+ if (WinEvents->m_xim) -+ { -+ WinEvents->m_xic = XCreateIC(WinEvents->m_xim, -+ XNClientWindow, WinEvents->m_window, -+ XNFocusWindow, WinEvents->m_window, -+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing, -+ XNResourceName, res_name, -+ XNResourceClass, res_name, -+ NULL); -+ } -+ -+ if (!WinEvents->m_xic) -+ CLog::Log(LOGWARNING,"CWinEventsX11::Init - no input method found"); -+ -+ // build Keysym lookup table -+ for (unsigned int i = 0; i < sizeof(SymMappingsX11)/(2*sizeof(uint32_t)); ++i) -+ { -+ WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; -+ } -+ -+ return true; -+} -+ -+void CWinEventsX11::Quit() -+{ -+ if (!WinEvents) -+ return; -+ -+ delete WinEvents; -+ WinEvents = 0; -+} -+ -+bool CWinEventsX11::HasStructureChanged() -+{ -+ if (!WinEvents) -+ return false; -+ -+ bool ret = WinEvents->m_structureChanged; -+ WinEvents->m_structureChanged = false; -+ return ret; -+} -+ -+bool CWinEventsX11::MessagePump() -+{ -+ if (!WinEvents) -+ return false; -+ -+ bool ret = false; -+ XEvent xevent; -+ unsigned long serial = 0; -+ -+ while (WinEvents && XPending(WinEvents->m_display)) -+ { -+ memset(&xevent, 0, sizeof (XEvent)); -+ XNextEvent(WinEvents->m_display, &xevent); -+ -+ // ignore events generated by auto-repeat -+ if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) -+ { -+ XEvent peekevent; -+ XPeekEvent(WinEvents->m_display, &peekevent); -+ if ((peekevent.type == KeyPress) && -+ (peekevent.xkey.keycode == xevent.xkey.keycode) && -+ ((peekevent.xkey.time - xevent.xkey.time) < 2)) -+ { -+ XNextEvent(WinEvents->m_display, &peekevent); -+ continue; -+ } -+ } -+ -+ if (XFilterEvent(&xevent, None)) -+ continue; -+ -+ switch (xevent.type) -+ { -+ case MapNotify: -+ { -+ g_application.m_AppActive = true; -+ break; -+ } -+ -+ case UnmapNotify: -+ { -+ g_application.m_AppActive = false; -+ break; -+ } -+ -+ case FocusIn: -+ { -+ if (WinEvents->m_xic) -+ XSetICFocus(WinEvents->m_xic); -+ g_application.m_AppFocused = true; -+ if (serial == xevent.xfocus.serial) -+ break; -+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -+ break; -+ } -+ -+ case FocusOut: -+ { -+ if (WinEvents->m_xic) -+ XUnsetICFocus(WinEvents->m_xic); -+ g_application.m_AppFocused = false; -+ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -+ serial = xevent.xfocus.serial; -+ break; -+ } -+ -+ case Expose: -+ { -+ g_windowManager.MarkDirty(); -+ break; -+ } -+ -+ case ConfigureNotify: -+ { -+ if (xevent.xconfigure.window != WinEvents->m_window) -+ break; -+ -+ WinEvents->m_structureChanged = true; -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_VIDEORESIZE; -+ newEvent.resize.w = xevent.xconfigure.width; -+ newEvent.resize.h = xevent.xconfigure.height; -+ ret |= g_application.OnEvent(newEvent); -+ g_windowManager.MarkDirty(); -+ break; -+ } -+ -+ case ClientMessage: -+ { -+ if (xevent.xclient.data.l[0] == WinEvents->m_wmDeleteMessage) -+ if (!g_application.m_bStop) CApplicationMessenger::Get().Quit(); -+ break; -+ } -+ -+ case KeyPress: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_KEYDOWN; -+ KeySym xkeysym; -+ -+ // fallback if we have no IM -+ if (!WinEvents->m_xic) -+ { -+ static XComposeStatus state; -+ char keybuf[32]; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ if (XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state)) -+ { -+ newEvent.key.keysym.unicode = keybuf[0]; -+ } -+ ret |= ProcessKey(newEvent, 500); -+ break; -+ } -+ -+ Status status; -+ int utf16size; -+ int utf16length; -+ int len; -+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ &xkeysym, &status); -+ if (status == XBufferOverflow) -+ { -+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); -+ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -+ WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ &xkeysym, &status); -+ } -+ switch (status) -+ { -+ case XLookupNone: -+ break; -+ case XLookupChars: -+ case XLookupBoth: -+ { -+ if (len == 0) -+ break; -+ utf16size = len * sizeof(uint16_t); -+ if (utf16size > sizeof(WinEvents->m_utf16buf)) -+ { -+ WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); -+ if (WinEvents->m_utf16buf == NULL) -+ { -+ break; -+ } -+ } -+ utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); -+ if (utf16length < 0) -+ { -+ break; -+ } -+ for (unsigned int i = 0; i < utf16length - 1; i++) -+ { -+ newEvent.key.keysym.sym = XBMCK_UNKNOWN; -+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 500); -+ } -+ if (utf16length > 0) -+ { -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ -+ ret |= ProcessKey(newEvent, 500); -+ } -+ break; -+ } -+ -+ case XLookupKeySym: -+ { -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 500); -+ break; -+ } -+ -+ }// switch status -+ break; -+ } //KeyPress -+ -+ case KeyRelease: -+ { -+ XBMC_Event newEvent; -+ KeySym xkeysym; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_KEYUP; -+ xkeysym = XLookupKeysym(&xevent.xkey, 0); -+ newEvent.key.keysym.scancode = xevent.xkey.keycode; -+ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -+ newEvent.key.state = xevent.xkey.state; -+ newEvent.key.type = xevent.xkey.type; -+ ret |= ProcessKey(newEvent, 0); -+ break; -+ } -+ -+ // lose mouse coverage -+ case LeaveNotify: -+ { -+ g_Mouse.SetActive(false); -+ break; -+ } -+ -+ case MotionNotify: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEMOTION; -+ newEvent.motion.xrel = (int16_t)xevent.xmotion.x_root; -+ newEvent.motion.yrel = (int16_t)xevent.xmotion.y_root; -+ newEvent.motion.x = (int16_t)xevent.xmotion.x; -+ newEvent.motion.y = (int16_t)xevent.xmotion.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ case ButtonPress: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEBUTTONDOWN; -+ newEvent.button.button = (unsigned char)xevent.xbutton.button; -+ newEvent.button.state = XBMC_PRESSED; -+ newEvent.button.x = (int16_t)xevent.xbutton.x; -+ newEvent.button.y = (int16_t)xevent.xbutton.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ case ButtonRelease: -+ { -+ XBMC_Event newEvent; -+ memset(&newEvent, 0, sizeof(newEvent)); -+ newEvent.type = XBMC_MOUSEBUTTONUP; -+ newEvent.button.button = (unsigned char)xevent.xbutton.button; -+ newEvent.button.state = XBMC_RELEASED; -+ newEvent.button.x = (int16_t)xevent.xbutton.x; -+ newEvent.button.y = (int16_t)xevent.xbutton.y; -+ ret |= g_application.OnEvent(newEvent); -+ break; -+ } -+ -+ default: -+ { -+ break; -+ } -+ }// switch event.type -+ }// while -+ -+ ret |= ProcessKeyRepeat(); -+ -+ return ret; -+} -+ -+bool CWinEventsX11::ProcessKey(XBMC_Event &event, int repeatDelay) -+{ -+ if (event.type == XBMC_KEYDOWN) -+ { -+ // check key modifiers -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_LSHIFT: -+ WinEvents->m_keymodState |= XBMCKMOD_LSHIFT; -+ break; -+ case XBMCK_RSHIFT: -+ WinEvents->m_keymodState |= XBMCKMOD_RSHIFT; -+ break; -+ case XBMCK_LCTRL: -+ WinEvents->m_keymodState |= XBMCKMOD_LCTRL; -+ break; -+ case XBMCK_RCTRL: -+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LALT: -+ WinEvents->m_keymodState |= XBMCKMOD_LALT; -+ break; -+ case XBMCK_RALT: -+ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LMETA: -+ WinEvents->m_keymodState |= XBMCKMOD_LMETA; -+ break; -+ case XBMCK_RMETA: -+ WinEvents->m_keymodState |= XBMCKMOD_RMETA; -+ break; -+ case XBMCK_MODE: -+ WinEvents->m_keymodState |= XBMCKMOD_MODE; -+ break; -+ default: -+ break; -+ } -+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -+ memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); -+ WinEvents->m_repeatKeyTimeout.Set(repeatDelay); -+ -+ bool ret = ProcessShortcuts(event); -+ if (ret) -+ return ret; -+ } -+ else if (event.type == XBMC_KEYUP) -+ { -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_LSHIFT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LSHIFT; -+ break; -+ case XBMCK_RSHIFT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RSHIFT; -+ break; -+ case XBMCK_LCTRL: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LCTRL; -+ break; -+ case XBMCK_RCTRL: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LALT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LALT; -+ break; -+ case XBMCK_RALT: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; -+ break; -+ case XBMCK_LMETA: -+ WinEvents->m_keymodState &= ~XBMCKMOD_LMETA; -+ break; -+ case XBMCK_RMETA: -+ WinEvents->m_keymodState &= ~XBMCKMOD_RMETA; -+ break; -+ case XBMCK_MODE: -+ WinEvents->m_keymodState &= ~XBMCKMOD_MODE; -+ break; -+ default: -+ break; -+ } -+ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(event)); -+ } -+ -+ return g_application.OnEvent(event); -+} -+ -+bool CWinEventsX11::ProcessShortcuts(XBMC_Event& event) -+{ -+ if (event.key.keysym.mod & XBMCKMOD_ALT) -+ { -+ switch(event.key.keysym.sym) -+ { -+ case XBMCK_TAB: // ALT+TAB to minimize/hide -+ g_application.Minimize(); -+ return true; -+ -+ default: -+ return false; -+ } -+ } -+ return false; -+} -+ -+bool CWinEventsX11::ProcessKeyRepeat() -+{ -+ if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) -+ { -+ if (WinEvents->m_repeatKeyTimeout.IsTimePast()) -+ { -+ return ProcessKey(WinEvents->m_lastKey, 10); -+ } -+ } -+ return false; -+} -+ -+int CWinEventsX11::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) -+{ -+ // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. -+ uint16_t *p = utf16; -+ uint16_t const *const maxPtr = utf16 + utf16MaxLength; -+ -+ // end_of_input points to the last byte of input as opposed to the next to the last byte. -+ char const *const endOfInput = utf8 + utf8Length - 1; -+ -+ while (utf8 <= endOfInput) -+ { -+ unsigned char const c = *utf8; -+ if (p >= maxPtr) -+ { -+ //No more output space. -+ return -1; -+ } -+ if (c < 0x80) -+ { -+ //One byte ASCII. -+ *p++ = c; -+ utf8 += 1; -+ } -+ else if (c < 0xC0) -+ { -+ // Follower byte without preceding leader bytes. -+ return -1; -+ } -+ // 11 bits -+ else if (c < 0xE0) -+ { -+ // Two byte sequence. We need one follower byte. -+ if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) -+ { -+ return -1; -+ } -+ *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); -+ utf8 += 2; -+ } -+ // 16 bis -+ else if (c < 0xF0) -+ { -+ // Three byte sequence. We need two follower byte. -+ if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) -+ { -+ return -1; -+ } -+ *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); -+ utf8 += 3; -+ } -+ // 21 bits -+ else if (c < 0xF8) -+ { -+ int plane; -+ // Four byte sequence. We need three follower bytes. -+ if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || -+ ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) -+ { -+ return -1; -+ } -+ uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + -+ ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); -+ utf8 += 4; -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ } -+ // 26 bits -+ else if (c < 0xFC) -+ { -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ utf8 += 5; -+ } -+ // 31 bit -+ else -+ { -+ CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -+ utf8 += 6; -+ } -+ } -+ return p - utf16; -+} -+ -+XBMCKey CWinEventsX11::LookupXbmcKeySym(KeySym keysym) -+{ -+ // try direct mapping first -+ std::map::iterator it; -+ it = WinEvents->m_symLookupTable.find(keysym); -+ if (it != WinEvents->m_symLookupTable.end()) -+ { -+ return (XBMCKey)(it->second); -+ } -+ -+ // try ascii mappings -+ if (keysym>>8 == 0x00) -+ return (XBMCKey)(keysym & 0xFF); -+ -+ return (XBMCKey)keysym; -+} -+#endif -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -new file mode 100644 -index 0000000..e9b7553 ---- /dev/null -+++ b/xbmc/windowing/WinEventsX11.h -@@ -0,0 +1,57 @@ -+/* -+* Copyright (C) 2005-2012 Team XBMC -+* http://www.xbmc.org -+* -+* This Program is free software; you can redistribute it and/or modify -+* it under the terms of the GNU General Public License as published by -+* the Free Software Foundation; either version 2, or (at your option) -+* any later version. -+* -+* This Program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+* GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License -+* along with XBMC; see the file COPYING. If not, write to -+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -+* http://www.gnu.org/copyleft/gpl.html -+* -+*/ -+#pragma once -+ -+#include "WinEvents.h" -+#include -+#include "threads/SystemClock.h" -+#include -+ -+class CWinEventsX11 : public CWinEventsBase -+{ -+public: -+ CWinEventsX11(); -+ virtual ~CWinEventsX11(); -+ static bool Init(Display *dpy, Window win); -+ static void Quit(); -+ static bool HasStructureChanged(); -+ static bool MessagePump(); -+ -+protected: -+ static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); -+ static XBMCKey LookupXbmcKeySym(KeySym keysym); -+ static bool ProcessKey(XBMC_Event &event, int repeatDelay); -+ static bool ProcessKeyRepeat(); -+ static bool ProcessShortcuts(XBMC_Event& event); -+ static CWinEventsX11 *WinEvents; -+ Display *m_display; -+ Window m_window; -+ Atom m_wmDeleteMessage; -+ char *m_keybuf; -+ uint16_t *m_utf16buf; -+ XIM m_xim; -+ XIC m_xic; -+ XBMC_Event m_lastKey; -+ XbmcThreads::EndTime m_repeatKeyTimeout; -+ std::map m_symLookupTable; -+ int m_keymodState; -+ bool m_structureChanged; -+}; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index a839709..76ef462 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -22,7 +22,6 @@ - - #ifdef HAS_GLX - --#include - #include "WinSystemX11.h" - #include "settings/Settings.h" - #include "guilib/Texture.h" -@@ -31,27 +30,30 @@ - #include "XRandR.h" - #include - #include "threads/SingleLock.h" --#include - #include "cores/VideoRenderers/RenderManager.h" - #include "utils/TimeUtils.h" -+#include "settings/GUISettings.h" - - #if defined(HAS_XRANDR) - #include - #endif - -+#include "../WinEvents.h" -+#include "input/MouseStat.h" -+ - using namespace std; - - CWinSystemX11::CWinSystemX11() : CWinSystemBase() - { - m_eWindowSystem = WINDOW_SYSTEM_X11; - m_glContext = NULL; -- m_SDLSurface = NULL; - m_dpy = NULL; - m_glWindow = 0; -- m_wmWindow = 0; - m_bWasFullScreenBeforeMinimize = false; - m_minimized = false; -+ m_bIgnoreNextFocusMessage = false; - m_dpyLostTime = 0; -+ m_invisibleCursor = 0; - - XSetErrorHandler(XErrorHandler); - } -@@ -64,18 +66,6 @@ bool CWinSystemX11::InitWindowSystem() - { - if ((m_dpy = XOpenDisplay(NULL))) - { -- -- SDL_EnableUNICODE(1); -- // set repeat to 10ms to ensure repeat time < frame time -- // so that hold times can be reliably detected -- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10); -- -- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); -- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); -- - return CWinSystemBase::InitWindowSystem(); - } - else -@@ -113,45 +103,37 @@ bool CWinSystemX11::DestroyWindowSystem() - - bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) - { -- RESOLUTION_INFO& desktop = g_settings.m_ResInfo[RES_DESKTOP]; -- -- if (fullScreen && -- (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || -- res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) -- { -- //on the first call to SDL_SetVideoMode, SDL stores the current displaymode -- //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode -- //before the first call to SDL_SetVideoMode, SDL changes the displaymode back -- //to the wrong mode on exit -- -- CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); -- if (!SetFullScreen(true, desktop, false)) -- return false; -- } -- - if(!SetFullScreen(fullScreen, res, false)) - return false; - -- CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon.png"); -- -- if (iconTexture) -- SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); -- SDL_WM_SetCaption("XBMC Media Center", NULL); -- delete iconTexture; -- -- // register XRandR Events --#if defined(HAS_XRANDR) -- int iReturn; -- XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn); -- XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask); --#endif -- - m_bWindowCreated = true; - return true; - } - - bool CWinSystemX11::DestroyWindow() - { -+ if (!m_glWindow) -+ return true; -+ -+ if (m_glContext) -+ glXMakeCurrent(m_dpy, None, NULL); -+ -+ if (m_invisibleCursor) -+ { -+ XUndefineCursor(m_dpy, m_glWindow); -+ XFreeCursor(m_dpy, m_invisibleCursor); -+ m_invisibleCursor = 0; -+ } -+ -+ CWinEvents::Quit(); -+ -+ XUnmapWindow(m_dpy, m_glWindow); -+ XSync(m_dpy,TRUE); -+ XUngrabKeyboard(m_dpy, CurrentTime); -+ XUngrabPointer(m_dpy, CurrentTime); -+ XDestroyWindow(m_dpy, m_glWindow); -+ m_glWindow = 0; -+ - return true; - } - -@@ -161,65 +143,105 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - && m_nHeight == newHeight) - return true; - -+ if (!SetWindow(newWidth, newHeight, false)) -+ { -+ return false; -+ } -+ -+ RefreshGlxContext(); - m_nWidth = newWidth; - m_nHeight = newHeight; -+ m_bFullScreen = false; - -- int options = SDL_OPENGL; -- if (m_bFullScreen) -- options |= SDL_FULLSCREEN; -- else -- options |= SDL_RESIZABLE; -+ return false; -+} -+ -+void CWinSystemX11::RefreshWindow() -+{ -+ g_xrandr.Query(true); -+ XOutput out = g_xrandr.GetCurrentOutput(); -+ XMode mode = g_xrandr.GetCurrentMode(out.name); - -- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) -+ // only overwrite desktop resolution, if we are not in fullscreen mode -+ if (!g_graphicsContext.IsFullScreenVideo()) - { -- RefreshGlxContext(); -- return true; -+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; -+ g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; - } - -- return false; -+ RESOLUTION_INFO res; -+ unsigned int i; -+ bool found(false); -+ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) -+ { -+ if (g_settings.m_ResInfo[i].strId == mode.id) -+ { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -+ return; -+ } -+ -+ if (g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -+ else -+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); - } - - bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { -- m_nWidth = res.iWidth; -- m_nHeight = res.iHeight; -- m_bFullScreen = fullScreen; - - #if defined(HAS_XRANDR) - XOutput out; - XMode mode; -- out.name = res.strOutput; -- mode.w = res.iWidth; -- mode.h = res.iHeight; -- mode.hz = res.fRefreshRate; -- mode.id = res.strId; -+ -+ if (fullScreen) -+ { -+ out.name = res.strOutput; -+ mode.w = res.iWidth; -+ mode.h = res.iHeight; -+ mode.hz = res.fRefreshRate; -+ mode.id = res.strId; -+ } -+ else -+ { -+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ } - -- if(m_bFullScreen) -+ XOutput currout = g_xrandr.GetCurrentOutput(); -+ XMode currmode = g_xrandr.GetCurrentMode(currout.name); -+ -+ // only call xrandr if mode changes -+ if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || -+ currmode.hz != mode.hz || currmode.id != mode.id) - { -+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); - OnLostDevice(); - g_xrandr.SetMode(out, mode); - } -- else -- g_xrandr.RestoreState(); - #endif - -- int options = SDL_OPENGL; -- if (m_bFullScreen) -- options |= SDL_FULLSCREEN; -- else -- options |= SDL_RESIZABLE; -- -- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) -- { -- if ((m_SDLSurface->flags & SDL_OPENGL) != SDL_OPENGL) -- CLog::Log(LOGERROR, "CWinSystemX11::SetFullScreen SDL_OPENGL not set, SDL_GetError:%s", SDL_GetError()); -+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) -+ return false; - -- RefreshGlxContext(); -+ RefreshGlxContext(); - -- return true; -- } -+ m_nWidth = res.iWidth; -+ m_nHeight = res.iHeight; -+ m_bFullScreen = fullScreen; - -- return false; -+ return true; - } - - void CWinSystemX11::UpdateResolutions() -@@ -321,17 +343,10 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - bool CWinSystemX11::RefreshGlxContext() - { - bool retVal = false; -- SDL_SysWMinfo info; -- SDL_VERSION(&info.version); -- if (SDL_GetWMInfo(&info) <= 0) -- { -- CLog::Log(LOGERROR, "Failed to get window manager info from SDL"); -- return false; -- } - -- if(m_glWindow == info.info.x11.window && m_glContext) -+ if (m_glContext) - { -- CLog::Log(LOGERROR, "GLX: Same window as before, refreshing context"); -+ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); - return true; -@@ -343,8 +358,6 @@ bool CWinSystemX11::RefreshGlxContext() - int availableVisuals = 0; - vMask.screen = DefaultScreen(m_dpy); - XWindowAttributes winAttr; -- m_glWindow = info.info.x11.window; -- m_wmWindow = info.info.x11.wmwindow; - - /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() - or XGetVisualInfo() fail. That shouldn't happen unless something is -@@ -415,7 +428,10 @@ bool CWinSystemX11::RefreshGlxContext() - - void CWinSystemX11::ShowOSMouse(bool show) - { -- SDL_ShowCursor(show ? 1 : 0); -+ if (show) -+ XUndefineCursor(m_dpy,m_glWindow); -+ else if (m_invisibleCursor) -+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); - } - - void CWinSystemX11::ResetOSScreensaver() -@@ -429,8 +445,6 @@ void CWinSystemX11::ResetOSScreensaver() - { - m_screensaverReset.StartZero(); - XResetScreenSaver(m_dpy); -- //need to flush the output buffer, since we don't check for events on m_dpy -- XFlush(m_dpy); - } - } - else -@@ -446,13 +460,27 @@ void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - - m_minimized = !bActivated; - } -+ -+void CWinSystemX11::NotifyAppFocusChange(bool bGaining) -+{ -+ if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && -+ !g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.ToggleFullScreenRoot(); -+ if (!bGaining) -+ m_bIgnoreNextFocusMessage = false; -+} -+ - bool CWinSystemX11::Minimize() - { - m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); - if (m_bWasFullScreenBeforeMinimize) -+ { -+ m_bIgnoreNextFocusMessage = true; - g_graphicsContext.ToggleFullScreenRoot(); -+ } -+ -+ XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); - -- SDL_WM_IconifyWindow(); - m_minimized = true; - return true; - } -@@ -462,13 +490,13 @@ bool CWinSystemX11::Restore() - } - bool CWinSystemX11::Hide() - { -- XUnmapWindow(m_dpy, m_wmWindow); -+ XUnmapWindow(m_dpy, m_glWindow); - XSync(m_dpy, False); - return true; - } - bool CWinSystemX11::Show(bool raise) - { -- XMapWindow(m_dpy, m_wmWindow); -+ XMapWindow(m_dpy, m_glWindow); - XSync(m_dpy, False); - m_minimized = false; - return true; -@@ -500,6 +528,7 @@ void CWinSystemX11::CheckDisplayEvents() - if (bGotEvent || bTimeout) - { - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -+ RefreshWindow(); - - CSingleLock lock(m_resourceSection); - -@@ -558,4 +587,151 @@ bool CWinSystemX11::EnableFrameLimiter() - return m_minimized; - } - -+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) -+{ -+ bool changeWindow = false; -+ bool changeSize = false; -+ bool mouseActive = false; -+ float mouseX, mouseY; -+ -+ if (m_glWindow && (m_bFullScreen != fullscreen)) -+ { -+ mouseActive = g_Mouse.IsActive(); -+ if (mouseActive) -+ { -+ Window root_return, child_return; -+ int root_x_return, root_y_return; -+ int win_x_return, win_y_return; -+ unsigned int mask_return; -+ bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, -+ &root_x_return, &root_y_return, -+ &win_x_return, &win_y_return, -+ &mask_return); -+ if (isInWin) -+ { -+ mouseX = (float)win_x_return/m_nWidth; -+ mouseY = (float)win_y_return/m_nHeight; -+ g_Mouse.SetActive(false); -+ } -+ else -+ mouseActive = false; -+ } -+ DestroyWindow(); -+ } -+ -+ // create main window -+ if (!m_glWindow) -+ { -+ GLint att[] = -+ { -+ GLX_RGBA, -+ GLX_RED_SIZE, 8, -+ GLX_GREEN_SIZE, 8, -+ GLX_BLUE_SIZE, 8, -+ GLX_ALPHA_SIZE, 8, -+ GLX_DEPTH_SIZE, 24, -+ GLX_DOUBLEBUFFER, -+ None -+ }; -+ Colormap cmap; -+ XSetWindowAttributes swa; -+ XVisualInfo *vi; -+ -+ vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); -+ cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); -+ -+ int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -+ swa.override_redirect = fullscreen ? True : False; -+ swa.border_pixel = fullscreen ? 0 : 5; -+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; -+ swa.colormap = cmap; -+ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; -+ swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | -+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | -+ PropertyChangeMask | StructureNotifyMask | KeymapStateMask | -+ EnterWindowMask | LeaveWindowMask | ExposureMask; -+ unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; -+ -+ m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -+ 0, 0, width, height, 0, vi->depth, -+ InputOutput, vi->visual, -+ mask, &swa); -+ -+ // define invisible cursor -+ Pixmap bitmapNoData; -+ XColor black; -+ static char noData[] = { 0,0,0,0,0,0,0,0 }; -+ black.red = black.green = black.blue = 0; -+ -+ bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); -+ m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, -+ &black, &black, 0, 0); -+ XFreePixmap(m_dpy, bitmapNoData); -+ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); -+ -+ //init X11 events -+ CWinEvents::Init(m_dpy, m_glWindow); -+ -+ changeWindow = true; -+ changeSize = true; -+ } -+ -+ if (!CWinEvents::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) -+ { -+ changeSize = true; -+ } -+ -+ if (changeSize || changeWindow) -+ { -+ XResizeWindow(m_dpy, m_glWindow, width, height); -+ } -+ -+ if (changeWindow) -+ { -+ if (!fullscreen) -+ { -+ XWMHints wm_hints; -+ XClassHint class_hints; -+ XTextProperty windowName, iconName; -+ std::string titleString = "XBMC Media Center"; -+ char *title = (char*)titleString.c_str(); -+ -+ XStringListToTextProperty(&title, 1, &windowName); -+ XStringListToTextProperty(&title, 1, &iconName); -+ wm_hints.initial_state = NormalState; -+ wm_hints.input = True; -+ wm_hints.icon_pixmap = None; -+ wm_hints.flags = StateHint | IconPixmapHint | InputHint; -+ -+ XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -+ NULL, 0, NULL, &wm_hints, -+ NULL); -+ -+ // register interest in the delete window message -+ Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); -+ XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); -+ } -+ XMapRaised(m_dpy, m_glWindow); -+ XSync(m_dpy,TRUE); -+ -+ if (changeWindow && mouseActive) -+ { -+ XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); -+ } -+ -+ if (fullscreen) -+ { -+ int result = -1; -+ while (result != GrabSuccess) -+ { -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); -+ XbmcThreads::ThreadSleep(100); -+ } -+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ -+ } -+ } -+ return true; -+} -+ - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 2dd8a9f..9616d17 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -52,6 +52,7 @@ class CWinSystemX11 : public CWinSystemBase - virtual bool EnableFrameLimiter(); - - virtual void NotifyAppActiveChange(bool bActivated); -+ virtual void NotifyAppFocusChange(bool bGaining); - - virtual bool Minimize(); - virtual bool Restore() ; -@@ -64,19 +65,21 @@ class CWinSystemX11 : public CWinSystemBase - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -+ void RefreshWindow(); - - protected: - bool RefreshGlxContext(); - void CheckDisplayEvents(); - void OnLostDevice(); -+ bool SetWindow(int width, int height, bool fullscreen); - -- SDL_Surface* m_SDLSurface; -+ Window m_glWindow; - GLXContext m_glContext; -- GLXWindow m_glWindow; -- Window m_wmWindow; - Display* m_dpy; -+ Cursor m_invisibleCursor; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; -+ bool m_bIgnoreNextFocusMessage; - int m_RREventBase; - CCriticalSection m_resourceSection; - std::vector m_resources; --- -1.7.10 - - -From 5a5787c6f51a9d92f69e95dea42175f3837777cb Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 36/88] X11: Add xbmc icon - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 126 ++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 2 + - 2 files changed, 127 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 76ef462..c854598 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -134,6 +134,9 @@ bool CWinSystemX11::DestroyWindow() - XDestroyWindow(m_dpy, m_glWindow); - m_glWindow = 0; - -+ if (m_icon) -+ XFreePixmap(m_dpy, m_icon); -+ - return true; - } - -@@ -688,8 +691,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - - if (changeWindow) - { -+ m_icon = None; - if (!fullscreen) - { -+ CreateIconPixmap(); - XWMHints wm_hints; - XClassHint class_hints; - XTextProperty windowName, iconName; -@@ -700,7 +705,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - XStringListToTextProperty(&title, 1, &iconName); - wm_hints.initial_state = NormalState; - wm_hints.input = True; -- wm_hints.icon_pixmap = None; -+ wm_hints.icon_pixmap = m_icon; - wm_hints.flags = StateHint | IconPixmapHint | InputHint; - - XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -@@ -734,4 +739,123 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - return true; - } - -+bool CWinSystemX11::CreateIconPixmap() -+{ -+ int depth; -+ XImage *img = NULL; -+ Visual *vis; -+ XWindowAttributes wndattribs; -+ XVisualInfo visInfo; -+ double rRatio; -+ double gRatio; -+ double bRatio; -+ int outIndex = 0; -+ int i,j; -+ int numBufBytes; -+ unsigned char *buf; -+ uint32_t *newBuf = 0; -+ size_t numNewBufBytes; -+ -+ // Get visual Info -+ XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs); -+ visInfo.visualid = wndattribs.visual->visualid; -+ int nvisuals = 0; -+ XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals); -+ if (nvisuals != 1) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual"); -+ return false; -+ } -+ visInfo = visuals[0]; -+ XFree(visuals); -+ -+ depth = visInfo.depth; -+ vis = visInfo.visual; -+ -+ if (depth < 15) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth"); -+ return false; -+ } -+ -+ rRatio = vis->red_mask / 255.0; -+ gRatio = vis->green_mask / 255.0; -+ bRatio = vis->blue_mask / 255.0; -+ -+ CTexture iconTexture; -+ iconTexture.LoadFromFile("special://xbmc/media/icon.png"); -+ buf = iconTexture.GetPixels(); -+ -+ numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; -+ -+ if (depth>=24) -+ numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ else -+ numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ -+ newBuf = (uint32_t*)malloc(numNewBufBytes); -+ if (!newBuf) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed"); -+ return false; -+ } -+ -+ for (i=0; ired_mask; -+ g &= vis->green_mask; -+ b &= vis->blue_mask; -+ newBuf[outIndex] = r | g | b; -+ ++outIndex; -+ } -+ } -+ img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, -+ iconTexture.GetWidth(), iconTexture.GetHeight(), -+ (depth>=24)?32:16, 0); -+ if (!img) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image"); -+ free(newBuf); -+ return false; -+ } -+ if (!XInitImage(img)) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed"); -+ XDestroyImage(img); -+ return false; -+ } -+ -+ // set byte order -+ union -+ { -+ char c[sizeof(short)]; -+ short s; -+ } order; -+ order.s = 1; -+ if ((1 == order.c[0])) -+ { -+ img->byte_order = LSBFirst; -+ } -+ else -+ { -+ img->byte_order = MSBFirst; -+ } -+ -+ // create icon pixmap from image -+ m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth); -+ GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL); -+ XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height); -+ XFreeGC(m_dpy, gc); -+ XDestroyImage(img); // this also frees newBuf -+ -+ return true; -+} -+ - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 9616d17..debf714 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -77,6 +77,7 @@ class CWinSystemX11 : public CWinSystemBase - GLXContext m_glContext; - Display* m_dpy; - Cursor m_invisibleCursor; -+ Pixmap m_icon; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -@@ -88,6 +89,7 @@ class CWinSystemX11 : public CWinSystemBase - private: - bool IsSuitableVisual(XVisualInfo *vInfo); - static int XErrorHandler(Display* dpy, XErrorEvent* error); -+ bool CreateIconPixmap(); - - CStopWatch m_screensaverReset; - }; --- -1.7.10 - - -From e6ae1b597d479cb9d9ae2dfc8cf43cceac4a82f7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 37/88] X11: add SDL joystick until we have a better solution - ---- - xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 24477ae..2ec86a8 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -35,6 +35,10 @@ - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -+#ifdef HAS_SDL_JOYSTICK -+#include "input/SDLJoystick.h" -+#endif -+ - CWinEventsX11* CWinEventsX11::WinEvents = 0; - - static uint32_t SymMappingsX11[][2] = -@@ -547,6 +551,28 @@ bool CWinEventsX11::MessagePump() - - ret |= ProcessKeyRepeat(); - -+#ifdef HAS_SDL_JOYSTICK -+ SDL_Event event; -+ while (SDL_PollEvent(&event)) -+ { -+ switch(event.type) -+ { -+ case SDL_JOYBUTTONUP: -+ case SDL_JOYBUTTONDOWN: -+ case SDL_JOYAXISMOTION: -+ case SDL_JOYBALLMOTION: -+ case SDL_JOYHATMOTION: -+ g_Joystick.Update(event); -+ ret = true; -+ break; -+ -+ default: -+ break; -+ } -+ memset(&event, 0, sizeof(SDL_Event)); -+ } -+#endif -+ - return ret; - } - --- -1.7.10 - - -From 22a59cd9df66e37394ac61b3d03d3ab6ac2f824f Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 38/88] X11: factor out code handling device reset - notification - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 22 ++++++++++++++-------- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 15 insertions(+), 8 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c854598..70557d0 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -530,14 +530,7 @@ void CWinSystemX11::CheckDisplayEvents() - - if (bGotEvent || bTimeout) - { -- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -- RefreshWindow(); -- -- CSingleLock lock(m_resourceSection); -- -- // tell any shared resources -- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -- (*i)->OnResetDevice(); -+ NotifyXRREvent(); - - // reset fail safe timer - m_dpyLostTime = 0; -@@ -545,6 +538,19 @@ void CWinSystemX11::CheckDisplayEvents() - #endif - } - -+void CWinSystemX11::NotifyXRREvent() -+{ -+ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -+ RefreshWindow(); -+ -+ CSingleLock lock(m_resourceSection); -+ -+ // tell any shared resources -+ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -+ (*i)->OnResetDevice(); -+ -+} -+ - void CWinSystemX11::OnLostDevice() - { - CLog::Log(LOGDEBUG, "%s - notify display change event", __FUNCTION__); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index debf714..8c28e3f 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -66,6 +66,7 @@ class CWinSystemX11 : public CWinSystemBase - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } - void RefreshWindow(); -+ void NotifyXRREvent(); - - protected: - bool RefreshGlxContext(); --- -1.7.10 - - -From 6c8f71e86c88314ee94673ad58407a8122995049 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 39/88] X11: move xrandr events to WinEventsX11 - ---- - xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++ - xbmc/windowing/WinEventsX11.h | 5 +++++ - xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++- - 3 files changed, 52 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 2ec86a8..5946a33 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -35,6 +35,10 @@ - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -+#if defined(HAS_XRANDR) -+#include -+#endif -+ - #ifdef HAS_SDL_JOYSTICK - #include "input/SDLJoystick.h" - #endif -@@ -203,6 +207,7 @@ bool CWinEventsX11::Init(Display *dpy, Window win) - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -+ WinEvents->m_xrrEventPending = false; - memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - - // open input method -@@ -266,6 +271,13 @@ bool CWinEventsX11::Init(Display *dpy, Window win) - WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; - } - -+ // register for xrandr events -+#if defined(HAS_XRANDR) -+ int iReturn; -+ XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); -+ XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); -+#endif -+ - return true; - } - -@@ -288,6 +300,15 @@ bool CWinEventsX11::HasStructureChanged() - return ret; - } - -+void CWinEventsX11::SetXRRFailSafeTimer(int millis) -+{ -+ if (!WinEvents) -+ return; -+ -+ WinEvents->m_xrrFailSafeTimer.Set(millis); -+ WinEvents->m_xrrEventPending = true; -+} -+ - bool CWinEventsX11::MessagePump() - { - if (!WinEvents) -@@ -547,10 +568,31 @@ bool CWinEventsX11::MessagePump() - break; - } - }// switch event.type -+ -+#if defined(HAS_XRANDR) -+ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) -+ { -+ XRRUpdateConfiguration(&xevent); -+ if (xevent.xgeneric.serial != serial) -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ serial = xevent.xgeneric.serial; -+ } -+#endif -+ - }// while - - ret |= ProcessKeyRepeat(); - -+#if defined(HAS_XRANDR) -+ if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) -+ { -+ CLog::Log(LOGERROR,"CWinEventsX11::MessagePump - missed XRR Events"); -+ g_Windowing.NotifyXRREvent(); -+ WinEvents->m_xrrEventPending = false; -+ } -+#endif -+ - #ifdef HAS_SDL_JOYSTICK - SDL_Event event; - while (SDL_PollEvent(&event)) -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index e9b7553..6100933 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -33,6 +33,8 @@ class CWinEventsX11 : public CWinEventsBase - static bool Init(Display *dpy, Window win); - static void Quit(); - static bool HasStructureChanged(); -+ static void PendingResize(int width, int height); -+ static void SetXRRFailSafeTimer(int millis); - static bool MessagePump(); - - protected: -@@ -54,4 +56,7 @@ class CWinEventsX11 : public CWinEventsBase - std::map m_symLookupTable; - int m_keymodState; - bool m_structureChanged; -+ int m_RREventBase; -+ XbmcThreads::EndTime m_xrrFailSafeTimer; -+ bool m_xrrEventPending; - }; -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 70557d0..1cce843 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -507,7 +507,7 @@ bool CWinSystemX11::Show(bool raise) - - void CWinSystemX11::CheckDisplayEvents() - { --#if defined(HAS_XRANDR) -+#if defined(HAS_XRANDR) && defined(HAS_SDL_VIDEO_X11) - bool bGotEvent(false); - bool bTimeout(false); - XEvent Event; -@@ -563,8 +563,12 @@ void CWinSystemX11::OnLostDevice() - (*i)->OnLostDevice(); - } - -+#if defined(HAS_SDL_VIDEO_X11) - // fail safe timer - m_dpyLostTime = CurrentHostCounter(); -+#else -+ CWinEvents::SetXRRFailSafeTimer(3000); -+#endif - } - - void CWinSystemX11::Register(IDispResource *resource) --- -1.7.10 - - -From 9d24be16a3f9cc78ca26645ac2c7808e6e6b1e3e Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 40/88] xrandr: remove method RestoreState - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++-- - xbmc/windowing/X11/XRandR.cpp | 19 ------------------- - xbmc/windowing/X11/XRandR.h | 1 - - 3 files changed, 11 insertions(+), 22 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 1cce843..e13ffa4 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -77,9 +77,18 @@ bool CWinSystemX11::InitWindowSystem() - bool CWinSystemX11::DestroyWindowSystem() - { - #if defined(HAS_XRANDR) -- //restore videomode on exit -+ //restore desktop resolution on exit - if (m_bFullScreen) -- g_xrandr.RestoreState(); -+ { -+ XOutput out; -+ XMode mode; -+ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; -+ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; -+ g_xrandr.SetMode(out, mode); -+ } - #endif - - if (m_dpy) -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index d8e9161..59755a6 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -139,25 +139,6 @@ void CXRandR::SaveState() - Query(true); - } - --void CXRandR::RestoreState() --{ -- vector::iterator outiter; -- for (outiter=m_current.begin() ; outiter!=m_current.end() ; outiter++) -- { -- vector modes = (*outiter).modes; -- vector::iterator modeiter; -- for (modeiter=modes.begin() ; modeiter!=modes.end() ; modeiter++) -- { -- XMode mode = *modeiter; -- if (mode.isCurrent) -- { -- SetMode(*outiter, mode); -- return; -- } -- } -- } --} -- - bool CXRandR::SetMode(XOutput output, XMode mode) - { - if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 2a269d0..5b64633 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -99,7 +99,6 @@ class CXRandR - bool SetMode(XOutput output, XMode mode); - void LoadCustomModeLinesToAllOutputs(void); - void SaveState(); -- void RestoreState(); - //bool Has1080i(); - //bool Has1080p(); - //bool Has720p(); --- -1.7.10 - - -From b74182e365180b8f6bb413ad49ef17846cb6cf66 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 41/88] xrandr: observe orientation - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 61 +++++++++++++++++++++++++++++++++-- - xbmc/windowing/X11/WinSystemX11.h | 2 ++ - xbmc/windowing/X11/XRandR.cpp | 7 ++++ - xbmc/windowing/X11/XRandR.h | 1 + - 4 files changed, 68 insertions(+), 3 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index e13ffa4..6b0aa92 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -170,15 +170,24 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - - void CWinSystemX11::RefreshWindow() - { -- g_xrandr.Query(true); -+ if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } - XOutput out = g_xrandr.GetCurrentOutput(); - XMode mode = g_xrandr.GetCurrentMode(out.name); - -+ RotateResolutions(); -+ - // only overwrite desktop resolution, if we are not in fullscreen mode - if (!g_graphicsContext.IsFullScreenVideo()) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ if (!out.isRotated) -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ else -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.h, mode.w, mode.hz); - g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; - g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; - } -@@ -234,6 +243,14 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - XOutput currout = g_xrandr.GetCurrentOutput(); - XMode currmode = g_xrandr.GetCurrentMode(currout.name); - -+ // flip h/w when rotated -+ if (m_bIsRotated) -+ { -+ int w = mode.w; -+ mode.w = mode.h; -+ mode.h = w; -+ } -+ - // only call xrandr if mode changes - if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || - currmode.hz != mode.hz || currmode.id != mode.id) -@@ -266,7 +283,11 @@ void CWinSystemX11::UpdateResolutions() - { - XOutput out = g_xrandr.GetCurrentOutput(); - XMode mode = g_xrandr.GetCurrentMode(out.name); -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ m_bIsRotated = out.isRotated; -+ if (!m_bIsRotated) -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ else -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.h, mode.w, mode.hz); - g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; - g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; - } -@@ -305,6 +326,16 @@ void CWinSystemX11::UpdateResolutions() - res.iHeight = mode.h; - res.iScreenWidth = mode.w; - res.iScreenHeight = mode.h; -+ if (!m_bIsRotated) -+ { -+ res.iWidth = mode.w; -+ res.iHeight = mode.h; -+ } -+ else -+ { -+ res.iWidth = mode.h; -+ res.iHeight = mode.w; -+ } - if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) - res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); - else -@@ -332,6 +363,30 @@ void CWinSystemX11::UpdateResolutions() - - } - -+void CWinSystemX11::RotateResolutions() -+{ -+#if defined(HAS_XRANDR) -+ XOutput out = g_xrandr.GetCurrentOutput(); -+ if (out.isRotated == m_bIsRotated) -+ return; -+ -+ for (unsigned int i = 0; i < g_settings.m_ResInfo.size(); ++i) -+ { -+ int width = g_settings.m_ResInfo[i].iWidth; -+ g_settings.m_ResInfo[i].iWidth = g_settings.m_ResInfo[i].iHeight; -+ g_settings.m_ResInfo[i].iHeight = width; -+ } -+ // update desktop resolution -+// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; -+// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; -+// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; -+// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); -+ -+ m_bIsRotated = out.isRotated; -+ -+#endif -+} -+ - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - { - int value; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 8c28e3f..93cf5db 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -73,12 +73,14 @@ class CWinSystemX11 : public CWinSystemBase - void CheckDisplayEvents(); - void OnLostDevice(); - bool SetWindow(int width, int height, bool fullscreen); -+ void RotateResolutions(); - - Window m_glWindow; - GLXContext m_glContext; - Display* m_dpy; - Cursor m_invisibleCursor; - Pixmap m_icon; -+ bool m_bIsRotated; - bool m_bWasFullScreenBeforeMinimize; - bool m_minimized; - bool m_bIgnoreNextFocusMessage; -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 59755a6..45aeb71 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -98,6 +98,13 @@ bool CXRandR::Query(bool force) - xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); - xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); - xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); -+ if (output->Attribute("rotation") != NULL -+ && (strcasecmp(output->Attribute("rotation"), "left") == 0 || strcasecmp(output->Attribute("rotation"), "right") == 0)) -+ { -+ xoutput.isRotated = true; -+ } -+ else -+ xoutput.isRotated = false; - - if (!xoutput.isConnected) - continue; -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 5b64633..618bd68 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -86,6 +86,7 @@ class XOutput - int wmm; - int hmm; - std::vector modes; -+ bool isRotated; - }; - - class CXRandR --- -1.7.10 - - -From 80ebbe1851f21ed959f6b30eac6374d3bbe9258e Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 42/88] xrandr: allow getting info for multiple screen's - -Refactored by: Joakim Plate ---- - xbmc/windowing/X11/XRandR.cpp | 65 ++++++++++++++++++++++++++++++++--------- - xbmc/windowing/X11/XRandR.h | 8 +++-- - 2 files changed, 57 insertions(+), 16 deletions(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 45aeb71..cc933b9 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -39,6 +39,7 @@ - CXRandR::CXRandR(bool query) - { - m_bInit = false; -+ m_numScreens = 1; - if (query) - Query(); - } -@@ -55,11 +56,21 @@ bool CXRandR::Query(bool force) - return false; - - m_outputs.clear(); -- m_current.clear(); -+ // query all screens -+ for(unsigned int screennum=0; screennumValue(), "screen") != 0) -+ if (strcasecmp(pRootElement->Value(), "screen") != screennum) - { - // TODO ERROR - return false; -@@ -92,6 +103,7 @@ bool CXRandR::Query(bool force) - xoutput.name.TrimLeft(" \n\r\t"); - xoutput.name.TrimRight(" \n\r\t"); - xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0); -+ xoutput.screen = screennum; - xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0); - xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); - xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); -@@ -123,7 +135,6 @@ bool CXRandR::Query(bool force) - xoutput.modes.push_back(xmode); - if (xmode.isCurrent) - { -- m_current.push_back(xoutput); - hascurrent = true; - } - } -@@ -247,17 +258,6 @@ bool CXRandR::SetMode(XOutput output, XMode mode) - return true; - } - --XOutput CXRandR::GetCurrentOutput() --{ -- Query(); -- for (unsigned int j = 0; j < m_outputs.size(); j++) -- { -- if(m_outputs[j].isConnected) -- return m_outputs[j]; -- } -- XOutput empty; -- return empty; --} - XMode CXRandR::GetCurrentMode(CStdString outputName) - { - Query(); -@@ -331,6 +331,43 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void) - } - } - -+void CXRandR::SetNumScreens(unsigned int num) -+{ -+ m_numScreens = num; -+ m_bInit = false; -+} -+ -+bool CXRandR::IsOutputConnected(CStdString name) -+{ -+ bool result = false; -+ Query(); -+ -+ for (unsigned int i = 0; i < m_outputs.size(); ++i) -+ { -+ if (m_outputs[i].name == name) -+ { -+ result = true; -+ break; -+ } -+ } -+ return result; -+} -+ -+XOutput* CXRandR::GetOutput(CStdString outputName) -+{ -+ XOutput *result = 0; -+ Query(); -+ for (unsigned int i = 0; i < m_outputs.size(); ++i) -+ { -+ if (m_outputs[i].name == outputName) -+ { -+ result = &m_outputs[i]; -+ break; -+ } -+ } -+ return result; -+} -+ - CXRandR g_xrandr; - - #endif // HAS_XRANDR -diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h -index 618bd68..0824af5 100644 ---- a/xbmc/windowing/X11/XRandR.h -+++ b/xbmc/windowing/X11/XRandR.h -@@ -79,6 +79,7 @@ class XOutput - } - CStdString name; - bool isConnected; -+ int screen; - int w; - int h; - int x; -@@ -94,12 +95,15 @@ class CXRandR - public: - CXRandR(bool query=false); - bool Query(bool force=false); -+ bool Query(bool force, int screennum); - std::vector GetModes(void); -- XOutput GetCurrentOutput(); - XMode GetCurrentMode(CStdString outputName); -+ XOutput *GetOutput(CStdString outputName); - bool SetMode(XOutput output, XMode mode); - void LoadCustomModeLinesToAllOutputs(void); - void SaveState(); -+ void SetNumScreens(unsigned int num); -+ bool IsOutputConnected(CStdString name); - //bool Has1080i(); - //bool Has1080p(); - //bool Has720p(); -@@ -107,10 +111,10 @@ class CXRandR - - private: - bool m_bInit; -- std::vector m_current; - std::vector m_outputs; - CStdString m_currentOutput; - CStdString m_currentMode; -+ unsigned int m_numScreens; - }; - - extern CXRandR g_xrandr; --- -1.7.10 - - -From ec0fa66fe2322cf5cd47ec0b6b832f47e1ab7e1f Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 43/88] X11: fix multi-head setups - ---- - language/English/strings.po | 4 +- - xbmc/rendering/gl/RenderSystemGL.h | 1 + - xbmc/settings/GUISettings.cpp | 5 + - xbmc/settings/GUIWindowSettingsCategory.cpp | 60 +++++- - xbmc/settings/GUIWindowSettingsCategory.h | 1 + - xbmc/windowing/WinEventsX11.cpp | 7 + - xbmc/windowing/X11/WinSystemX11.cpp | 262 ++++++++++++++++----------- - xbmc/windowing/X11/WinSystemX11.h | 10 +- - 8 files changed, 235 insertions(+), 115 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index c3ba92f..f2abd3f 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -895,7 +895,9 @@ msgctxt "#245" - msgid "Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1) (VShift: %2.2f)" - msgstr "" - --#empty string with id 246 -+msgctxt "#246" -+msgid "Monitor" -+msgstr "" - - msgctxt "#247" - msgid "Scripts" -diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h -index efe5493..85d780d 100644 ---- a/xbmc/rendering/gl/RenderSystemGL.h -+++ b/xbmc/rendering/gl/RenderSystemGL.h -@@ -44,6 +44,7 @@ class CRenderSystemGL : public CRenderSystemBase - virtual bool IsExtSupported(const char* extension); - - virtual void SetVSync(bool vsync); -+ virtual void ResetVSync() { m_bVsyncInit = false; } - - virtual void SetViewPort(CRect& viewPort); - virtual void GetViewPort(CRect& viewPort); -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 4cec1b3..30b402d 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -392,11 +392,16 @@ void CGUISettings::Initialize() - AddGroup(SETTINGS_SYSTEM, 13000); - CSettingsCategory* vs = AddCategory(SETTINGS_SYSTEM, "videoscreen", 21373); - -+#if defined(HAS_GLX) -+ AddString(vs, "videoscreen.monitor", 246, "", SPIN_CONTROL_TEXT); -+#endif -+ - // this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode. - // contains a DISPLAYMODE - #if !defined(TARGET_DARWIN_IOS_ATV2) && !defined(TARGET_RASPBERRY_PI) - AddInt(vs, "videoscreen.screen", 240, 0, -1, 1, 32, SPIN_CONTROL_TEXT); - #endif -+ - // this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode. - // contains an index to the g_settings.m_ResInfo array. the only meaningful fields are iScreen, iWidth, iHeight. - #if defined(TARGET_DARWIN) -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index 2af9315..b9f18e4 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -528,6 +528,12 @@ void CGUIWindowSettingsCategory::CreateSettings() - FillInRefreshRates(strSetting, g_guiSettings.GetResolution(), false); - continue; - } -+ else if (strSetting.Equals("videoscreen.monitor")) -+ { -+ AddSetting(pSetting, group->GetWidth(), iControlID); -+ FillInMonitors(strSetting); -+ continue; -+ } - else if (strSetting.Equals("lookandfeel.skintheme")) - { - AddSetting(pSetting, group->GetWidth(), iControlID); -@@ -1477,6 +1483,20 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting - // Cascade - FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); - } -+ else if (strSetting.Equals("videoscreen.monitor")) -+ { -+ CSettingString *pSettingString = (CSettingString *)pSettingControl->GetSetting(); -+ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(pSettingControl->GetID()); -+ CStdString currentMonitor = pControl->GetCurrentLabel(); -+ if (!g_Windowing.IsCurrentOutput(currentMonitor)) -+ { -+ g_guiSettings.SetString("videoscreen.monitor", currentMonitor); -+ g_Windowing.UpdateResolutions(); -+ DisplayMode mode = g_guiSettings.GetInt("videoscreen.screen"); -+ // Cascade -+ FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); -+ } -+ } - else if (strSetting.Equals("videoscreen.resolution")) - { - RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution"); -@@ -2413,11 +2433,15 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES - if (g_advancedSettings.m_canWindowed) - pControl->AddLabel(g_localizeStrings.Get(242), -1); - -+#if !defined(HAS_GLX) - for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++) - { - strScreen.Format(g_localizeStrings.Get(241), g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen + 1); - pControl->AddLabel(strScreen, g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen); - } -+#else -+ pControl->AddLabel(g_localizeStrings.Get(244), 0); -+#endif - pControl->SetValue(mode); - g_guiSettings.SetInt("videoscreen.screen", mode); - } -@@ -2425,6 +2449,36 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES - return mode; - } - -+void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) -+{ -+ // we expect "videoscreen.monitor" but it might be hidden on some platforms, -+ // so check that we actually have a visable control. -+ CBaseSettingControl *control = GetSetting(strSetting); -+ if (control) -+ { -+ control->SetDelayed(); -+ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID()); -+ pControl->Clear(); -+ -+ std::vector monitors; -+ g_Windowing.GetConnectedOutputs(&monitors); -+ -+ int currentMonitor = 0; -+ for (unsigned int i=0; iAddLabel(monitors[i], i); -+ } -+ -+ pControl->SetValue(currentMonitor); -+ g_guiSettings.SetString("videoscreen.monitor", g_settings.m_ResInfo[RES_DESKTOP].strOutput); -+ } -+} -+ -+ - void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, DisplayMode mode, RESOLUTION res, bool UserChange) - { - BaseSettingControlPtr control = GetSetting(strSetting); -@@ -2553,13 +2607,15 @@ void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes) - RESOLUTION lastRes = g_graphicsContext.GetVideoResolution(); - bool cancelled = false; - -+ bool outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); -+ - g_guiSettings.SetResolution(nextRes); -- g_graphicsContext.SetVideoResolution(nextRes); -+ g_graphicsContext.SetVideoResolution(nextRes, outputChanged); - - if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000)) - { - g_guiSettings.SetResolution(lastRes); -- g_graphicsContext.SetVideoResolution(lastRes); -+ g_graphicsContext.SetVideoResolution(lastRes, outputChanged); - - DisplayMode mode = FillInScreens("videoscreen.screen", lastRes); - FillInResolutions("videoscreen.resolution", mode, lastRes, false); -diff --git a/xbmc/settings/GUIWindowSettingsCategory.h b/xbmc/settings/GUIWindowSettingsCategory.h -index 5142c6e..0d4649d 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.h -+++ b/xbmc/settings/GUIWindowSettingsCategory.h -@@ -51,6 +51,7 @@ class CGUIWindowSettingsCategory : - void FillInSoundSkins(CSetting *pSetting); - void FillInLanguages(CSetting *pSetting, const std::vector &languages = std::vector(), const std::vector &languageKeys = std::vector()); - DisplayMode FillInScreens(CStdString strSetting, RESOLUTION res); -+ void FillInMonitors(CStdString strSetting); - void FillInResolutions(CStdString strSetting, DisplayMode mode, RESOLUTION res, bool UserChange); - void FillInRefreshRates(CStdString strSetting, RESOLUTION res, bool UserChange); - void OnRefreshRateChanged(RESOLUTION resolution); -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 5946a33..6c22358 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -517,9 +517,16 @@ bool CWinEventsX11::MessagePump() - break; - } - -+ case EnterNotify: -+ { -+ g_Windowing.NotifyMouseCoverage(true); -+ break; -+ } -+ - // lose mouse coverage - case LeaveNotify: - { -+ g_Windowing.NotifyMouseCoverage(false); - g_Mouse.SetActive(false); - break; - } -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 6b0aa92..5f913f1 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -33,6 +33,7 @@ - #include "cores/VideoRenderers/RenderManager.h" - #include "utils/TimeUtils.h" - #include "settings/GUISettings.h" -+#include "windowing/WindowingFactory.h" - - #if defined(HAS_XRANDR) - #include -@@ -54,6 +55,7 @@ - m_bIgnoreNextFocusMessage = false; - m_dpyLostTime = 0; - m_invisibleCursor = 0; -+ m_bIsInternalXrr = false; - - XSetErrorHandler(XErrorHandler); - } -@@ -66,7 +68,8 @@ bool CWinSystemX11::InitWindowSystem() - { - if ((m_dpy = XOpenDisplay(NULL))) - { -- return CWinSystemBase::InitWindowSystem(); -+ bool ret = CWinSystemBase::InitWindowSystem(); -+ return ret; - } - else - CLog::Log(LOGERROR, "GLX Error: No Display found"); -@@ -103,6 +106,8 @@ bool CWinSystemX11::DestroyWindowSystem() - - //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy - //so instead we just let m_dpy die on exit -+ // i have seen core dumps on ATI if the display is not closed here -+ XCloseDisplay(m_dpy); - } - - // m_SDLSurface is free()'d by SDL_Quit(). -@@ -125,7 +130,10 @@ bool CWinSystemX11::DestroyWindow() - return true; - - if (m_glContext) -+ { -+ glFinish(); - glXMakeCurrent(m_dpy, None, NULL); -+ } - - if (m_invisibleCursor) - { -@@ -155,7 +163,7 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - && m_nHeight == newHeight) - return true; - -- if (!SetWindow(newWidth, newHeight, false)) -+ if (!SetWindow(newWidth, newHeight, false, g_guiSettings.GetString("videoscreen.monitor"))) - { - return false; - } -@@ -164,58 +172,11 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - m_nWidth = newWidth; - m_nHeight = newHeight; - m_bFullScreen = false; -+ m_currentOutput = g_guiSettings.GetString("videoscreen.monitor"); - - return false; - } - --void CWinSystemX11::RefreshWindow() --{ -- if (!g_xrandr.Query(true)) -- { -- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -- return; -- } -- XOutput out = g_xrandr.GetCurrentOutput(); -- XMode mode = g_xrandr.GetCurrentMode(out.name); -- -- RotateResolutions(); -- -- // only overwrite desktop resolution, if we are not in fullscreen mode -- if (!g_graphicsContext.IsFullScreenVideo()) -- { -- CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshWindow - store desktop resolution, width: %d, height: %d, hz: %2.2f", mode.w, mode.h, mode.hz); -- if (!out.isRotated) -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -- else -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.h, mode.w, mode.hz); -- g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; -- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; -- } -- -- RESOLUTION_INFO res; -- unsigned int i; -- bool found(false); -- for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) -- { -- if (g_settings.m_ResInfo[i].strId == mode.id) -- { -- found = true; -- break; -- } -- } -- -- if (!found) -- { -- CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -- return; -- } -- -- if (g_graphicsContext.IsFullScreenRoot()) -- g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -- else -- g_graphicsContext.SetVideoResolution(RES_WINDOW, true); --} -- - bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { - -@@ -240,8 +201,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; - } - -- XOutput currout = g_xrandr.GetCurrentOutput(); -- XMode currmode = g_xrandr.GetCurrentMode(currout.name); -+ XMode currmode = g_xrandr.GetCurrentMode(out.name); - - // flip h/w when rotated - if (m_bIsRotated) -@@ -252,16 +212,17 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - } - - // only call xrandr if mode changes -- if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h || -+ if (currmode.w != mode.w || currmode.h != mode.h || - currmode.hz != mode.hz || currmode.id != mode.id) - { - CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); - OnLostDevice(); -+ m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); - } - #endif - -- if (!SetWindow(res.iWidth, res.iHeight, fullScreen)) -+ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, g_guiSettings.GetString("videoscreen.monitor"))) - return false; - - RefreshGlxContext(); -@@ -269,6 +230,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_bFullScreen = fullScreen; -+ m_currentOutput = g_guiSettings.GetString("videoscreen.monitor"); - - return true; - } -@@ -277,19 +239,30 @@ void CWinSystemX11::UpdateResolutions() - { - CWinSystemBase::UpdateResolutions(); - -- - #if defined(HAS_XRANDR) -- if(g_xrandr.Query()) -- { -- XOutput out = g_xrandr.GetCurrentOutput(); -- XMode mode = g_xrandr.GetCurrentMode(out.name); -- m_bIsRotated = out.isRotated; -+ CStdString currentMonitor; -+ int numScreens = XScreenCount(m_dpy); -+ g_xrandr.SetNumScreens(numScreens); -+ if(g_xrandr.Query(true)) -+ { -+ currentMonitor = g_guiSettings.GetString("videoscreen.monitor"); -+ // check if the monitor is connected -+ XOutput *out = g_xrandr.GetOutput(currentMonitor); -+ if (!out) -+ { -+ // choose first output -+ currentMonitor = g_xrandr.GetModes()[0].name; -+ out = g_xrandr.GetOutput(currentMonitor); -+ g_guiSettings.SetString("videoscreen.monitor", currentMonitor); -+ } -+ XMode mode = g_xrandr.GetCurrentMode(currentMonitor); -+ m_bIsRotated = out->isRotated; - if (!m_bIsRotated) -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], out->screen, mode.w, mode.h, mode.hz); - else -- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.h, mode.w, mode.hz); -+ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], out->screen, mode.h, mode.w, mode.hz); - g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; -- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; -+ g_settings.m_ResInfo[RES_DESKTOP].strOutput = currentMonitor; - } - else - #endif -@@ -300,23 +273,26 @@ void CWinSystemX11::UpdateResolutions() - UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, 0.0); - } - -- - #if defined(HAS_XRANDR) - -+ // erase previous stored modes -+ if (g_settings.m_ResInfo.size() > RES_CUSTOM) -+ { -+ std::vector::iterator firstCustom = g_settings.m_ResInfo.begin()+RES_CUSTOM; -+ g_settings.m_ResInfo.erase(firstCustom, g_settings.m_ResInfo.end()); -+ } -+ - CLog::Log(LOGINFO, "Available videomodes (xrandr):"); -- vector::iterator outiter; -- vector outs; -- outs = g_xrandr.GetModes(); -- CLog::Log(LOGINFO, "Number of connected outputs: %"PRIdS"", outs.size()); -+ -+ XOutput *out = g_xrandr.GetOutput(currentMonitor); - string modename = ""; - -- for (outiter = outs.begin() ; outiter != outs.end() ; outiter++) -+ if (out != NULL) - { -- XOutput out = *outiter; - vector::iterator modeiter; -- CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out.name.c_str(), out.modes.size()); -+ CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out->name.c_str(), out->modes.size()); - -- for (modeiter = out.modes.begin() ; modeiter!=out.modes.end() ; modeiter++) -+ for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++) - { - XMode mode = *modeiter; - CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", -@@ -336,15 +312,15 @@ void CWinSystemX11::UpdateResolutions() - res.iWidth = mode.h; - res.iHeight = mode.w; - } -- if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) -- res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); -+ if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0) -+ res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h)); - else - res.fPixelRatio = 1.0f; - - CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio); - -- res.strMode.Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); -- res.strOutput = out.name; -+ res.strMode.Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); -+ res.strOutput = out->name; - res.strId = mode.id; - res.iSubtitles = (int)(0.95*mode.h); - res.fRefreshRate = mode.hz; -@@ -363,28 +339,19 @@ void CWinSystemX11::UpdateResolutions() - - } - --void CWinSystemX11::RotateResolutions() -+void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) - { --#if defined(HAS_XRANDR) -- XOutput out = g_xrandr.GetCurrentOutput(); -- if (out.isRotated == m_bIsRotated) -- return; -- -- for (unsigned int i = 0; i < g_settings.m_ResInfo.size(); ++i) -+ vector outs; -+ outs = g_xrandr.GetModes(); -+ for(unsigned int i=0; ipush_back(outs[i].name); - } -- // update desktop resolution --// int h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; --// int w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; --// float hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; --// UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, hz); -- -- m_bIsRotated = out.isRotated; -+} - --#endif -+bool CWinSystemX11::IsCurrentOutput(CStdString output) -+{ -+ return m_currentOutput.Equals(output); - } - - bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) -@@ -414,8 +381,11 @@ bool CWinSystemX11::RefreshGlxContext() - if (m_glContext) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); -+ glFinish(); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -+ XSync(m_dpy, FALSE); -+ g_Windowing.ResetVSync(); - return true; - } - -@@ -481,6 +451,8 @@ bool CWinSystemX11::RefreshGlxContext() - { - // make this context current - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -+ g_Windowing.ResetVSync(); -+ XSync(m_dpy, False); - retVal = true; - } - else -@@ -522,24 +494,53 @@ void CWinSystemX11::ResetOSScreensaver() - - void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - { -- if (bActivated && m_bWasFullScreenBeforeMinimize && !g_graphicsContext.IsFullScreenRoot()) -+ if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) -+ { - g_graphicsContext.ToggleFullScreenRoot(); - -+ m_bWasFullScreenBeforeMinimize = false; -+ } - m_minimized = !bActivated; - } - - void CWinSystemX11::NotifyAppFocusChange(bool bGaining) - { - if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && -- !g_graphicsContext.IsFullScreenRoot()) -+ !m_bFullScreen) -+ { -+ m_bWasFullScreenBeforeMinimize = false; - g_graphicsContext.ToggleFullScreenRoot(); -+ m_minimized = false; -+ } - if (!bGaining) - m_bIgnoreNextFocusMessage = false; - } - -+void CWinSystemX11::NotifyMouseCoverage(bool covered) -+{ -+ if (!m_bFullScreen) -+ return; -+ -+ if (covered) -+ { -+ int result = -1; -+ while (result != GrabSuccess && result != AlreadyGrabbed) -+ { -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); -+ XbmcThreads::ThreadSleep(100); -+ } -+ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -+ } -+ else -+ { -+ XUngrabKeyboard(m_dpy, CurrentTime); -+ XUngrabPointer(m_dpy, CurrentTime); -+ } -+} -+ - bool CWinSystemX11::Minimize() - { -- m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); -+ m_bWasFullScreenBeforeMinimize = m_bFullScreen; - if (m_bWasFullScreenBeforeMinimize) - { - m_bIgnoreNextFocusMessage = true; -@@ -605,13 +606,46 @@ void CWinSystemX11::CheckDisplayEvents() - void CWinSystemX11::NotifyXRREvent() - { - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); -- RefreshWindow(); -+ m_windowDirty = true; - -- CSingleLock lock(m_resourceSection); -+ // if external event update resolutions -+ if (!m_bIsInternalXrr) -+ { -+ UpdateResolutions(); -+ } -+ else if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } -+ m_bIsInternalXrr = false; - -- // tell any shared resources -- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -- (*i)->OnResetDevice(); -+ CStdString currentOutput = g_guiSettings.GetString("videoscreen.monitor"); -+ XOutput *out = g_xrandr.GetOutput(currentOutput); -+ XMode mode = g_xrandr.GetCurrentMode(currentOutput); -+ -+ RESOLUTION_INFO res; -+ unsigned int i; -+ bool found(false); -+ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) -+ { -+ if (g_settings.m_ResInfo[i].strId == mode.id) -+ { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); -+ i = RES_DESKTOP; -+ } -+ -+ if (g_graphicsContext.IsFullScreenRoot()) -+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); -+ else -+ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); - - } - -@@ -664,14 +698,14 @@ bool CWinSystemX11::EnableFrameLimiter() - return m_minimized; - } - --bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) -+bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) - { - bool changeWindow = false; - bool changeSize = false; - bool mouseActive = false; - float mouseX, mouseY; - -- if (m_glWindow && (m_bFullScreen != fullscreen)) -+ if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) - { - mouseActive = g_Mouse.IsActive(); - if (mouseActive) -@@ -693,6 +727,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - else - mouseActive = false; - } -+ OnLostDevice(); - DestroyWindow(); - } - -@@ -714,7 +749,11 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - XSetWindowAttributes swa; - XVisualInfo *vi; - -- vi = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att); -+ XOutput *out = g_xrandr.GetOutput(output); -+ if (!out) -+ out = g_xrandr.GetOutput(m_currentOutput); -+ m_nScreen = out->screen; -+ vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -@@ -730,7 +769,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; - - m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -- 0, 0, width, height, 0, vi->depth, -+ out->x, out->y, width, height, 0, vi->depth, - InputOutput, vi->visual, - mask, &swa); - -@@ -801,14 +840,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen) - if (fullscreen) - { - int result = -1; -- while (result != GrabSuccess) -+ while (result != GrabSuccess && result != AlreadyGrabbed) - { -- result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_glWindow, None, CurrentTime); -+ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - XbmcThreads::ThreadSleep(100); - } - XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); -- - } -+ CSingleLock lock(m_resourceSection); -+ // tell any shared resources -+ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) -+ (*i)->OnResetDevice(); -+ -+ m_windowDirty = false; - } - return true; - } -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 93cf5db..71034fc 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -65,15 +65,16 @@ class CWinSystemX11 : public CWinSystemBase - Display* GetDisplay() { return m_dpy; } - GLXWindow GetWindow() { return m_glWindow; } - GLXContext GetGlxContext() { return m_glContext; } -- void RefreshWindow(); - void NotifyXRREvent(); -+ void GetConnectedOutputs(std::vector *outputs); -+ bool IsCurrentOutput(CStdString output); -+ void NotifyMouseCoverage(bool covered); - - protected: - bool RefreshGlxContext(); - void CheckDisplayEvents(); - void OnLostDevice(); -- bool SetWindow(int width, int height, bool fullscreen); -- void RotateResolutions(); -+ bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); - - Window m_glWindow; - GLXContext m_glContext; -@@ -88,6 +89,9 @@ class CWinSystemX11 : public CWinSystemBase - CCriticalSection m_resourceSection; - std::vector m_resources; - uint64_t m_dpyLostTime; -+ CStdString m_currentOutput; -+ bool m_windowDirty; -+ bool m_bIsInternalXrr; - - private: - bool IsSuitableVisual(XVisualInfo *vInfo); --- -1.7.10 - - -From 89a7d265a0e2673b8076bde718690cbb02e59670 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 44/88] X11: remove all DefaultScreen and RootWindow macros - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- - xbmc/windowing/X11/WinSystemX11.h | 1 + - xbmc/windowing/X11/WinSystemX11GL.cpp | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 5f913f1..af1307c 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -267,7 +267,7 @@ void CWinSystemX11::UpdateResolutions() - else - #endif - { -- int x11screen = DefaultScreen(m_dpy); -+ int x11screen = m_nScreen; - int w = DisplayWidth(m_dpy, x11screen); - int h = DisplayHeight(m_dpy, x11screen); - UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, 0.0); -@@ -393,7 +393,7 @@ bool CWinSystemX11::RefreshGlxContext() - XVisualInfo *visuals; - XVisualInfo *vInfo = NULL; - int availableVisuals = 0; -- vMask.screen = DefaultScreen(m_dpy); -+ vMask.screen = m_nScreen; - XWindowAttributes winAttr; - - /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() -@@ -547,7 +547,7 @@ bool CWinSystemX11::Minimize() - g_graphicsContext.ToggleFullScreenRoot(); - } - -- XIconifyWindow(m_dpy, m_glWindow, DefaultScreen(m_dpy)); -+ XIconifyWindow(m_dpy, m_glWindow, m_nScreen); - - m_minimized = true; - return true; -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 71034fc..3bb4b8e 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -47,6 +47,7 @@ class CWinSystemX11 : public CWinSystemBase - virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays); - virtual void UpdateResolutions(); - virtual int GetNumScreens() { return 1; } -+ virtual int GetCurrentScreen() { return m_nScreen; } - virtual void ShowOSMouse(bool show); - virtual void ResetOSScreensaver(); - virtual bool EnableFrameLimiter(); -diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp -index f858f88..d192697 100644 ---- a/xbmc/windowing/X11/WinSystemX11GL.cpp -+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp -@@ -203,7 +203,7 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R - return false; - - m_glxext = " "; -- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy)); -+ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_nScreen); - m_glxext += " "; - - CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str()); --- -1.7.10 - - -From ac87010f83e230caf6ed03e36c562a4fb0abb2ab Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 45/88] X11: remove all DefaultScreen and RootWindow macros - (VideoRefClock) - -Note this is on a separate display connection. ---- - xbmc/video/VideoReferenceClock.cpp | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 9785fe7..0004e07 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -270,7 +270,7 @@ bool CVideoReferenceClock::SetupGLX() - } - - bool ExtensionFound = false; -- istringstream Extensions(glXQueryExtensionsString(m_Dpy, DefaultScreen(m_Dpy))); -+ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); - string ExtensionStr; - - while (!ExtensionFound) -@@ -297,7 +297,7 @@ bool CVideoReferenceClock::SetupGLX() - m_bIsATI = true; - } - -- m_vInfo = glXChooseVisual(m_Dpy, DefaultScreen(m_Dpy), singleBufferAttributes); -+ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); - if (!m_vInfo) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); -@@ -308,15 +308,16 @@ bool CVideoReferenceClock::SetupGLX() - { - Swa.border_pixel = 0; - Swa.event_mask = StructureNotifyMask; -- Swa.colormap = XCreateColormap(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), m_vInfo->visual, AllocNone ); -+ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); - SwaMask = CWBorderPixel | CWColormap | CWEventMask; - -- m_Window = XCreateWindow(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), 0, 0, 256, 256, 0, -+ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, - m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); - } - else - { -- m_pixmap = XCreatePixmap(m_Dpy, DefaultRootWindow(m_Dpy), 256, 256, m_vInfo->depth); -+ Window window = g_Windowing.GetWindow(); -+ m_pixmap = XCreatePixmap(m_Dpy, window, 256, 256, m_vInfo->depth); - if (!m_pixmap) - { - CLog::Log(LOGDEBUG, "CVideoReferenceClock: unable to create pixmap"); -@@ -383,7 +384,7 @@ bool CVideoReferenceClock::SetupGLX() - - //set up receiving of RandR events, we'll get one when the refreshrate changes - XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); -- XRRSelectInput(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), RRScreenChangeNotifyMask); -+ XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); - - UpdateRefreshrate(true); //forced refreshrate update - m_MissedVblanks = 0; -@@ -518,7 +519,7 @@ int CVideoReferenceClock::GetRandRRate() - int RefreshRate; - XRRScreenConfiguration *CurrInfo; - -- CurrInfo = XRRGetScreenInfo(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen)); -+ CurrInfo = XRRGetScreenInfo(m_Dpy, g_Windowing.GetWindow()); - RefreshRate = XRRConfigCurrentRate(CurrInfo); - XRRFreeScreenConfigInfo(CurrInfo); - --- -1.7.10 - - -From 5510c47704fc1156897abc1932151460e4c07569 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 46/88] X11: recreate gl context after output has changed - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++---------- - xbmc/windowing/X11/WinSystemX11.h | 1 + - xbmc/windowing/X11/WinSystemX11GL.cpp | 9 +++++++++ - 3 files changed, 24 insertions(+), 10 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index af1307c..d3d15e2 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -168,7 +168,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n - return false; - } - -- RefreshGlxContext(); - m_nWidth = newWidth; - m_nHeight = newHeight; - m_bFullScreen = false; -@@ -219,14 +218,13 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - OnLostDevice(); - m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); -+ return true; - } - #endif - - if (!SetWindow(res.iWidth, res.iHeight, fullScreen, g_guiSettings.GetString("videoscreen.monitor"))) - return false; - -- RefreshGlxContext(); -- - m_nWidth = res.iWidth; - m_nHeight = res.iHeight; - m_bFullScreen = fullScreen; -@@ -381,11 +379,8 @@ bool CWinSystemX11::RefreshGlxContext() - if (m_glContext) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); -- glFinish(); - glXMakeCurrent(m_dpy, None, NULL); - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -- XSync(m_dpy, FALSE); -- g_Windowing.ResetVSync(); - return true; - } - -@@ -445,14 +440,14 @@ bool CWinSystemX11::RefreshGlxContext() - { - glXMakeCurrent(m_dpy, None, NULL); - glXDestroyContext(m_dpy, m_glContext); -+ XSync(m_dpy, FALSE); -+ m_newGlContext = true; - } - - if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True))) - { - // make this context current - glXMakeCurrent(m_dpy, m_glWindow, m_glContext); -- g_Windowing.ResetVSync(); -- XSync(m_dpy, False); - retVal = true; - } - else -@@ -729,6 +724,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - OnLostDevice(); - DestroyWindow(); -+ m_windowDirty = true; - } - - // create main window -@@ -847,13 +843,21 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } -+ -+ CDirtyRegionList dr; -+ RefreshGlxContext(); -+ XSync(m_dpy, FALSE); -+ g_graphicsContext.Clear(0); -+ g_graphicsContext.Flip(dr); -+ g_Windowing.ResetVSync(); -+ m_windowDirty = false; -+ - CSingleLock lock(m_resourceSection); - // tell any shared resources - for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) - (*i)->OnResetDevice(); -- -- m_windowDirty = false; - } -+ - return true; - } - -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 3bb4b8e..cc28f56 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -93,6 +93,7 @@ class CWinSystemX11 : public CWinSystemBase - CStdString m_currentOutput; - bool m_windowDirty; - bool m_bIsInternalXrr; -+ bool m_newGlContext; - - private: - bool IsSuitableVisual(XVisualInfo *vInfo); -diff --git a/xbmc/windowing/X11/WinSystemX11GL.cpp b/xbmc/windowing/X11/WinSystemX11GL.cpp -index d192697..0f2d1d2 100644 ---- a/xbmc/windowing/X11/WinSystemX11GL.cpp -+++ b/xbmc/windowing/X11/WinSystemX11GL.cpp -@@ -23,6 +23,7 @@ - - #include "WinSystemX11GL.h" - #include "utils/log.h" -+#include "Application.h" - - CWinSystemX11GL::CWinSystemX11GL() - { -@@ -245,17 +246,25 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R - - bool CWinSystemX11GL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) - { -+ m_newGlContext = false; - CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop); - CRenderSystemGL::ResetRenderSystem(newWidth, newHeight, false, 0); - -+ if (m_newGlContext) -+ g_application.ReloadSkin(); -+ - return true; - } - - bool CWinSystemX11GL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) - { -+ m_newGlContext = false; - CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays); - CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate); - -+ if (m_newGlContext) -+ g_application.ReloadSkin(); -+ - return true; - } - --- -1.7.10 - - -From 72196d5e8e45d884bf9ac03d7050d29ced2b3aeb Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 47/88] X11: hook video reference clock in windowing - ---- - xbmc/video/VideoReferenceClock.cpp | 71 ++++++++++++++++++++++++++---------- - xbmc/video/VideoReferenceClock.h | 13 ++++++- - 2 files changed, 63 insertions(+), 21 deletions(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 0004e07..fa8e35a 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -135,12 +135,23 @@ - m_Context = NULL; - m_pixmap = None; - m_glPixmap = None; -- m_RREventBase = 0; - m_UseNvSettings = true; - m_bIsATI = false; - #endif - } - -+CVideoReferenceClock::~CVideoReferenceClock() -+{ -+#if defined(HAS_GLX) -+ // some ATI voodoo, if we don't close the display, we crash on exit -+ if (m_Dpy) -+ { -+ XCloseDisplay(m_Dpy); -+ m_Dpy = NULL; -+ } -+#endif -+} -+ - void CVideoReferenceClock::Process() - { - bool SetupSuccess = false; -@@ -151,6 +162,10 @@ void CVideoReferenceClock::Process() - m_D3dCallback.Reset(); - g_Windowing.Register(&m_D3dCallback); - #endif -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ g_Windowing.Register(this); -+ m_xrrEvent = false; -+#endif - - while(!m_bStop) - { -@@ -211,6 +226,16 @@ void CVideoReferenceClock::Process() - //clean up the vblank clock - #if defined(HAS_GLX) && defined(HAS_XRANDR) - CleanupGLX(); -+ if (m_xrrEvent) -+ { -+ m_releaseEvent.Set(); -+ while (!m_bStop) -+ { -+ if (m_resetEvent.WaitMSec(100)) -+ break; -+ } -+ m_xrrEvent = false; -+ } - #elif defined(_WIN32) && defined(HAS_DX) - CleanupD3D(); - #elif defined(TARGET_DARWIN) -@@ -222,6 +247,9 @@ void CVideoReferenceClock::Process() - #if defined(_WIN32) && defined(HAS_DX) - g_Windowing.Unregister(&m_D3dCallback); - #endif -+#if defined(HAS_GLX) -+ g_Windowing.Unregister(this); -+#endif - } - - bool CVideoReferenceClock::WaitStarted(int MSecs) -@@ -231,6 +259,24 @@ bool CVideoReferenceClock::WaitStarted(int MSecs) - } - - #if defined(HAS_GLX) && defined(HAS_XRANDR) -+ -+void CVideoReferenceClock::OnLostDevice() -+{ -+ if (!m_xrrEvent) -+ { -+ m_releaseEvent.Reset(); -+ m_resetEvent.Reset(); -+ m_xrrEvent = true; -+ m_releaseEvent.Wait(); -+ } -+} -+ -+void CVideoReferenceClock::OnResetDevice() -+{ -+ m_xrrEvent = false; -+ m_resetEvent.Set(); -+} -+ - bool CVideoReferenceClock::SetupGLX() - { - int singleBufferAttributes[] = { -@@ -382,10 +428,6 @@ bool CVideoReferenceClock::SetupGLX() - return false; - } - -- //set up receiving of RandR events, we'll get one when the refreshrate changes -- XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); -- XRRSelectInput(m_Dpy, g_Windowing.GetWindow(), RRScreenChangeNotifyMask); -- - UpdateRefreshrate(true); //forced refreshrate update - m_MissedVblanks = 0; - -@@ -586,6 +628,9 @@ void CVideoReferenceClock::RunGLX() - - while(!m_bStop) - { -+ if (m_xrrEvent) -+ return; -+ - //wait for the next vblank - if (!m_bIsATI) - { -@@ -649,7 +694,6 @@ void CVideoReferenceClock::RunGLX() - UpdateClock((int)(VblankCount - PrevVblankCount), true); - SingleLock.Leave(); - SendVblankSignal(); -- UpdateRefreshrate(); - IsReset = false; - } - else if (!m_bStop) -@@ -1186,23 +1230,10 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) - - #if defined(HAS_GLX) && defined(HAS_XRANDR) - -- //check for RandR events -- bool GotEvent = Forced || m_RefreshChanged == 2; -- XEvent Event; -- while (XCheckTypedEvent(m_Dpy, m_RREventBase + RRScreenChangeNotify, &Event)) -- { -- if (Event.type == m_RREventBase + RRScreenChangeNotify) -- { -- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Received RandR event %i", Event.type); -- GotEvent = true; -- } -- XRRUpdateConfiguration(&Event); -- } -- - if (!Forced) - m_RefreshChanged = 0; - -- if (!GotEvent) //refreshrate did not change -+ if (!Forced) //refreshrate did not change - return false; - - //the refreshrate can be wrong on nvidia drivers, so read it from nvidia-settings when it's available -diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h -index dcc4f09..7eb6317 100644 ---- a/xbmc/video/VideoReferenceClock.h -+++ b/xbmc/video/VideoReferenceClock.h -@@ -30,6 +30,7 @@ - #include - #include - #include -+ #include "guilib/DispResource.h" - #elif defined(_WIN32) && defined(HAS_DX) - #include - #include "guilib/D3DResource.h" -@@ -56,9 +57,13 @@ class CD3DCallback : public ID3DResource - #endif - - class CVideoReferenceClock : public CThread -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ ,public IDispResource -+#endif - { - public: - CVideoReferenceClock(); -+ virtual ~CVideoReferenceClock(); - - int64_t GetTime(bool interpolated = true); - int64_t GetFrequency(); -@@ -75,6 +80,11 @@ class CVideoReferenceClock : public CThread - void VblankHandler(int64_t nowtime, double fps); - #endif - -+#if defined(HAS_GLX) && defined(HAS_XRANDR) -+ virtual void OnLostDevice(); -+ virtual void OnResetDevice(); -+#endif -+ - private: - void Process(); - bool UpdateRefreshrate(bool Forced = false); -@@ -121,7 +131,8 @@ class CVideoReferenceClock : public CThread - GLXContext m_Context; - Pixmap m_pixmap; - GLXPixmap m_glPixmap; -- int m_RREventBase; -+ bool m_xrrEvent; -+ CEvent m_releaseEvent, m_resetEvent; - - bool m_UseNvSettings; - bool m_bIsATI; --- -1.7.10 - - -From ee2f6f0a246b6b684192ee30cb2cd0e5ac1300cf Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 48/88] X11: fix video calibrations - ---- - xbmc/settings/Settings.cpp | 1 + - xbmc/windowing/WinSystem.h | 1 + - xbmc/windowing/X11/WinSystemX11.cpp | 36 ++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 4 files changed, 38 insertions(+), 1 deletion(-) - -diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp -index 8a430ad..fde6e4e 100644 ---- a/xbmc/settings/Settings.cpp -+++ b/xbmc/settings/Settings.cpp -@@ -55,6 +55,7 @@ - #include "filesystem/File.h" - #include "filesystem/DirectoryCache.h" - #include "DatabaseManager.h" -+#include "windowing/WindowingFactory.h" - - using namespace std; - using namespace XFILE; -diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h -index 05c5eda..852d085 100644 ---- a/xbmc/windowing/WinSystem.h -+++ b/xbmc/windowing/WinSystem.h -@@ -100,6 +100,7 @@ class CWinSystemBase - std::vector ScreenResolutions(int screen); - std::vector RefreshRates(int screen, int width, int height, uint32_t dwFlags); - REFRESHRATE DefaultRefreshRate(int screen, std::vector rates); -+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo) { return true; }; - - protected: - void UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen, int width, int height, float refreshRate, uint32_t dwFlags = 0); -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index d3d15e2..487b324 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -320,7 +320,7 @@ void CWinSystemX11::UpdateResolutions() - res.strMode.Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); - res.strOutput = out->name; - res.strId = mode.id; -- res.iSubtitles = (int)(0.95*mode.h); -+ res.iSubtitles = (int)(0.965*mode.h); - res.fRefreshRate = mode.hz; - res.bFullScreen = true; - -@@ -333,8 +333,42 @@ void CWinSystemX11::UpdateResolutions() - g_settings.m_ResInfo.push_back(res); - } - } -+ g_settings.ApplyCalibrations(); - #endif -+} -+ -+bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) -+{ -+ XOutput *out = g_xrandr.GetOutput(m_currentOutput); -+ -+ // keep calibrations done on a not connected output -+ if (!out->name.Equals(resInfo.strOutput)) -+ return true; -+ -+ // keep calibrations not updated with resolution data -+ if (resInfo.iWidth == 0) -+ return true; -+ -+ float fPixRatio; -+ if (resInfo.iHeight>0 && resInfo.iWidth>0 && out->hmm>0 && out->wmm>0) -+ fPixRatio = ((float)out->wmm/(float)resInfo.iWidth) / (((float)out->hmm/(float)resInfo.iHeight)); -+ else -+ fPixRatio = 1.0f; - -+ if (resInfo.Overscan.left != 0) -+ return true; -+ if (resInfo.Overscan.top != 0) -+ return true; -+ if (resInfo.Overscan.right != resInfo.iWidth) -+ return true; -+ if (resInfo.Overscan.bottom != resInfo.iHeight) -+ return true; -+ if (resInfo.fPixelRatio != fPixRatio) -+ return true; -+ if (resInfo.iSubtitles != (int)(0.965*resInfo.iHeight)) -+ return true; -+ -+ return false; - } - - void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index cc28f56..c046c86 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -61,6 +61,7 @@ class CWinSystemX11 : public CWinSystemBase - virtual bool Show(bool raise = true); - virtual void Register(IDispResource *resource); - virtual void Unregister(IDispResource *resource); -+ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo); - - // Local to WinSystemX11 only - Display* GetDisplay() { return m_dpy; } --- -1.7.10 - - -From e4f883d19e247bde088178c96ab3dbb21b7be61d Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 49/88] X11: deactivate screen saver on startup - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++ - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 30 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 487b324..b3e7ab5 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -521,6 +521,33 @@ void CWinSystemX11::ResetOSScreensaver() - } - } - -+void CWinSystemX11::EnableSystemScreenSaver(bool bEnable) -+{ -+ if (!m_dpy) -+ return; -+ -+ if (bEnable) -+ XForceScreenSaver(m_dpy, ScreenSaverActive); -+ else -+ { -+ Window root_return, child_return; -+ int root_x_return, root_y_return; -+ int win_x_return, win_y_return; -+ unsigned int mask_return; -+ bool isInWin = XQueryPointer(m_dpy, RootWindow(m_dpy, m_nScreen), &root_return, &child_return, -+ &root_x_return, &root_y_return, -+ &win_x_return, &win_y_return, -+ &mask_return); -+ -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return+300, root_y_return+300); -+ XSync(m_dpy, FALSE); -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, 0, 0); -+ XSync(m_dpy, FALSE); -+ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return, root_y_return); -+ XSync(m_dpy, FALSE); -+ } -+} -+ - void CWinSystemX11::NotifyAppActiveChange(bool bActivated) - { - if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) -@@ -764,6 +791,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - // create main window - if (!m_glWindow) - { -+ EnableSystemScreenSaver(false); -+ - GLint att[] = - { - GLX_RGBA, -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index c046c86..e953d2d 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -51,6 +51,7 @@ class CWinSystemX11 : public CWinSystemBase - virtual void ShowOSMouse(bool show); - virtual void ResetOSScreensaver(); - virtual bool EnableFrameLimiter(); -+ virtual void EnableSystemScreenSaver(bool bEnable); - - virtual void NotifyAppActiveChange(bool bActivated); - virtual void NotifyAppFocusChange(bool bGaining); --- -1.7.10 - - -From 9143044b7d7469751143fda07a5d960403bac8f9 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 50/88] X11: change method of going full-screen - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index b3e7ab5..91f92c1 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -34,6 +34,7 @@ - #include "utils/TimeUtils.h" - #include "settings/GUISettings.h" - #include "windowing/WindowingFactory.h" -+#include - - #if defined(HAS_XRANDR) - #include -@@ -816,7 +817,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -- swa.override_redirect = fullscreen ? True : False; -+ swa.override_redirect = False; - swa.border_pixel = fullscreen ? 0 : 5; - swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.colormap = cmap; -@@ -832,6 +833,12 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - InputOutput, vi->visual, - mask, &swa); - -+ if (fullscreen) -+ { -+ Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); -+ XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); -+ } -+ - // define invisible cursor - Pixmap bitmapNoData; - XColor black; --- -1.7.10 - - -From e9c03d83ef43d874283b9dab8de57601fa610419 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 51/88] X11: reset key repeat and key modifier on focus lost - and gain - ---- - xbmc/windowing/WinEventsX11.cpp | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 6c22358..d86205d 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -359,6 +359,8 @@ bool CWinEventsX11::MessagePump() - if (WinEvents->m_xic) - XSetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = true; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); -+ WinEvents->m_keymodState = 0; - if (serial == xevent.xfocus.serial) - break; - g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); -@@ -370,6 +372,7 @@ bool CWinEventsX11::MessagePump() - if (WinEvents->m_xic) - XUnsetICFocus(WinEvents->m_xic); - g_application.m_AppFocused = false; -+ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); - g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); - serial = xevent.xfocus.serial; - break; --- -1.7.10 - - -From b0fca2b5347e07513a16932875d5384d32eaae57 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 52/88] X11: replace custom utf8 to unicode with charset - convertor (squash to x11 events) - ---- - xbmc/windowing/WinEventsX11.cpp | 119 ++++----------------------------------- - xbmc/windowing/WinEventsX11.h | 2 - - 2 files changed, 11 insertions(+), 110 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index d86205d..76702e6 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -32,6 +32,7 @@ - #include "X11/keysymdef.h" - #include "X11/XF86keysym.h" - #include "utils/log.h" -+#include "utils/CharsetConverter.h" - #include "guilib/GUIWindowManager.h" - #include "input/MouseStat.h" - -@@ -161,7 +162,6 @@ - m_display = 0; - m_window = 0; - m_keybuf = 0; -- m_utf16buf = 0; - } - - CWinEventsX11::~CWinEventsX11() -@@ -172,12 +172,6 @@ - m_keybuf = 0; - } - -- if (m_utf16buf) -- { -- free(m_utf16buf); -- m_utf16buf = 0; -- } -- - if (m_xic) - { - XUnsetICFocus(m_xic); -@@ -203,7 +197,6 @@ bool CWinEventsX11::Init(Display *dpy, Window win) - WinEvents->m_display = dpy; - WinEvents->m_window = win; - WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -- WinEvents->m_utf16buf = (uint16_t*)malloc(32*sizeof(uint16_t)); - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -@@ -433,8 +426,6 @@ bool CWinEventsX11::MessagePump() - } - - Status status; -- int utf16size; -- int utf16length; - int len; - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, - WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -@@ -453,36 +444,29 @@ bool CWinEventsX11::MessagePump() - case XLookupChars: - case XLookupBoth: - { -- if (len == 0) -- break; -- utf16size = len * sizeof(uint16_t); -- if (utf16size > sizeof(WinEvents->m_utf16buf)) -- { -- WinEvents->m_utf16buf = (uint16_t *)realloc(WinEvents->m_utf16buf,utf16size); -- if (WinEvents->m_utf16buf == NULL) -- { -- break; -- } -- } -- utf16length = Utf8ToUnicode(WinEvents->m_keybuf, len, WinEvents->m_utf16buf, utf16size); -- if (utf16length < 0) -+ CStdString data(WinEvents->m_keybuf, len); -+ CStdStringW keys; -+ g_charsetConverter.utf8ToW(data, keys, false); -+ -+ if (keys.length() == 0) - { - break; - } -- for (unsigned int i = 0; i < utf16length - 1; i++) -+ -+ for (unsigned int i = 0; i < keys.length() - 1; i++) - { - newEvent.key.keysym.sym = XBMCK_UNKNOWN; -- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[i]; -+ newEvent.key.keysym.unicode = keys[i]; - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; - ret |= ProcessKey(newEvent, 500); - } -- if (utf16length > 0) -+ if (keys.length() > 0) - { - newEvent.key.keysym.scancode = xevent.xkey.keycode; - xkeysym = XLookupKeysym(&xevent.xkey, 0); - newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); -- newEvent.key.keysym.unicode = WinEvents->m_utf16buf[utf16length - 1]; -+ newEvent.key.keysym.unicode = keys[keys.length() - 1]; - newEvent.key.state = xevent.xkey.state; - newEvent.key.type = xevent.xkey.type; - -@@ -743,87 +727,6 @@ bool CWinEventsX11::ProcessKeyRepeat() - return false; - } - --int CWinEventsX11::Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength) --{ -- // p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. -- uint16_t *p = utf16; -- uint16_t const *const maxPtr = utf16 + utf16MaxLength; -- -- // end_of_input points to the last byte of input as opposed to the next to the last byte. -- char const *const endOfInput = utf8 + utf8Length - 1; -- -- while (utf8 <= endOfInput) -- { -- unsigned char const c = *utf8; -- if (p >= maxPtr) -- { -- //No more output space. -- return -1; -- } -- if (c < 0x80) -- { -- //One byte ASCII. -- *p++ = c; -- utf8 += 1; -- } -- else if (c < 0xC0) -- { -- // Follower byte without preceding leader bytes. -- return -1; -- } -- // 11 bits -- else if (c < 0xE0) -- { -- // Two byte sequence. We need one follower byte. -- if (endOfInput - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) -- { -- return -1; -- } -- *p++ = (uint16_t)(((c & 0x1F) << 6) + (utf8[1] & 0x3F)); -- utf8 += 2; -- } -- // 16 bis -- else if (c < 0xF0) -- { -- // Three byte sequence. We need two follower byte. -- if (endOfInput - utf8 < 2 || ((utf8[1] ^ 0x80) & 0xC0) || ((utf8[2] ^ 0x80) & 0xC0)) -- { -- return -1; -- } -- *p++ = (uint16_t)(((c & 0xF) << 12) + ((utf8[1] & 0x3F) << 6) + (utf8[2] & 0x3F)); -- utf8 += 3; -- } -- // 21 bits -- else if (c < 0xF8) -- { -- int plane; -- // Four byte sequence. We need three follower bytes. -- if (endOfInput - utf8 < 3 || ((utf8[1] ^ 0x80) & 0xC0) || -- ((utf8[2] ^ 0x80) & 0xC0) || ((utf8[3] ^ 0x80) & 0xC0)) -- { -- return -1; -- } -- uint32_t unicode = ((c & 0x7) << 18) + ((utf8[1] & 0x3F) << 12) + -- ((utf8[2] & 0x3F) << 6) + (utf8[3] & 0x3F); -- utf8 += 4; -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- } -- // 26 bits -- else if (c < 0xFC) -- { -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- utf8 += 5; -- } -- // 31 bit -- else -- { -- CLog::Log(LOGERROR, "CWinEventsX11::Utf8ToUnicode: 4 byte unicode not supported"); -- utf8 += 6; -- } -- } -- return p - utf16; --} -- - XBMCKey CWinEventsX11::LookupXbmcKeySym(KeySym keysym) - { - // try direct mapping first -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 6100933..72955ad 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -38,7 +38,6 @@ class CWinEventsX11 : public CWinEventsBase - static bool MessagePump(); - - protected: -- static int Utf8ToUnicode(const char *utf8, const int utf8Length, uint16_t *utf16, const int utf16MaxLength); - static XBMCKey LookupXbmcKeySym(KeySym keysym); - static bool ProcessKey(XBMC_Event &event, int repeatDelay); - static bool ProcessKeyRepeat(); -@@ -48,7 +47,6 @@ class CWinEventsX11 : public CWinEventsBase - Window m_window; - Atom m_wmDeleteMessage; - char *m_keybuf; -- uint16_t *m_utf16buf; - XIM m_xim; - XIC m_xic; - XBMC_Event m_lastKey; --- -1.7.10 - - -From c93af676cf85551e3f4325808d17098da3bc6811 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 53/88] X11: fixed invalid usage of sizeof() (squash into x11 - changes) - ---- - xbmc/windowing/WinEventsX11.cpp | 11 +++++++---- - xbmc/windowing/WinEventsX11.h | 1 + - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index 76702e6..c31877e 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -162,6 +162,7 @@ - m_display = 0; - m_window = 0; - m_keybuf = 0; -+ m_keybuf_len = 0; - } - - CWinEventsX11::~CWinEventsX11() -@@ -196,7 +197,8 @@ bool CWinEventsX11::Init(Display *dpy, Window win) - WinEvents = new CWinEventsX11(); - WinEvents->m_display = dpy; - WinEvents->m_window = win; -- WinEvents->m_keybuf = (char*)malloc(32*sizeof(char)); -+ WinEvents->m_keybuf_len = 32*sizeof(char); -+ WinEvents->m_keybuf = (char*)malloc(WinEvents->m_keybuf_len); - WinEvents->m_keymodState = 0; - WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - WinEvents->m_structureChanged = false; -@@ -428,13 +430,14 @@ bool CWinEventsX11::MessagePump() - Status status; - int len; - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ WinEvents->m_keybuf, WinEvents->m_keybuf_len, - &xkeysym, &status); - if (status == XBufferOverflow) - { -- WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, len*sizeof(char)); -+ WinEvents->m_keybuf_len = len; -+ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, WinEvents->m_keybuf_len); - len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, -- WinEvents->m_keybuf, sizeof(WinEvents->m_keybuf), -+ WinEvents->m_keybuf, WinEvents->m_keybuf_len, - &xkeysym, &status); - } - switch (status) -diff --git a/xbmc/windowing/WinEventsX11.h b/xbmc/windowing/WinEventsX11.h -index 72955ad..102a076 100644 ---- a/xbmc/windowing/WinEventsX11.h -+++ b/xbmc/windowing/WinEventsX11.h -@@ -47,6 +47,7 @@ class CWinEventsX11 : public CWinEventsBase - Window m_window; - Atom m_wmDeleteMessage; - char *m_keybuf; -+ size_t m_keybuf_len; - XIM m_xim; - XIC m_xic; - XBMC_Event m_lastKey; --- -1.7.10 - - -From 04106be4cdf381658ae92bf20bc468ccad12fb31 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 54/88] add missing keys to xbmc keytable - ---- - xbmc/input/XBMC_keytable.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/input/XBMC_keytable.cpp b/xbmc/input/XBMC_keytable.cpp -index aaf65ba..9d7922f 100644 ---- a/xbmc/input/XBMC_keytable.cpp -+++ b/xbmc/input/XBMC_keytable.cpp -@@ -179,6 +179,8 @@ - , { XBMCK_LAUNCH_APP2, 0, 0, XBMCVK_LAUNCH_APP2, "launch_app2_pc_icon" } - , { XBMCK_LAUNCH_FILE_BROWSER, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER, "launch_file_browser" } - , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } -+, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } -+, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } - - // Function keys - , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} --- -1.7.10 - - -From fb35e45063cf476573ad09c3bed7459164d03066 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 55/88] videorefclock: temp deactivate of nv settings - ---- - xbmc/video/VideoReferenceClock.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index fa8e35a..85e36c7 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -135,7 +135,7 @@ - m_Context = NULL; - m_pixmap = None; - m_glPixmap = None; -- m_UseNvSettings = true; -+ m_UseNvSettings = false; - m_bIsATI = false; - #endif - } --- -1.7.10 - - -From 5e10bc67e7b0dffbbf9b7d8242fb78e8cef2403f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 56/88] videorefclock: ask graphics context for refresh rate - ---- - xbmc/video/VideoReferenceClock.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp -index 85e36c7..8209163 100644 ---- a/xbmc/video/VideoReferenceClock.cpp -+++ b/xbmc/video/VideoReferenceClock.cpp -@@ -30,6 +30,7 @@ - #include - #include - #include "windowing/WindowingFactory.h" -+ #include "guilib/GraphicContext.h" - #define NVSETTINGSCMD "nvidia-settings -nt -q RefreshRate3" - #elif defined(TARGET_DARWIN_OSX) - #include -@@ -1254,7 +1255,7 @@ bool CVideoReferenceClock::UpdateRefreshrate(bool Forced /*= false*/) - } - - CSingleLock SingleLock(m_CritSection); -- m_RefreshRate = GetRandRRate(); -+ m_RefreshRate = MathUtils::round_int(g_graphicsContext.GetFPS()); - - CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", (int)m_RefreshRate); - --- -1.7.10 - - -From aed9e87986eb99f21a7cafc6a356a4044b41becc Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 57/88] X11: fix icon texture after - cc5ed3c2474084ebc0373a3046410e6f766e03f4 - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 43 +++++++++++++++++++++-------------- - 1 file changed, 26 insertions(+), 17 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 91f92c1..174ccef 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -874,22 +874,24 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - if (!fullscreen) - { - CreateIconPixmap(); -- XWMHints wm_hints; -- XClassHint class_hints; -+ XWMHints *wm_hints; - XTextProperty windowName, iconName; - std::string titleString = "XBMC Media Center"; - char *title = (char*)titleString.c_str(); - - XStringListToTextProperty(&title, 1, &windowName); - XStringListToTextProperty(&title, 1, &iconName); -- wm_hints.initial_state = NormalState; -- wm_hints.input = True; -- wm_hints.icon_pixmap = m_icon; -- wm_hints.flags = StateHint | IconPixmapHint | InputHint; - -+ wm_hints = XAllocWMHints(); -+ wm_hints->initial_state = NormalState; -+ wm_hints->icon_pixmap = m_icon; -+ wm_hints->flags = StateHint | IconPixmapHint; -+ -+ XSync(m_dpy,False); - XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, -- NULL, 0, NULL, &wm_hints, -+ NULL, 0, NULL, wm_hints, - NULL); -+ XFree(wm_hints); - - // register interest in the delete window message - Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); -@@ -974,16 +976,21 @@ bool CWinSystemX11::CreateIconPixmap() - gRatio = vis->green_mask / 255.0; - bRatio = vis->blue_mask / 255.0; - -- CTexture iconTexture; -- iconTexture.LoadFromFile("special://xbmc/media/icon.png"); -- buf = iconTexture.GetPixels(); -+ CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon.png"); -+ -+ if (!iconTexture) -+ return false; - -- numBufBytes = iconTexture.GetWidth() * iconTexture.GetHeight() * 4; -+ buf = iconTexture->GetPixels(); -+ -+ numBufBytes = iconTexture->GetWidth() * iconTexture->GetHeight() * 4; -+ int wid = iconTexture->GetWidth(); -+ int hi = iconTexture->GetHeight(); - - if (depth>=24) -- numNewBufBytes = (4 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight())); - else -- numNewBufBytes = (2 * (iconTexture.GetWidth() * iconTexture.GetHeight())); -+ numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight())); - - newBuf = (uint32_t*)malloc(numNewBufBytes); - if (!newBuf) -@@ -992,11 +999,11 @@ bool CWinSystemX11::CreateIconPixmap() - return false; - } - -- for (i=0; iGetHeight();++i) - { -- for (j=0; jGetWidth();++j) - { -- unsigned int pos = i*iconTexture.GetPitch()+j*4; -+ unsigned int pos = i*iconTexture->GetPitch()+j*4; - unsigned int r, g, b; - r = (buf[pos+2] * rRatio); - g = (buf[pos+1] * gRatio); -@@ -1009,7 +1016,7 @@ bool CWinSystemX11::CreateIconPixmap() - } - } - img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, -- iconTexture.GetWidth(), iconTexture.GetHeight(), -+ iconTexture->GetWidth(), iconTexture->GetHeight(), - (depth>=24)?32:16, 0); - if (!img) - { -@@ -1047,6 +1054,8 @@ bool CWinSystemX11::CreateIconPixmap() - XFreeGC(m_dpy, gc); - XDestroyImage(img); // this also frees newBuf - -+ delete iconTexture; -+ - return true; - } - --- -1.7.10 - - -From 7c4464b9114e5eba42c1cc1fce0cfe750ec44eba Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 58/88] X11: check for window manager - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 2 files changed, 73 insertions(+), 2 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 174ccef..4f1ae26 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -816,8 +816,10 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - -+ bool hasWM = HasWindowManager(); -+ - int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); -- swa.override_redirect = False; -+ swa.override_redirect = hasWM ? False : True; - swa.border_pixel = fullscreen ? 0 : 5; - swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; - swa.colormap = cmap; -@@ -833,7 +835,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - InputOutput, vi->visual, - mask, &swa); - -- if (fullscreen) -+ if (fullscreen && hasWM) - { - Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); - XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); -@@ -1059,4 +1061,72 @@ bool CWinSystemX11::CreateIconPixmap() - return true; - } - -+bool CWinSystemX11::HasWindowManager() -+{ -+ Window wm_check; -+ unsigned char *data; -+ int status, real_format; -+ Atom real_type, prop; -+ unsigned long items_read, items_left, i; -+ char req = 0; -+ -+ prop = XInternAtom(m_dpy, "_NET_SUPPORTING_WM_CHECK", True); -+ if (prop == None) -+ return false; -+ status = XGetWindowProperty(m_dpy, DefaultRootWindow(m_dpy), prop, -+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ if(status != Success || ! items_read) -+ { -+ if(status == Success) -+ XFree(data); -+ return false; -+ } -+ -+ wm_check = ((Window*)data)[0]; -+ XFree(data); -+ -+ status = XGetWindowProperty(m_dpy, wm_check, prop, -+ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ -+ if(status != Success || !items_read) -+ { -+ if(status == Success) -+ XFree(data); -+ return false; -+ } -+ -+ if(wm_check != ((Window*)data)[0]) -+ { -+ XFree(data); -+ return false; -+ } -+ -+ XFree(data); -+ -+ prop = XInternAtom(m_dpy, "_NET_WM_NAME", True); -+ if (prop == None) -+ { -+ CLog::Log(LOGDEBUG,"Window Manager Name: "); -+ return true; -+ } -+ -+ status = XGetWindowProperty(m_dpy, wm_check, prop, -+ 0L, (~0L), False, AnyPropertyType, &real_type, &real_format, -+ &items_read, &items_left, &data); -+ -+ if(status == Success && items_read) -+ { -+ CLog::Log(LOGDEBUG,"Window Manager Name: %s", data); -+ } -+ else -+ CLog::Log(LOGDEBUG,"Window Manager Name: "); -+ -+ if(status == Success) -+ XFree(data); -+ -+ return true; -+} -+ - #endif -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index e953d2d..0b7c10a 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -101,6 +101,7 @@ class CWinSystemX11 : public CWinSystemBase - bool IsSuitableVisual(XVisualInfo *vInfo); - static int XErrorHandler(Display* dpy, XErrorEvent* error); - bool CreateIconPixmap(); -+ bool HasWindowManager(); - - CStopWatch m_screensaverReset; - }; --- -1.7.10 - - -From d156746c8968312db2a60fbcbcbb48029ff0d60a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 59/88] X11: dont set window on xrandr if no mode available - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 4f1ae26..c11ea89 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -665,16 +665,17 @@ void CWinSystemX11::NotifyXRREvent() - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); - m_windowDirty = true; - -+ if (!g_xrandr.Query(true)) -+ { -+ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -+ return; -+ } -+ - // if external event update resolutions - if (!m_bIsInternalXrr) - { - UpdateResolutions(); - } -- else if (!g_xrandr.Query(true)) -- { -- CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); -- return; -- } - m_bIsInternalXrr = false; - - CStdString currentOutput = g_guiSettings.GetString("videoscreen.monitor"); --- -1.7.10 - - -From 7da277793b15d9cbd5dcaf27dc7fee2fb3dde945 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 60/88] X11: fix crash after a resolution change on startup - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index c11ea89..0bd72d4 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -219,7 +219,8 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl - OnLostDevice(); - m_bIsInternalXrr = true; - g_xrandr.SetMode(out, mode); -- return true; -+ if (m_glWindow) -+ return true; - } - #endif - --- -1.7.10 - - -From 31d401e7052f2e3d03e4c78bccc05909d870e5a6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 61/88] X11: lock graphics context in NotifyXRREvent - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 0bd72d4..ef83133 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -666,6 +666,8 @@ void CWinSystemX11::NotifyXRREvent() - CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); - m_windowDirty = true; - -+ CSingleLock lock(g_graphicsContext); -+ - if (!g_xrandr.Query(true)) - { - CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); --- -1.7.10 - - -From b2cd5ea5e38446dc54b73cf2f6a82072add474f1 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 8 Oct 2011 16:45:13 +0200 -Subject: [PATCH 62/88] ffmpeg: add xvba hwaccel - ---- - lib/ffmpeg/configure | 8 ++ - lib/ffmpeg/libavcodec/Makefile | 7 +- - lib/ffmpeg/libavcodec/allcodecs.c | 4 + - lib/ffmpeg/libavcodec/h264.c | 1 + - lib/ffmpeg/libavcodec/mpegvideo.c | 1 + - lib/ffmpeg/libavcodec/xvba.c | 66 +++++++++++ - lib/ffmpeg/libavcodec/xvba.h | 71 ++++++++++++ - lib/ffmpeg/libavcodec/xvba_h264.c | 195 +++++++++++++++++++++++++++++++++ - lib/ffmpeg/libavcodec/xvba_internal.h | 24 ++++ - lib/ffmpeg/libavcodec/xvba_mpeg2.c | 52 +++++++++ - lib/ffmpeg/libavcodec/xvba_vc1.c | 190 ++++++++++++++++++++++++++++++++ - lib/ffmpeg/libavcodec/xvmc_internal.h | 4 +- - lib/ffmpeg/libavutil/pixdesc.c | 6 + - lib/ffmpeg/libavutil/pixfmt.h | 1 + - 14 files changed, 628 insertions(+), 2 deletions(-) - create mode 100644 lib/ffmpeg/libavcodec/xvba.c - create mode 100644 lib/ffmpeg/libavcodec/xvba.h - create mode 100644 lib/ffmpeg/libavcodec/xvba_h264.c - create mode 100644 lib/ffmpeg/libavcodec/xvba_internal.h - create mode 100644 lib/ffmpeg/libavcodec/xvba_mpeg2.c - create mode 100644 lib/ffmpeg/libavcodec/xvba_vc1.c - -diff --git a/lib/ffmpeg/configure b/lib/ffmpeg/configure -index c06005b..157cfd3 100755 ---- a/lib/ffmpeg/configure -+++ b/lib/ffmpeg/configure -@@ -113,6 +113,7 @@ Configuration options: - --enable-vdpau enable VDPAU code [autodetect] - --disable-dxva2 disable DXVA2 code - --disable-vda disable VDA code -+ --disable-xvba disable XVBA code - --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary) - --enable-hardcoded-tables use hardcoded tables instead of runtime generation - --disable-safe-bitstream-reader -@@ -1084,6 +1085,7 @@ CONFIG_LIST=" - vaapi - vda - vdpau -+ xvba - version3 - x11grab - zlib -@@ -1423,6 +1425,7 @@ h264_dxva2_hwaccel_select="dxva2 h264_decoder" - h264_vaapi_hwaccel_select="vaapi h264_decoder" - h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" - h264_vda_hwaccel_select="vda h264_decoder" -+h264_xvba_hwaccel_select="xvba h264_decoder" - h264_vdpau_decoder_select="vdpau h264_decoder" - imc_decoder_select="fft mdct sinewin" - jpegls_decoder_select="golomb" -@@ -1459,6 +1462,7 @@ mpeg4_crystalhd_decoder_select="crystalhd" - mpeg4_decoder_select="h263_decoder mpeg4video_parser" - mpeg4_encoder_select="h263_encoder" - mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" -+mpeg2_xvba_hwaccel_select="xvba mpeg2video_decoder" - mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" - msmpeg4_crystalhd_decoder_select="crystalhd" - msmpeg4v1_decoder_select="h263_decoder" -@@ -1501,6 +1505,7 @@ vc1_decoder_select="h263_decoder h264chroma" - vc1_dxva2_hwaccel_deps="dxva2api_h" - vc1_dxva2_hwaccel_select="dxva2 vc1_decoder" - vc1_vaapi_hwaccel_select="vaapi vc1_decoder" -+vc1_xvba_hwaccel_select="xvba vc1_decoder" - vc1_vdpau_decoder_select="vdpau vc1_decoder" - vc1image_decoder_select="vc1_decoder" - vorbis_decoder_select="mdct" -@@ -1525,6 +1530,7 @@ wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" - wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" - wmv3_vdpau_decoder_select="vc1_vdpau_decoder" - wmv3image_decoder_select="wmv3_decoder" -+wmv3_xvba_hwaccel_select="vc1_xvba_hwaccel" - zlib_decoder_select="zlib" - zlib_encoder_select="zlib" - zmbv_decoder_select="zlib" -@@ -1533,6 +1539,7 @@ zmbv_encoder_select="zlib" - crystalhd_deps="libcrystalhd_libcrystalhd_if_h" - vaapi_deps="va_va_h" - vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" -+xvba_deps="amd_amdxvba_h" - vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" - - # parsers -@@ -3062,6 +3069,7 @@ check_header sys/select.h - check_header termios.h - check_header vdpau/vdpau.h - check_header vdpau/vdpau_x11.h -+check_header amd/amdxvba.h - check_cpp_condition vdpau/vdpau.h "defined(VDP_DECODER_PROFILE_MPEG4_PART2_SP)" && enable vdpau_mpeg4_support - - check_header X11/extensions/XvMClib.h -diff --git a/lib/ffmpeg/libavcodec/Makefile b/lib/ffmpeg/libavcodec/Makefile -index 972cc59..fc441bf 100644 ---- a/lib/ffmpeg/libavcodec/Makefile -+++ b/lib/ffmpeg/libavcodec/Makefile -@@ -3,7 +3,7 @@ include $(SUBDIR)../config.mak - NAME = avcodec - FFLIBS = avutil - --HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h -+HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h xvba.h - - OBJS = allcodecs.o \ - audioconvert.o \ -@@ -51,6 +51,7 @@ OBJS-$(CONFIG_SINEWIN) += sinewin.o - OBJS-$(CONFIG_VAAPI) += vaapi.o - OBJS-$(CONFIG_VDA) += vda.o - OBJS-$(CONFIG_VDPAU) += vdpau.o -+OBJS-$(CONFIG_XVBA) += xvba.o - - # decoders/encoders/hardware accelerators - OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o -@@ -201,6 +202,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \ - OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o - OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o - OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o -+OBJS-$(CONFIG_H264_XVBA_HWACCEL) += xvba_h264.o - OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o - OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o - OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o -@@ -284,6 +286,7 @@ OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ - mpegvideo.o error_resilience.o - OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o - OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o -+OBJS-$(CONFIG_MPEG2_XVBA_HWACCEL) += xvba_mpeg2.o - OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o - OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ -@@ -431,6 +434,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ - intrax8.o intrax8dsp.o - OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o - OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o -+OBJS-$(CONFIG_VC1_XVBA_HWACCEL) += xvba_vc1.o - OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o - OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o - OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o -@@ -732,6 +736,7 @@ SKIPHEADERS-$(CONFIG_LIBDIRAC) += libdirac.h - SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h - SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h - SKIPHEADERS-$(CONFIG_VDA) += vda_internal.h -+SKIPHEADERS-$(CONFIG_XVBA) += xvba_internal.h - SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h - SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h - SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h -diff --git a/lib/ffmpeg/libavcodec/allcodecs.c b/lib/ffmpeg/libavcodec/allcodecs.c -index 32f3f52..0ff178e 100644 ---- a/lib/ffmpeg/libavcodec/allcodecs.c -+++ b/lib/ffmpeg/libavcodec/allcodecs.c -@@ -59,14 +59,18 @@ void avcodec_register_all(void) - REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); - REGISTER_HWACCEL (H264_VDA, h264_vda); - REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); -+ REGISTER_HWACCEL (H264_XVBA, h264_xvba); - REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); - REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); - REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); - REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); -+ REGISTER_HWACCEL (MPEG2_XVBA, mpeg2_xvba); - REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); - REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); -+ REGISTER_HWACCEL (VC1_XVBA, vc1_xvba); - REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2); - REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi); -+ REGISTER_HWACCEL (WMV3_XVBA, wmv3_xvba); - - /* video codecs */ - REGISTER_ENCODER (A64MULTI, a64multi); -diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c -index c4785db..e9e7546 100644 ---- a/lib/ffmpeg/libavcodec/h264.c -+++ b/lib/ffmpeg/libavcodec/h264.c -@@ -60,6 +60,7 @@ - PIX_FMT_DXVA2_VLD, - PIX_FMT_VAAPI_VLD, - PIX_FMT_VDA_VLD, -+ PIX_FMT_XVBA_VLD, - PIX_FMT_YUVJ420P, - PIX_FMT_NONE - }; -diff --git a/lib/ffmpeg/libavcodec/mpegvideo.c b/lib/ffmpeg/libavcodec/mpegvideo.c -index 04c149a..b22b631 100644 ---- a/lib/ffmpeg/libavcodec/mpegvideo.c -+++ b/lib/ffmpeg/libavcodec/mpegvideo.c -@@ -136,6 +136,7 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s, - PIX_FMT_DXVA2_VLD, - PIX_FMT_VAAPI_VLD, - PIX_FMT_VDA_VLD, -+ PIX_FMT_XVBA_VLD, - PIX_FMT_YUV420P, - PIX_FMT_NONE - }; -diff --git a/lib/ffmpeg/libavcodec/xvba.c b/lib/ffmpeg/libavcodec/xvba.c -new file mode 100644 -index 0000000..be29e5d ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba.c -@@ -0,0 +1,66 @@ -+/* -+ * HW decode acceleration for MPEG-2, H.264 and VC-1 -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+ -+/** -+ * \addtogroup XVBA_Decoding -+ * -+ * @{ -+ */ -+ -+#include -+#include "xvba.h" -+#include "xvba_internal.h" -+#include "avcodec.h" -+ -+int ff_xvba_translate_profile(int profile) { -+ -+ if (profile == 66) -+ return 1; -+ else if (profile == 77) -+ return 2; -+ else if (profile == 100) -+ return 3; -+ else if (profile == 0) -+ return 4; -+ else if (profile == 1) -+ return 5; -+ else if (profile == 3) -+ return 6; -+ else -+ return -1; -+} -+ -+void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size) { -+ -+ render->buffers = av_fast_realloc( -+ render->buffers, -+ &render->buffers_alllocated, -+ sizeof(struct xvba_bitstream_buffers)*(render->num_slices + 1) -+ ); -+ -+ render->buffers[render->num_slices].buffer = buffer; -+ render->buffers[render->num_slices].size = size; -+ -+ render->num_slices++; -+} -+ -diff --git a/lib/ffmpeg/libavcodec/xvba.h b/lib/ffmpeg/libavcodec/xvba.h -new file mode 100644 -index 0000000..9f9ff0c ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba.h -@@ -0,0 +1,71 @@ -+/* -+ * HW decode acceleration for MPEG-2, H.264 and VC-1 -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_XVBA_H -+#define AVCODEC_XVBA_H -+ -+#include -+#include -+#include -+ -+ -+/** -+ * \defgroup XVBA_Decoding VA API Decoding -+ * \ingroup Decoder -+ * @{ -+ */ -+ -+/** \brief The videoSurface is used for rendering. */ -+#define FF_XVBA_STATE_USED_FOR_RENDER 1 -+ -+/** -+ * \brief The videoSurface is needed for reference/prediction. -+ * The codec manipulates this. -+ */ -+#define FF_XVBA_STATE_USED_FOR_REFERENCE 2 -+ -+/** -+ * \brief The videoSurface holds a decoded frame. -+ * The codec manipulates this. -+ */ -+#define FF_XVBA_STATE_DECODED 4 -+ -+/* @} */ -+ -+struct xvba_bitstream_buffers -+{ -+ const void *buffer; -+ unsigned int size; -+}; -+ -+struct xvba_render_state { -+ -+ int state; ///< Holds FF_XVBA_STATE_* values. -+ void *surface; -+ XVBAPictureDescriptor *picture_descriptor; -+ XVBAQuantMatrixAvc *iq_matrix; -+ unsigned int num_slices; -+ struct xvba_bitstream_buffers *buffers; -+ uint32_t buffers_alllocated; -+}; -+ -+#endif /* AVCODEC_XVBA_H */ -diff --git a/lib/ffmpeg/libavcodec/xvba_h264.c b/lib/ffmpeg/libavcodec/xvba_h264.c -new file mode 100644 -index 0000000..87af687 ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba_h264.c -@@ -0,0 +1,195 @@ -+/* -+ * H.264 HW decode acceleration through XVBA -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "xvba.h" -+#include "xvba_internal.h" -+#include "h264.h" -+#include -+ -+/** @file -+ * This file implements the glue code between FFmpeg's and XvBA API's -+ * structures for H.264 decoding. -+ */ -+ -+ -+/** Initialize and start decoding a frame with XVBA. */ -+static int start_frame(AVCodecContext *avctx, -+ av_unused const uint8_t *buffer, -+ av_unused uint32_t size) -+{ -+ H264Context * const h = avctx->priv_data; -+ MpegEncContext * const s = &h->s; -+ struct xvba_render_state *render; -+ XVBAPictureDescriptor *pic_descriptor; -+ int i; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ if (render->picture_descriptor == 0) -+ return -1; -+ -+ pic_descriptor = render->picture_descriptor; -+ -+ for (i = 0; i < 2; ++i) { -+ int foc = s->current_picture_ptr->field_poc[i]; -+ if (foc == INT_MAX) -+ foc = 0; -+ pic_descriptor->avc_curr_field_order_cnt_list[i] = foc; -+ } -+ -+ pic_descriptor->avc_frame_num = h->frame_num; -+ -+ render->num_slices = 0; -+ -+ return 0; -+} -+ -+/** End a hardware decoding based frame. */ -+static int end_frame(AVCodecContext *avctx) -+{ -+ H264Context * const h = avctx->priv_data; -+ MpegEncContext * const s = &h->s; -+ struct xvba_render_state *render; -+ XVBAPictureDescriptor *pic_descriptor; -+ XVBAQuantMatrixAvc *iq_matrix; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ if (render->picture_descriptor == 0 || render->iq_matrix == 0) -+ return -1; -+ -+ pic_descriptor = render->picture_descriptor; -+ iq_matrix = render->iq_matrix; -+ -+ av_dlog(avctx, "end_frame()\n"); -+ -+ /* Fill in Picture Parameters*/ -+ pic_descriptor->profile = ff_xvba_translate_profile(avctx->profile); -+ pic_descriptor->level = avctx->level; -+ pic_descriptor->width_in_mb = s->mb_width; -+ pic_descriptor->height_in_mb = s->mb_height; -+ pic_descriptor->picture_structure = s->picture_structure; -+ pic_descriptor->chroma_format = s->chroma_format ? s->chroma_format : 1; -+ pic_descriptor->avc_intra_flag = (h->slice_type == AV_PICTURE_TYPE_I) ? 1 : 0; -+ pic_descriptor->avc_reference = (s->current_picture_ptr->f.reference & 3) ? 1 : 0; -+ -+ pic_descriptor->avc_bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; -+ pic_descriptor->avc_bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; -+ pic_descriptor->avc_log2_max_frame_num_minus4 = h->sps.log2_max_frame_num -4; -+ pic_descriptor->avc_pic_order_cnt_type = h->sps.poc_type; -+ pic_descriptor->avc_log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4; -+ pic_descriptor->avc_num_ref_frames = h->sps.ref_frame_count; -+ pic_descriptor->avc_reserved_8bit = 0; -+ -+ /* Set a level that can decode stuff in every case without a lookup table -+ xvba seems to have problems only when the number of Reframes goes beyond -+ the max support number of Level4.1@High. So in praxis decoding a Level 3.0 -+ file that in deed has level4.1@High specs does not matter. We use this fact -+ and check if the ref_frames stay in the range Level4.1@high can decode if -+ not, we set Level5.1 */ -+ if (pic_descriptor->avc_num_ref_frames > 4) { -+ const unsigned int mbw = pic_descriptor->width_in_mb; -+ const unsigned int mbh = pic_descriptor->height_in_mb; -+ // this matches Level4.1@High stats to differ between <= 4.1 and 5.1 -+ const unsigned int max_ref_frames = 12288 * 1024 / (mbw * mbh * 384); -+ const unsigned int num_ref_frames = pic_descriptor->avc_num_ref_frames; -+ if (max_ref_frames < num_ref_frames) -+ pic_descriptor->level = 51; -+ } -+ -+ pic_descriptor->avc_num_slice_groups_minus1 = h->pps.slice_group_count - 1; -+ pic_descriptor->avc_num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1; -+ pic_descriptor->avc_num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1; -+ -+ pic_descriptor->avc_pic_init_qp_minus26 = h->pps.init_qp - 26; -+ pic_descriptor->avc_pic_init_qs_minus26 = h->pps.init_qs - 26; -+ pic_descriptor->avc_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; -+ pic_descriptor->avc_second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; -+ pic_descriptor->avc_slice_group_change_rate_minus1 = 0; // not implemented in ffmpeg -+ pic_descriptor->avc_reserved_16bit = 0; // must be 0 -+ memset(pic_descriptor->avc_field_order_cnt_list,0,sizeof(pic_descriptor->avc_field_order_cnt_list)); // must be 0 -+ memset(pic_descriptor->avc_slice_group_map,0,sizeof(pic_descriptor->avc_slice_group_map)); // must be 0 -+ -+ // sps -+ pic_descriptor->sps_info.avc.delta_pic_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; -+ pic_descriptor->sps_info.avc.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; -+ pic_descriptor->sps_info.avc.frame_mbs_only_flag = h->sps.frame_mbs_only_flag; -+ pic_descriptor->sps_info.avc.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag; -+ pic_descriptor->sps_info.avc.mb_adaptive_frame_field_flag = h->sps.mb_aff; -+ pic_descriptor->sps_info.avc.residual_colour_transform_flag = h->sps.residual_color_transform_flag; -+ pic_descriptor->sps_info.avc.xvba_avc_sps_reserved = 0; -+ -+ // pps -+ pic_descriptor->pps_info.avc.entropy_coding_mode_flag = h->pps.cabac; -+ pic_descriptor->pps_info.avc.pic_order_present_flag = h->pps.pic_order_present; -+ pic_descriptor->pps_info.avc.weighted_pred_flag = h->pps.weighted_pred; -+ pic_descriptor->pps_info.avc.weighted_bipred_idc = h->pps.weighted_bipred_idc; -+ pic_descriptor->pps_info.avc.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; -+ pic_descriptor->pps_info.avc.constrained_intra_pred_flag = h->pps.constrained_intra_pred; -+ pic_descriptor->pps_info.avc.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; -+ pic_descriptor->pps_info.avc.transform_8x8_mode_flag = h->pps.transform_8x8_mode; -+ pic_descriptor->pps_info.avc.xvba_avc_pps_reserved = 0; // must be 0 -+ -+ memcpy(iq_matrix->bScalingLists4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->bScalingLists4x4)); -+ memcpy(iq_matrix->bScalingLists8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->bScalingLists8x8[0])); -+ memcpy(iq_matrix->bScalingLists8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->bScalingLists8x8[0])); -+ -+ // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs -+ if (!h->got_first_iframe) { -+ if (h->slice_type != AV_PICTURE_TYPE_I && h->slice_type != AV_PICTURE_TYPE_SI) -+ return -1; -+ h->got_first_iframe = 1; -+ } -+ -+ ff_draw_horiz_band(s, 0, s->avctx->height); -+ -+ return 0; -+} -+ -+/** Decode the given H.264 slice with XVBA. */ -+static int decode_slice(AVCodecContext *avctx, -+ const uint8_t *buffer, -+ uint32_t size) -+{ -+ H264Context * const h = avctx->priv_data; -+ MpegEncContext * const s = &h->s; -+ struct xvba_render_state *render; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ ff_xvba_add_slice_data(render, buffer, size); -+ -+ return 0; -+} -+ -+AVHWAccel ff_h264_xvba_hwaccel = { -+ .name = "h264_xvba", -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = CODEC_ID_H264, -+ .pix_fmt = PIX_FMT_XVBA_VLD, -+ .start_frame = start_frame, -+ .end_frame = end_frame, -+ .decode_slice = decode_slice, -+}; -diff --git a/lib/ffmpeg/libavcodec/xvba_internal.h b/lib/ffmpeg/libavcodec/xvba_internal.h -new file mode 100644 -index 0000000..9653f85 ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba_internal.h -@@ -0,0 +1,24 @@ -+/* -+ * HW decode acceleration for MPEG-2, H.264 and VC-1 -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+int ff_xvba_translate_profile(int profile); -+void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size); -diff --git a/lib/ffmpeg/libavcodec/xvba_mpeg2.c b/lib/ffmpeg/libavcodec/xvba_mpeg2.c -new file mode 100644 -index 0000000..552ef95 ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba_mpeg2.c -@@ -0,0 +1,52 @@ -+/* -+ * MPEG-2 HW decode acceleration through XVBA -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "dsputil.h" -+ -+static int start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) -+{ -+ struct MpegEncContext * const s = avctx->priv_data; -+ return 0; -+} -+ -+static int end_frame(AVCodecContext *avctx) -+{ -+ return 0; -+} -+ -+static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) -+{ -+ struct MpegEncContext * const s = avctx->priv_data; -+ return 0; -+} -+ -+AVHWAccel ff_mpeg2_xvba_hwaccel = { -+ .name = "mpeg2_xvba", -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = CODEC_ID_MPEG2VIDEO, -+ .pix_fmt = PIX_FMT_XVBA_VLD, -+ .capabilities = 0, -+ .start_frame = start_frame, -+ .end_frame = end_frame, -+ .decode_slice = decode_slice, -+ .priv_data_size = 0, -+}; -diff --git a/lib/ffmpeg/libavcodec/xvba_vc1.c b/lib/ffmpeg/libavcodec/xvba_vc1.c -new file mode 100644 -index 0000000..7315b62 ---- /dev/null -+++ b/lib/ffmpeg/libavcodec/xvba_vc1.c -@@ -0,0 +1,190 @@ -+/* -+ * VC-1 HW decode acceleration through XVBA -+ * -+ * Copyright (C) 2005-2011 Team XBMC -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "xvba.h" -+#include "xvba_internal.h" -+#include "vc1.h" -+#include "vc1data.h" -+#include -+ -+ -+/** @file -+ * Implement structures of ffmpeg <-> XvBA -+ */ -+ -+/* Initialize and start decoding a frame with XvBA */ -+static int start_frame(AVCodecContext *avctx, -+ av_unused const uint8_t *buffer, -+ av_unused uint32_t size) -+{ -+ VC1Context * const v = avctx->priv_data; -+ MpegEncContext * const s = &v->s; -+ struct xvba_render_state *render; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ render->num_slices = 0; -+ return 0; -+} -+ -+/* End a hardware decoding based frame */ -+static int end_frame(AVCodecContext *avctx) -+{ -+ VC1Context* const v = avctx->priv_data; -+ MpegEncContext* const s = &v->s; -+ struct xvba_render_state *render, *last, *next; -+ XVBAPictureDescriptor *pic_descriptor; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ if (render->picture_descriptor == 0) -+ return -1; -+ -+ pic_descriptor = render->picture_descriptor; -+ -+ av_dlog(avctx, "xvba_vc1_end_frame()\n"); -+ -+ memset(pic_descriptor, 0, sizeof(*pic_descriptor)); -+ -+ /* Fill in Parameters - for reference see AMD sdk documentation */ -+ pic_descriptor->profile = ff_xvba_translate_profile(v->profile); -+ pic_descriptor->level = v->level; -+ //done like in va-driver and vaapi -+ if (v->profile == PROFILE_ADVANCED) { -+ pic_descriptor->width_in_mb = s->avctx->coded_width; -+ pic_descriptor->height_in_mb = s->avctx->coded_height; -+ } else { -+ pic_descriptor->width_in_mb = s->mb_width; -+ pic_descriptor->height_in_mb = s->mb_height; -+ } -+ pic_descriptor->picture_structure = s->picture_structure; -+ // xvba-video set this to 1 only 4:2:0 supported -+ // doc says: if not set, choose 1 - we try this -+ pic_descriptor->chroma_format = 1; -+ pic_descriptor->avc_intra_flag = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type == 1; -+ pic_descriptor->avc_reference = (s->current_picture_ptr->f.reference & 3) ? 1 : 0; -+ -+ // VC-1 explicit parameters see page 30 of sdk -+ // sps_info -+ pic_descriptor->sps_info.vc1.postprocflag = v->postprocflag; -+ -+ // done as in vaapi -+ pic_descriptor->sps_info.vc1.pulldown = v->broadcast; -+ pic_descriptor->sps_info.vc1.interlace = v->interlace; -+ pic_descriptor->sps_info.vc1.tfcntrflag = v->tfcntrflag; -+ pic_descriptor->sps_info.vc1.finterpflag = v->finterpflag; -+ pic_descriptor->sps_info.vc1.reserved = 1; -+ // eventually check if this makes sense together with interlace -+ pic_descriptor->sps_info.vc1.psf = v->psf; -+ // what about if it is a frame (page 31) -+ // looked at xvba-driver -+ pic_descriptor->sps_info.vc1.second_field = !s->first_field; -+ pic_descriptor->sps_info.vc1.xvba_vc1_sps_reserved = 0; -+ -+ // VC-1 explicit parameters see page 30 of sdk -+ // pps_info -+ pic_descriptor->pps_info.vc1.panscan_flag = v->panscanflag; -+ pic_descriptor->pps_info.vc1.refdist_flag = v->refdist_flag; -+ pic_descriptor->pps_info.vc1.loopfilter = s->loop_filter; -+ pic_descriptor->pps_info.vc1.fastuvmc = v->fastuvmc; -+ pic_descriptor->pps_info.vc1.extended_mv = v->extended_mv; -+ pic_descriptor->pps_info.vc1.dquant = v->dquant; -+ pic_descriptor->pps_info.vc1.vstransform = v->vstransform; -+ pic_descriptor->pps_info.vc1.overlap = v->overlap; -+ pic_descriptor->pps_info.vc1.quantizer = v->quantizer_mode; -+ pic_descriptor->pps_info.vc1.extended_dmv = v->extended_dmv; -+ pic_descriptor->pps_info.vc1.maxbframes = s->avctx->max_b_frames; -+ pic_descriptor->pps_info.vc1.rangered = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : v->rangered; -+ pic_descriptor->pps_info.vc1.syncmarker = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : s->resync_marker; -+ pic_descriptor->pps_info.vc1.multires = v->multires; -+ pic_descriptor->pps_info.vc1.reserved = 1; -+ pic_descriptor->pps_info.vc1.range_mapy_flag = v->range_mapy_flag; -+ pic_descriptor->pps_info.vc1.range_mapy = v->range_mapy; -+ pic_descriptor->pps_info.vc1.range_mapuv_flag = v->range_mapuv_flag; -+ pic_descriptor->pps_info.vc1.range_mapuv = v->range_mapuv; -+ pic_descriptor->pps_info.vc1.xvba_vc1_pps_reserved = 0; -+ -+ pic_descriptor->past_surface = 0; -+ pic_descriptor->future_surface = 0; -+ switch (s->pict_type) { -+ case AV_PICTURE_TYPE_B: -+ next = (struct xvba_render_state *)s->next_picture.f.data[0]; -+ assert(next); -+ if (next) -+ pic_descriptor->past_surface = next->surface; -+ // fall-through -+ case AV_PICTURE_TYPE_P: -+ last = (struct xvba_render_state *)s->last_picture.f.data[0]; -+ assert(last); -+ if (last) -+ pic_descriptor->future_surface = last->surface; -+ break; -+ } -+ -+ ff_draw_horiz_band(s, 0, s->avctx->height); -+ -+ return 0; -+} -+ -+static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) -+{ -+ VC1Context* const v = avctx->priv_data; -+ MpegEncContext* const s = &v->s; -+ struct xvba_render_state *render; -+ -+ render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; -+ assert(render); -+ -+ if (avctx->codec_id == CODEC_ID_VC1 && -+ size >= 4 && IS_MARKER(AV_RB32(buffer))) { -+ buffer += 4; -+ size -= 4; -+ } -+ -+ ff_xvba_add_slice_data(render, buffer, size); -+ -+ return 0; -+} -+ -+#if CONFIG_WMV3_XVBA_HWACCEL -+AVHWAccel ff_wmv3_xvba_hwaccel = { -+ .name = "wmv3_xvba", -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = CODEC_ID_WMV3, -+ .pix_fmt = PIX_FMT_XVBA_VLD, -+ .start_frame = start_frame, -+ .end_frame = end_frame, -+ .decode_slice = decode_slice, -+}; -+#endif -+ -+AVHWAccel ff_vc1_xvba_hwaccel = { -+ .name = "vc1_xvba", -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = CODEC_ID_VC1, -+ .pix_fmt = PIX_FMT_XVBA_VLD, -+ .start_frame = start_frame, -+ .end_frame = end_frame, -+ .decode_slice = decode_slice, -+}; -diff --git a/lib/ffmpeg/libavcodec/xvmc_internal.h b/lib/ffmpeg/libavcodec/xvmc_internal.h -index 04197ce..d925eb1 100644 ---- a/lib/ffmpeg/libavcodec/xvmc_internal.h -+++ b/lib/ffmpeg/libavcodec/xvmc_internal.h -@@ -1,5 +1,7 @@ - /* -- * XVideo Motion Compensation internal functions -+ * HW decode acceleration for MPEG-2, H.264 and VC-1 -+ * -+ * Copyright (C) 2005-2011 Team XBMC - * - * This file is part of FFmpeg. - * -diff --git a/lib/ffmpeg/libavutil/pixdesc.c b/lib/ffmpeg/libavutil/pixdesc.c -index e73fbfe..5abbd14 100644 ---- a/lib/ffmpeg/libavutil/pixdesc.c -+++ b/lib/ffmpeg/libavutil/pixdesc.c -@@ -874,6 +874,12 @@ void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesi - .log2_chroma_h = 1, - .flags = PIX_FMT_HWACCEL, - }, -+ [PIX_FMT_XVBA_VLD] = { -+ .name = "xvba_vld", -+ .log2_chroma_w = 1, -+ .log2_chroma_h = 1, -+ .flags = PIX_FMT_HWACCEL, -+ }, - [PIX_FMT_YUV420P9LE] = { - .name = "yuv420p9le", - .nb_components = 3, -diff --git a/lib/ffmpeg/libavutil/pixfmt.h b/lib/ffmpeg/libavutil/pixfmt.h -index f0d9c01..0f8cf7b 100644 ---- a/lib/ffmpeg/libavutil/pixfmt.h -+++ b/lib/ffmpeg/libavutil/pixfmt.h -@@ -129,6 +129,7 @@ enum PixelFormat { - PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer -+ PIX_FMT_XVBA_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - - PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 - PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 --- -1.7.10 - - -From bb93e835939fce784f8ad4b2364f174df4ee3978 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Apr 2012 12:09:31 +0200 -Subject: [PATCH 63/88] xvba: add decoder - ---- - configure.in | 48 + - language/English/strings.po | 12 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 216 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 15 +- - xbmc/cores/VideoRenderers/RenderFormats.h | 1 + - xbmc/cores/VideoRenderers/RenderManager.cpp | 4 + - .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 4 + - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 16 + - xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in | 4 + - xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 2367 ++++++++++++++++++++ - xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h | 382 ++++ - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 + - xbmc/settings/GUISettings.cpp | 3 + - xbmc/settings/VideoSettings.h | 2 + - xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 1 + - 15 files changed, 3073 insertions(+), 6 deletions(-) - create mode 100644 xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp - create mode 100644 xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h - -diff --git a/configure.in b/configure.in -index 4769315..23439fd 100644 ---- a/configure.in -+++ b/configure.in -@@ -124,6 +124,8 @@ vaapi_not_found="== Could not find libva. VAAPI support disabled. ==" - vaapi_disabled="== VAAPI support manually disabled. ==" - crystalhd_not_found="== Could not find libcrystalhd. CrystalHD support disabled. ==" - crystalhd_disabled="== CrystalHD support manually disabled. ==" -+xvba_not_found="== Could not find amdxvba.h. XVBA support disabled. ==" -+xvba_disabled="== XVBA support manually disabled. ==" - vdadecoder_enabled="== VDADecoder support enabled. ==" - vdadecoder_disabled="== VDADecoder support manually disabled. ==" - vtbdecoder_enabled="== VTBDecoder support enabled. ==" -@@ -247,6 +249,12 @@ AC_ARG_ENABLE([crystalhd], - [enable CrystalHD decoding (default is auto)])], - [use_crystalhd=$enableval], - [use_crystalhd=auto]) -+ -+AC_ARG_ENABLE([xvba], -+ [AS_HELP_STRING([--enable-xvba], -+ [enable XVBA decoding (default is auto)])], -+ [use_xvba=$enableval], -+ [use_xvba=auto]) - - AC_ARG_ENABLE([vdadecoder], - [AS_HELP_STRING([--enable-vdadecoder], -@@ -1751,6 +1759,38 @@ else - USE_CRYSTALHD=0 - fi - -+# XVBA -+if test "x$use_xvba" != "xno"; then -+ if test "$host_vendor" = "apple" ; then -+ if test "x$use_xvba" = "xyes"; then -+ AC_MSG_ERROR([XVBA not supported on this platform]) -+ else -+ use_xvba="no" -+ AC_MSG_NOTICE($xvba_disabled) -+ fi -+ USE_XVBA=0 -+ else -+ initial_val=$use_xvba -+ AC_CHECK_HEADER([amd/amdxvba.h],, use_xvba=no, [#include ]) -+ -+ if test "x$use_xvba" = "xno"; then -+ if test "x$initial_val" = "xyes"; then -+ AC_MSG_ERROR($xvba_not_found) -+ else -+ AC_MSG_RESULT($xvba_not_found) -+ fi -+ USE_XVBA=0 -+ else -+ AC_DEFINE([HAVE_LIBXVBA], [1], [Define to 1 if you have the 'xvba' header (amdxvba.h)]) -+ USE_XVBA=1 -+ fi -+ fi -+else -+ AC_MSG_NOTICE($xvba_disabled) -+ USE_XVBA=0 -+fi -+ -+ - # VDADecoder - if test "x$use_vdadecoder" != "xno"; then - if test "$host_vendor" = "apple" ; then -@@ -1962,6 +2002,12 @@ else - final_message="$final_message\n CrystalHD:\tNo" - fi - -+if test "x$use_xvba" != "xno"; then -+ final_message="$final_message\n XVBA:\t\tYes" -+else -+ final_message="$final_message\n XVBA:\t\tNo" -+fi -+ - if test "x$use_vdadecoder" != "xno"; then - final_message="$final_message\n VDADecoder:\tYes" - else -@@ -2435,6 +2481,7 @@ AC_SUBST(USE_OPENGLES) - AC_SUBST(USE_VDPAU) - AC_SUBST(USE_VAAPI) - AC_SUBST(USE_CRYSTALHD) -+AC_SUBST(USE_XVBA) - AC_SUBST(USE_LIBSMBCLIENT) - AC_SUBST(USE_LIBNFS) - AC_SUBST(USE_LIBAFPCLIENT) -@@ -2618,6 +2665,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [ - `if test "x$use_vdpau" != "xno"; then echo --enable-vdpau; else echo --disable-vdpau; fi` \ - `if test "x$use_vaapi" != "xno"; then echo --enable-vaapi; else echo --disable-vaapi; fi` \ - `if test "$use_optimizations" != "no"; then echo --enable-optimizations; else echo --disable-optimizations; fi` \ -+ `if test "x$use_xvba" != "xno"; then echo --enable-xvba; else echo --disable-xvba; fi` \ - --enable-protocol=http \ - --enable-pthreads \ - --enable-runtime-cpudetect \ -diff --git a/language/English/strings.po b/language/English/strings.po -index f2abd3f..fc896b3 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5120,7 +5120,11 @@ msgctxt "#13436" - msgid "Prefer VDPAU Video Mixer" - msgstr "" - --#empty strings from id 13437 to 13499 -+msgctxt "#13437" -+msgid "Allow hardware acceleration (XVBA)" -+msgstr "" -+ -+#empty strings from id 13438 to 13499 - - msgctxt "#13500" - msgid "A/V sync method" -@@ -6342,7 +6346,11 @@ msgctxt "#16325" - msgid "VDPAU - Bob" - msgstr "" - --#empty strings from id 16326 to 16399 -+msgctxt "#16326" -+msgid "XVBA" -+msgstr "" -+ -+#empty strings from id 16327 to 16399 - - msgctxt "#16400" - msgid "Post-processing" -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 6e6d97e..0bb924b 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -63,6 +63,9 @@ - VA_MICRO_VERSION == 0 && VA_SDS_VERSION < 5))) - - #endif -+#ifdef HAVE_LIBXVBA -+#include "cores/dvdplayer/DVDCodecs/Video/XVBA.h" -+#endif - - #ifdef TARGET_DARWIN - #include "osx/CocoaInterface.h" -@@ -129,6 +132,9 @@ - #ifdef HAVE_LIBVDPAU - vdpau = NULL; - #endif -+#ifdef HAVE_LIBXVBA -+ xvba = NULL; -+#endif - } - - CLinuxRendererGL::YUVBUFFER::~YUVBUFFER() -@@ -604,6 +610,9 @@ void CLinuxRendererGL::ReleaseBuffer(int idx) - #ifdef HAVE_LIBVDPAU - SAFE_RELEASE(buf.vdpau); - #endif -+#ifdef HAVE_LIBXVBA -+ SAFE_RELEASE(buf.xvba); -+#endif - #ifdef HAVE_LIBVA - buf.vaapi.surface.reset(); - #endif -@@ -879,7 +888,7 @@ void CLinuxRendererGL::UpdateVideoFilter() - case VS_SCALINGMETHOD_LINEAR: - SetTextureFilter(m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR); - m_renderQuality = RQ_SINGLEPASS; -- if (((m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) && m_nonLinStretch) -+ if (((m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || (m_renderMethod & RENDER_XVBA)) && m_nonLinStretch) - { - m_pVideoFilterShader = new StretchFilterShader(); - if (!m_pVideoFilterShader->CompileAndLink()) -@@ -965,6 +974,11 @@ void CLinuxRendererGL::LoadShaders(int field) - CLog::Log(LOGNOTICE, "GL: Using CVBREF render method"); - m_renderMethod = RENDER_CVREF; - } -+ else if (m_format == RENDER_FMT_XVBA) -+ { -+ CLog::Log(LOGNOTICE, "GL: Using XVBA render method"); -+ m_renderMethod = RENDER_XVBA; -+ } - else - { - int requestedMethod = g_guiSettings.GetInt("videoplayer.rendermethod"); -@@ -1113,6 +1127,12 @@ void CLinuxRendererGL::LoadShaders(int field) - m_textureCreate = &CLinuxRendererGL::CreateCVRefTexture; - m_textureDelete = &CLinuxRendererGL::DeleteCVRefTexture; - } -+ else if (m_format == RENDER_FMT_XVBA) -+ { -+ m_textureUpload = &CLinuxRendererGL::UploadXVBATexture; -+ m_textureCreate = &CLinuxRendererGL::CreateXVBATexture; -+ m_textureDelete = &CLinuxRendererGL::DeleteXVBATexture; -+ } - else - { - // setup default YV12 texture handlers -@@ -1225,6 +1245,13 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - RenderVAAPI(renderBuffer, m_currentField); - } - #endif -+#ifdef HAVE_LIBXVBA -+ else if (m_renderMethod & RENDER_XVBA) -+ { -+ UpdateVideoFilter(); -+ RenderXVBA(renderBuffer, m_currentField); -+ } -+#endif - else - { - // RENDER_CVREF uses the same render as the default case -@@ -1732,6 +1759,77 @@ void CLinuxRendererGL::RenderVAAPI(int index, int field) - #endif - } - -+void CLinuxRendererGL::RenderXVBA(int index, int field) -+{ -+#ifdef HAVE_LIBXVBA -+ YUVPLANE &plane = m_buffers[index].fields[0][1]; -+ -+ glEnable(m_textureTarget); -+ glActiveTextureARB(GL_TEXTURE0); -+ -+ glBindTexture(m_textureTarget, plane.id); -+ -+ // Try some clamping or wrapping -+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -+ -+ if (m_pVideoFilterShader) -+ { -+ GLint filter; -+ if (!m_pVideoFilterShader->GetTextureFilter(filter)) -+ filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR; -+ -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter); -+ m_pVideoFilterShader->SetSourceTexture(0); -+ m_pVideoFilterShader->SetWidth(m_sourceWidth); -+ m_pVideoFilterShader->SetHeight(m_sourceHeight); -+ -+ //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer -+ //having non-linear stretch on breaks the alignment -+ if (g_application.m_pPlayer && g_application.m_pPlayer->IsInMenu()) -+ m_pVideoFilterShader->SetNonLinStretch(1.0); -+ else -+ m_pVideoFilterShader->SetNonLinStretch(pow(g_settings.m_fPixelRatio, g_advancedSettings.m_videoNonLinStretchRatio)); -+ -+ m_pVideoFilterShader->Enable(); -+ } -+ else -+ { -+ GLint filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR; -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter); -+ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter); -+ } -+ -+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -+ VerifyGLState(); -+ -+ glBegin(GL_QUADS); -+ if (m_textureTarget==GL_TEXTURE_2D) -+ { -+ glTexCoord2f(plane.rect.x1, plane.rect.y1); glVertex2f(m_destRect.x1, m_destRect.y1); -+ glTexCoord2f(plane.rect.x2, plane.rect.y1); glVertex2f(m_destRect.x2, m_destRect.y1); -+ glTexCoord2f(plane.rect.x2, plane.rect.y2); glVertex2f(m_destRect.x2, m_destRect.y2); -+ glTexCoord2f(plane.rect.x1, plane.rect.y2); glVertex2f(m_destRect.x1, m_destRect.y2); -+ } -+ else -+ { -+ glTexCoord2f(m_destRect.x1, m_destRect.y1); glVertex4f(m_destRect.x1, m_destRect.y1, 0.0f, 0.0f); -+ glTexCoord2f(m_destRect.x2, m_destRect.y1); glVertex4f(m_destRect.x2, m_destRect.y1, 1.0f, 0.0f); -+ glTexCoord2f(m_destRect.x2, m_destRect.y2); glVertex4f(m_destRect.x2, m_destRect.y2, 1.0f, 1.0f); -+ glTexCoord2f(m_destRect.x1, m_destRect.y2); glVertex4f(m_destRect.x1, m_destRect.y2, 0.0f, 1.0f); -+ } -+ glEnd(); -+ VerifyGLState(); -+ -+ if (m_pVideoFilterShader) -+ m_pVideoFilterShader->Disable(); -+ -+ glBindTexture (m_textureTarget, 0); -+ glDisable(m_textureTarget); -+#endif -+} -+ - void CLinuxRendererGL::RenderSoftware(int index, int field) - { - // used for textues uploaded from rgba or CVPixelBuffers. -@@ -2783,6 +2881,91 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) - return true; - } - -+void CLinuxRendererGL::DeleteXVBATexture(int index) -+{ -+#ifdef HAVE_LIBXVBA -+ YUVPLANE &plane = m_buffers[index].fields[0][0]; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ -+ SAFE_RELEASE(m_buffers[index].xvba); -+ -+ if(plane.id && glIsTexture(plane.id)) -+ glDeleteTextures(1, &plane.id); -+ plane.id = 0; -+ fields[0][1].id = 0; -+#endif -+} -+ -+bool CLinuxRendererGL::CreateXVBATexture(int index) -+{ -+#ifdef HAVE_LIBXVBA -+ YV12Image &im = m_buffers[index].image; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[0][0]; -+ -+ DeleteXVBATexture(index); -+ -+ memset(&im , 0, sizeof(im)); -+ memset(&fields, 0, sizeof(fields)); -+ -+ glGenTextures(1, &plane.id); -+ -+ m_eventTexturesDone[index]->Set(); -+#endif -+ return true; -+} -+ -+void CLinuxRendererGL::UploadXVBATexture(int index) -+{ -+#ifdef HAVE_LIBXVBA -+ XVBA::CXvbaRenderPicture *xvba = m_buffers[index].xvba; -+ YV12Image &im = m_buffers[index].image; -+ -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[0][1]; -+ -+ if (!xvba || !xvba->valid) -+ { -+ m_eventTexturesDone[index]->Set(); -+ m_skipRender = true; -+ return; -+ } -+ -+ plane.id = xvba->texture; -+ -+ im.height = xvba->texHeight; -+ im.width = xvba->texWidth; -+ -+ plane.texwidth = xvba->texWidth; -+ plane.texheight = xvba->texHeight; -+ plane.pixpertex_x = 1; -+ plane.pixpertex_y = 1; -+ -+ plane.rect = m_sourceRect; -+ plane.width = im.width; -+ plane.height = im.height; -+ -+ plane.height /= plane.pixpertex_y; -+ plane.rect.y1 /= plane.pixpertex_y; -+ plane.rect.y2 /= plane.pixpertex_y; -+ plane.width /= plane.pixpertex_x; -+ plane.rect.x1 /= plane.pixpertex_x; -+ plane.rect.x2 /= plane.pixpertex_x; -+ -+ if (m_textureTarget == GL_TEXTURE_2D) -+ { -+ plane.height /= plane.texheight; -+ plane.rect.y1 /= plane.texheight; -+ plane.rect.y2 /= plane.texheight; -+ plane.width /= plane.texwidth; -+ plane.rect.x1 /= plane.texwidth; -+ plane.rect.x2 /= plane.texwidth; -+ } -+ -+ m_eventTexturesDone[index]->Set(); -+#endif -+} -+ - void CLinuxRendererGL::UploadYUV422PackedTexture(int source) - { - YUVBUFFER& buf = m_buffers[source]; -@@ -3368,6 +3551,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - if (m_renderMethod & RENDER_VAAPI) - return false; - -+ if (m_renderMethod & RENDER_XVBA) -+ return false; -+ - return (m_renderMethod & RENDER_GLSL) - || (m_renderMethod & RENDER_ARB) - || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3381,6 +3567,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - if (m_renderMethod & RENDER_VAAPI) - return false; - -+ if (m_renderMethod & RENDER_XVBA) -+ return false; -+ - return (m_renderMethod & RENDER_GLSL) - || (m_renderMethod & RENDER_ARB) - || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3404,7 +3593,8 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) - if (feature == RENDERFEATURE_NONLINSTRETCH) - { - if (((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT)) || -- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) -+ (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || -+ (m_renderMethod & RENDER_XVBA)) - return true; - } - -@@ -3476,6 +3666,16 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) - return false; - } - -+ if(m_renderMethod & RENDER_XVBA) -+ { -+#ifdef HAVE_LIBXVBA -+ XVBA::CXvbaRenderPicture *xvba = m_buffers[m_iYV12RenderBuffer].xvba; -+ if(xvba) -+ return xvba->xvba->Supports(method); -+#endif -+ return false; -+ } -+ - #ifdef TARGET_DARWIN - // YADIF too slow for HD but we have no methods to fall back - // to something that works so just turn it off. -@@ -3518,7 +3718,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) - || method == VS_SCALINGMETHOD_LANCZOS3) - { - if ((glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL)) || -- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) -+ (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || (m_renderMethod & RENDER_XVBA)) - { - // spline36 and lanczos3 are only allowed through advancedsettings.xml - if(method != VS_SCALINGMETHOD_SPLINE36 -@@ -3610,4 +3810,14 @@ void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) - } - #endif - -+#ifdef HAVE_LIBXVBA -+void CLinuxRendererGL::AddProcessor(XVBA::CXvbaRenderPicture* xvba, int index) -+{ -+ YUVBUFFER &buf = m_buffers[index]; -+ XVBA::CXvbaRenderPicture *pic = xvba->Acquire(); -+ SAFE_RELEASE(buf.xvba); -+ buf.xvba = pic; -+} -+#endif -+ - #endif -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 13217ce..a189892 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -43,6 +43,8 @@ - namespace Shaders { class BaseVideoFilterShader; } - namespace VAAPI { struct CHolder; } - namespace VDPAU { class CVdpauRenderPicture; } -+namespace XVBA { class CXvbaRenderPicture; } -+ - - #undef ALIGN - #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) -@@ -88,6 +90,7 @@ enum RenderMethod - RENDER_POT=0x10, - RENDER_VAAPI=0x20, - RENDER_CVREF = 0x40, -+ RENDER_XVBA=0x80, - }; - - enum RenderQuality -@@ -149,7 +152,9 @@ class CLinuxRendererGL : public CBaseRenderer - #ifdef TARGET_DARWIN - virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); - #endif -- -+#ifdef HAVE_LIBXVBA -+ virtual void AddProcessor(XVBA::CXvbaRenderPicture* xvba, int index); -+#endif - virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); - - // Feature support -@@ -208,6 +213,10 @@ class CLinuxRendererGL : public CBaseRenderer - void DeleteYUV422PackedTexture(int index); - bool CreateYUV422PackedTexture(int index); - -+ void UploadXVBATexture(int index); -+ void DeleteXVBATexture(int index); -+ bool CreateXVBATexture(int index); -+ - void UploadRGBTexture(int index); - void ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsigned flipIndexBuf); - void ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, unsigned flipIndexPlaneBot, unsigned flipIndexBuf); -@@ -223,6 +232,7 @@ class CLinuxRendererGL : public CBaseRenderer - void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware - void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware - void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware -+ void RenderXVBA(int renderBuffer, int field); // render using xvba hardware - - struct - { -@@ -290,6 +300,9 @@ class CLinuxRendererGL : public CBaseRenderer - #ifdef TARGET_DARWIN_OSX - struct __CVBuffer *cvBufferRef; - #endif -+#ifdef HAVE_LIBXVBA -+ XVBA::CXvbaRenderPicture *xvba; -+#endif - }; - - typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS]; -diff --git a/xbmc/cores/VideoRenderers/RenderFormats.h b/xbmc/cores/VideoRenderers/RenderFormats.h -index 0262c60..a727d94 100644 ---- a/xbmc/cores/VideoRenderers/RenderFormats.h -+++ b/xbmc/cores/VideoRenderers/RenderFormats.h -@@ -35,6 +35,7 @@ enum ERenderFormat { - RENDER_FMT_OMXEGL, - RENDER_FMT_CVBREF, - RENDER_FMT_BYPASS, -+ RENDER_FMT_XVBA, - }; - - #endif -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index b89ec67..c99a555 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -876,6 +876,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic) - else if(pic.format == RENDER_FMT_VAAPI) - m_pRenderer->AddProcessor(*pic.vaapi, index); - #endif -+#ifdef HAVE_LIBXVBA -+ else if(pic.format == RENDER_FMT_XVBA) -+ m_pRenderer->AddProcessor(pic.xvba, index); -+#endif - m_pRenderer->ReleaseImage(index, false); - - m_bRenderBufferUsed = true; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -index 64c5f5f..5fa52c3 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h -@@ -35,6 +35,7 @@ - namespace DXVA { class CSurfaceContext; } - namespace VAAPI { struct CHolder; } - namespace VDPAU { class CVdpauRenderPicture; } -+namespace XVBA { class CXvbaRenderPicture; } - class COpenMax; - class COpenMaxVideo; - struct OpenMaxVideoBuffer; -@@ -60,6 +61,9 @@ struct DVDVideoPicture - struct { - VAAPI::CHolder* vaapi; - }; -+ struct { -+ XVBA::CXvbaRenderPicture* xvba; -+ }; - - struct { - COpenMax *openMax; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -index e0c0f84..fc51dbf 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -56,6 +56,9 @@ - #ifdef HAVE_LIBVA - #include "VAAPI.h" - #endif -+#ifdef HAVE_LIBXVBA -+#include "XVBA.h" -+#endif - - using namespace boost; - -@@ -100,6 +103,19 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - dec->Release(); - } - #endif -+#ifdef HAVE_LIBXVBA -+ if(*cur == PIX_FMT_XVBA_VLD && g_guiSettings.GetBool("videoplayer.usexvba")) -+ { -+ XVBA::CDecoder* dec = new XVBA::CDecoder(); -+ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) -+ { -+ ctx->SetHardware(dec); -+ return *cur; -+ } -+ else -+ dec->Release(); -+ } -+#endif - #ifdef HAVE_LIBVA - // mpeg4 vaapi decoding is disabled - if(*cur == PIX_FMT_VAAPI_VLD && g_guiSettings.GetBool("videoplayer.usevaapi") -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in b/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in -index 176ceff..c58422b 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in -@@ -14,6 +14,10 @@ ifeq (@USE_CRYSTALHD@,1) - SRCS += CrystalHD.cpp - SRCS += DVDVideoCodecCrystalHD.cpp - endif -+ifeq (@USE_XVBA@,1) -+SRCS+= XVBA.cpp \ -+ -+endif - ifeq (@USE_VDA@,1) - SRCS += DVDVideoCodecVDA.cpp - endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp -new file mode 100644 -index 0000000..47ff25f ---- /dev/null -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp 2013-03-10 13:00:12.324988156 +0100 @@ -0,0 +1,2367 @@ +/* + * Copyright (C) 2005-2011 Team XBMC @@ -19081,11 +8967,9 @@ index 0000000..47ff25f +} + +#endif -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h -new file mode 100644 -index 0000000..f38444c ---- /dev/null -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h 2013-03-10 13:00:12.324988156 +0100 @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2005-2011 Team XBMC @@ -19469,190 +9353,9 @@ index 0000000..f38444c +}; + +} -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 92f62bb..1e5d2ac5 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1174,6 +1174,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - formatstr = "NONE"; - buffering = false; - break; -+ case RENDER_FMT_XVBA: -+ formatstr = "XVBA"; -+ buffering = true; -+ break; - } - - if(m_bAllowFullscreen) -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 30b402d..67aeec9 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -695,6 +695,9 @@ void CGUISettings::Initialize() - #ifdef HAVE_LIBVA - AddBool(vp, "videoplayer.usevaapi", 13426, true); - #endif -+#ifdef HAVE_LIBXVBA -+ AddBool(vp, "videoplayer.usexvba", 13437, true); -+#endif - #ifdef HAS_DX - AddBool(g_sysinfo.IsVistaOrHigher() ? vp: NULL, "videoplayer.usedxva2", 13427, g_sysinfo.IsVistaOrHigher() ? true : false); - #endif -diff --git a/xbmc/settings/VideoSettings.h b/xbmc/settings/VideoSettings.h -index f8093b2..f54a837 100644 ---- a/xbmc/settings/VideoSettings.h -+++ b/xbmc/settings/VideoSettings.h -@@ -65,6 +65,8 @@ enum EINTERLACEMETHOD - VS_INTERLACEMETHOD_SW_BLEND = 20, - VS_INTERLACEMETHOD_AUTO_ION = 21, - -+ VS_INTERLACEMETHOD_XVBA = 22, -+ - 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 f25d10d..f6b1ea4 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -@@ -110,6 +110,7 @@ void CGUIDialogVideoSettings::CreateSettings() - entries.push_back(make_pair(VS_INTERLACEMETHOD_DXVA_BOB , 16320)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_DXVA_BEST , 16321)); - entries.push_back(make_pair(VS_INTERLACEMETHOD_AUTO_ION , 16325)); -+ entries.push_back(make_pair(VS_INTERLACEMETHOD_XVBA , 16326)); - - /* remove unsupported methods */ - for(vector >::iterator it = entries.begin(); it != entries.end();) --- -1.7.10 - - -From aa13bba48a76e32136814ab242c18646cd8744ec Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Sun, 4 Nov 2012 16:24:10 +0100 -Subject: [PATCH 64/88] xvba: add string for available decoders - we are - important so make sure we are there - ---- - xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index 0cea7a9..6fb74b7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -169,6 +169,11 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne - #elif defined(_LINUX) && !defined(TARGET_DARWIN) - hwSupport += "VAAPI:no "; - #endif -+#if defined(HAVE_LIBXVBA) && defined(TARGET_LINUX) -+ hwSupport += "XVBA:yes "; -+#elif defined(TARGET_LINUX) -+ hwSupport += "XVBA:no "; -+#endif - - CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); - --- -1.7.10 - - -From 82ae5c8a538374f73dd2f728bcda7ff14efe532a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Jun 2012 12:46:30 +0200 -Subject: [PATCH 65/88] xvba: do not use vaapi if xvba is present - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -index a2b9195..43a05b3 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -261,6 +261,15 @@ void CDecoder::Close() - - bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces) - { -+#ifdef HAVE_LIBXVBA -+ std::string Vendor = g_Windowing.GetRenderVendor(); -+ std::transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); -+ if (Vendor.compare(0, 3, "ati") == 0) -+ { -+ return false; -+ } -+#endif -+ - VAEntrypoint entrypoint = VAEntrypointVLD; - VAProfile profile; - --- -1.7.10 - - -From 1aabfca9ab8a0acd87b3593f97180946ba08e630 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 23 Aug 2012 19:39:49 +0200 -Subject: [PATCH 66/88] ffmpeg: add av_find_default_stream_index to interface - ---- - lib/DllAvFormat.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/DllAvFormat.h b/lib/DllAvFormat.h -index 9bda3f3..bf31fcb 100644 ---- a/lib/DllAvFormat.h -+++ b/lib/DllAvFormat.h -@@ -98,6 +98,7 @@ class DllAvFormatInterface - virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options)=0; - virtual int av_write_trailer(AVFormatContext *s)=0; - virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt)=0; -+ virtual int av_find_default_stream_index(AVFormatContext *s)=0; - }; - - #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) -@@ -153,6 +154,7 @@ class DllAvFormat : public DllDynamic, DllAvFormatInterface - virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options) { return ::avformat_write_header (s, options); } - virtual int av_write_trailer(AVFormatContext *s) { return ::av_write_trailer(s); } - virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt) { return ::av_write_frame(s, pkt); } -+ virtual int av_find_default_stream_index(AVFormatContext *s) { return ::av_find_default_stream_index(s); } - - // DLL faking. - virtual bool ResolveExports() { return true; } -@@ -209,6 +211,7 @@ class DllAvFormat : public DllDynamic, DllAvFormatInterface - DEFINE_METHOD2(int, avformat_write_header , (AVFormatContext *p1, AVDictionary **p2)) - DEFINE_METHOD1(int, av_write_trailer, (AVFormatContext *p1)) - DEFINE_METHOD2(int, av_write_frame , (AVFormatContext *p1, AVPacket *p2)) -+ DEFINE_METHOD1(int, av_find_default_stream_index, (AVFormatContext *p1)) - BEGIN_METHOD_RESOLVE() - RESOLVE_METHOD_RENAME(av_register_all, av_register_all_dont_call) - RESOLVE_METHOD(av_find_input_format) -@@ -243,6 +246,7 @@ class DllAvFormat : public DllDynamic, DllAvFormatInterface - RESOLVE_METHOD(avformat_write_header) - RESOLVE_METHOD(av_write_trailer) - RESOLVE_METHOD(av_write_frame) -+ RESOLVE_METHOD(av_find_default_stream_index) - END_METHOD_RESOLVE() - - /* dependencies of libavformat */ --- -1.7.10 - - -From 541d9c977d0c3d4ab7710085b7edc2386d76ae03 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 67/88] dvdplayer: observe pts counter overflow - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 198 +++++++++++++++++++- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 4 + - 2 files changed, 201 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index 7c0ab03..f91be3c 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp 2013-03-10 13:00:12.326988141 +0100 @@ -18,13 +18,13 @@ * */ @@ -19668,7 +9371,7 @@ index 7c0ab03..f91be3c 100644 #ifdef _LINUX #include "stdint.h" #endif -@@ -495,6 +495,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) +@@ -495,6 +495,9 @@ AddStream(i); } @@ -19678,7 +9381,7 @@ index 7c0ab03..f91be3c 100644 return true; } -@@ -605,6 +608,12 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) +@@ -605,6 +608,12 @@ if (pts == (int64_t)AV_NOPTS_VALUE) return DVD_NOPTS_VALUE; @@ -19691,7 +9394,7 @@ index 7c0ab03..f91be3c 100644 // do calculations in floats as they can easily overflow otherwise // we don't care for having a completly exact timestamp anyway double timestamp = (double)pts * num / den; -@@ -729,6 +738,24 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() +@@ -729,6 +738,24 @@ pkt.pts = AV_NOPTS_VALUE; } @@ -19716,7 +9419,7 @@ index 7c0ab03..f91be3c 100644 // copy contents into our own packet pPacket->iSize = pkt.size; -@@ -845,10 +872,20 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) +@@ -845,10 +872,20 @@ int ret; { CSingleLock lock(m_critSection); @@ -19737,7 +9440,7 @@ index 7c0ab03..f91be3c 100644 } if(m_iCurrentPts == DVD_NOPTS_VALUE) -@@ -867,6 +904,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) +@@ -867,6 +904,165 @@ return (ret >= 0); } @@ -19903,11 +9606,10 @@ index 7c0ab03..f91be3c 100644 bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) { g_demuxer.set(this); -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index 2b5f2e8..e0acf29 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -97,6 +97,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h 2013-03-10 13:00:12.326988141 +0100 +@@ -97,6 +97,7 @@ DemuxPacket* Read(); bool SeekTime(int time, bool backwords = false, double* startpts = NULL); @@ -19915,7 +9617,7 @@ index 2b5f2e8..e0acf29 100644 bool SeekByte(int64_t pos); int GetStreamLength(); CDemuxStream* GetStream(int iStreamId); -@@ -141,5 +142,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux +@@ -141,5 +142,8 @@ XbmcThreads::EndTime m_timeout; CDVDInputStream* m_pInput; @@ -19924,169 +9626,32 @@ index 2b5f2e8..e0acf29 100644 + int64_t m_iStartTime, m_iMaxTime, m_iEndTime; }; --- -1.7.10 - - -From 30b4f0f57c63d3aca9a55e24714d4360edc761c6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 68/88] dvdplayer: avoid short screen flicker caused by - unnecessary reconfigure of renderer - ---- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 1e5d2ac5..69f45d4 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1030,7 +1030,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - || m_output.height != pPicture->iHeight - || m_output.dwidth != pPicture->iDisplayWidth - || m_output.dheight != pPicture->iDisplayHeight -- || m_output.framerate != config_framerate -+ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 ) - || m_output.color_format != (unsigned int)pPicture->format - || m_output.extended_format != pPicture->extended_format - || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified -@@ -1197,7 +1197,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) - m_output.height = pPicture->iHeight; - m_output.dwidth = pPicture->iDisplayWidth; - m_output.dheight = pPicture->iDisplayHeight; -- m_output.framerate = config_framerate; -+ m_output.framerate = config_framerate == 0.0 ? g_graphicsContext.GetFPS() : config_framerate; - m_output.color_format = pPicture->format; - m_output.extended_format = pPicture->extended_format; - m_output.color_matrix = pPicture->color_matrix; --- -1.7.10 - - -From 545cfa0bee6159fc55dfcaf2969d7bc657502071 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 69/88] 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 68cf36a..524efae 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1696,10 +1696,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 -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp 2013-03-10 13:00:12.329988120 +0100 +@@ -348,9 +348,7 @@ + if (stm) + { + st = dynamic_cast(stm); +- if (!st +- || (st->codec != (CodecID)props.stream[i].iCodecId) +- || (st->iChannels != props.stream[i].iChannels)) ++ if (!st || (st->codec != (CodecID)props.stream[i].iCodecId)) + DisposeStream(i); + } + if (!m_streams[i]) +@@ -367,6 +365,7 @@ + st->iBitsPerSample = props.stream[i].iBitsPerSample; + m_streams[i] = st; + st->m_parser_split = true; ++ st->changes++; + } + else if (props.stream[i].iCodecType == AVMEDIA_TYPE_VIDEO) { -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 04a7c7c..0e68a80 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -106,6 +106,8 @@ void CAdvancedSettings::Initialize() - m_videoAllowMpeg4VAAPI = false; - m_videoDisableBackgroundDeinterlace = false; - m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect -+ m_videoVDPAUdeintHD = -1; -+ m_videoVDPAUdeintSD = -1; - m_videoVDPAUtelecine = false; - m_videoVDPAUdeintSkipChromaHD = false; - m_DXVACheckCompatibility = false; -@@ -503,6 +505,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) - XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI); - XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace); - XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1); -+ XMLUtils::GetInt(pElement,"vdpauHDdeint",m_videoVDPAUdeintHD); -+ XMLUtils::GetInt(pElement,"vdpauSDdeint",m_videoVDPAUdeintSD); - XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine); - XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); - -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index 72718e5..aaa4702 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -133,6 +133,8 @@ class CAdvancedSettings - int m_videoPercentSeekBackwardBig; - CStdString m_videoPPFFmpegDeint; - CStdString m_videoPPFFmpegPostProc; -+ int m_videoVDPAUdeintHD; -+ int m_videoVDPAUdeintSD; - bool m_videoVDPAUtelecine; - bool m_videoVDPAUdeintSkipChromaHD; - bool m_musicUseTimeSeeking; --- -1.7.10 - - -From ae14edafa313c667d22cf9a255effab6bcf1fc61 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 13:01:08 +0200 -Subject: [PATCH 70/88] dvdplayer: correct determination if video is playing - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 3737419..890d99e 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -2382,9 +2382,16 @@ bool CDVDPlayer::IsPaused() const - - bool CDVDPlayer::HasVideo() const - { -- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) return true; -+ bool hasVideo(false); - -- return m_SelectionStreams.Count(STREAM_VIDEO) > 0 ? true : false; -+ if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) -+ hasVideo = true; -+ else if (m_SelectionStreams.Count(STREAM_VIDEO) > 0) -+ hasVideo = true; -+ else if (g_renderManager.IsConfigured()) -+ hasVideo = true; -+ -+ return hasVideo; - } - - bool CDVDPlayer::HasAudio() const --- -1.7.10 - - -From 1999316cc983ec63d6f9fe05626a0f481d858119 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 71/88] player: fix rewind - ---- - xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 30 +++++++++++++++++++----------- - xbmc/cores/dvdplayer/DVDPlayer.h | 7 ++++--- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 10 ++++++---- - xbmc/cores/dvdplayer/DVDPlayerVideo.h | 1 + - 5 files changed, 34 insertions(+), 19 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDMessage.h b/xbmc/cores/dvdplayer/DVDMessage.h -index 30b2f5c..b9831d4 100644 ---- a/xbmc/cores/dvdplayer/DVDMessage.h -+++ b/xbmc/cores/dvdplayer/DVDMessage.h -@@ -218,7 +218,7 @@ class CDVDMsgPlayerSetState : public CDVDMsg +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDMessage.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDMessage.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDMessage.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDMessage.h 2013-03-10 13:00:12.327988134 +0100 +@@ -218,7 +218,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg { public: @@ -20095,7 +9660,7 @@ index 30b2f5c..b9831d4 100644 : CDVDMsg(PLAYER_SEEK) , m_time(time) , m_backward(backward) -@@ -226,6 +226,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg +@@ -226,6 +226,7 @@ , m_accurate(accurate) , m_restore(restore) , m_trickplay(trickplay) @@ -20103,7 +9668,7 @@ index 30b2f5c..b9831d4 100644 {} int GetTime() { return m_time; } bool GetBackward() { return m_backward; } -@@ -233,6 +234,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg +@@ -233,6 +234,7 @@ bool GetAccurate() { return m_accurate; } bool GetRestore() { return m_restore; } bool GetTrickPlay() { return m_trickplay; } @@ -20111,7 +9676,7 @@ index 30b2f5c..b9831d4 100644 private: int m_time; bool m_backward; -@@ -240,6 +242,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg +@@ -240,6 +242,7 @@ bool m_accurate; bool m_restore; // whether to restore any EDL cut time bool m_trickplay; @@ -20119,15 +9684,16 @@ index 30b2f5c..b9831d4 100644 }; class CDVDMsgPlayerSeekChapter : public CDVDMsg -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 890d99e..d02f086 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1543,11 +1543,13 @@ void CDVDPlayer::HandlePlaySpeed() +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayer.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayer.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayer.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayer.cpp 2013-03-10 13:00:12.328988127 +0100 +@@ -1542,12 +1542,14 @@ + } else if (m_CurrentVideo.id >= 0 - && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file +- && m_CurrentVideo.inited == true - && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() ++ && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file + && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200)) + && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE) && m_SpeedState.lasttime != GetTime()) @@ -20138,7 +9704,7 @@ index 890d99e..d02f086 100644 // check how much off clock video is when ff/rw:ing // a problem here is that seeking isn't very accurate // and since the clock will be resynced after seek -@@ -1566,7 +1568,7 @@ void CDVDPlayer::HandlePlaySpeed() +@@ -1566,7 +1568,7 @@ { CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up"); int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL); @@ -20147,7 +9713,7 @@ index 890d99e..d02f086 100644 } } } -@@ -2030,7 +2032,7 @@ void CDVDPlayer::HandleMessages() +@@ -2030,7 +2032,7 @@ if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward())) CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time); } @@ -20156,7 +9722,7 @@ index 890d99e..d02f086 100644 } else CLog::Log(LOGWARNING, "error while seeking"); -@@ -2168,9 +2170,10 @@ void CDVDPlayer::HandleMessages() +@@ -2168,9 +2170,10 @@ double offset; offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; @@ -20168,17 +9734,40 @@ index 890d99e..d02f086 100644 m_State.timestamp = CDVDClock::GetAbsoluteClock(); } -@@ -2186,7 +2189,8 @@ void CDVDPlayer::HandleMessages() - // do a seek after rewind, clock is not in sync with current pts - if (m_playSpeed < 0 && speed >= 0) - { -- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset); -+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true)); +@@ -2183,6 +2186,13 @@ + pvrinputstream->Pause( speed == 0 ); } ++ // do a seek after rewind, clock is not in sync with current pts ++ if (m_playSpeed < 0 && speed >= 0) ++ { ++ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset); ++ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true)); ++ } ++ // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE -@@ -3140,7 +3144,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) + // audioplayer, stops outputing audio to audiorendere, but still tries to + // sleep an correct amount for each packet +@@ -2376,9 +2386,16 @@ + + bool CDVDPlayer::HasVideo() const + { +- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) return true; ++ bool hasVideo(false); ++ ++ if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) ++ hasVideo = true; ++ else if (m_SelectionStreams.Count(STREAM_VIDEO) > 0) ++ hasVideo = true; ++ else if (g_renderManager.IsConfigured()) ++ hasVideo = true; + +- return m_SelectionStreams.Count(STREAM_VIDEO) > 0 ? true : false; ++ return hasVideo; + } + + bool CDVDPlayer::HasAudio() const +@@ -3127,7 +3144,7 @@ return true; } @@ -20187,7 +9776,7 @@ index 890d99e..d02f086 100644 { double startpts; if(accurate) -@@ -3152,19 +3156,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3139,19 +3156,23 @@ if(startpts != DVD_NOPTS_VALUE) startpts -= m_offset_pts; @@ -20215,7 +9804,7 @@ index 890d99e..d02f086 100644 m_CurrentTeletext.dts = DVD_NOPTS_VALUE; m_CurrentTeletext.startpts = startpts; -@@ -3208,7 +3216,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3195,7 +3216,7 @@ m_CurrentTeletext.started = false; } @@ -20224,11 +9813,10 @@ index 890d99e..d02f086 100644 m_clock.Discontinuity(pts); UpdatePlayState(0); } -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index d3c201e..70ecea9 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.h -+++ b/xbmc/cores/dvdplayer/DVDPlayer.h -@@ -310,7 +310,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayer.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayer.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayer.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayer.h 2013-03-10 13:00:12.328988127 +0100 +@@ -310,7 +310,7 @@ bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset); @@ -20237,7 +9825,7 @@ index d3c201e..70ecea9 100644 void HandleMessages(); void HandlePlaySpeed(); -@@ -359,8 +359,9 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer +@@ -359,8 +359,9 @@ int m_playSpeed; struct SSpeedState { @@ -20249,293 +9837,2658 @@ index d3c201e..70ecea9 100644 } m_SpeedState; int m_errorCount; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 69f45d4..0434cb9 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -1281,13 +1281,13 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp 2013-03-10 13:00:12.328988127 +0100 +@@ -325,8 +325,10 @@ + + int iDropped = 0; //frames dropped in a row + bool bRequestDrop = false; ++ int iDropDirective; + + m_videoStats.Start(); ++ m_droppingStats.Reset(); + + while (!m_bStop) + { +@@ -436,6 +438,7 @@ + picture.iFlags &= ~DVP_FLAG_ALLOCATED; + m_packets.clear(); + m_started = false; ++ m_droppingStats.Reset(); + } + else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush()) + { +@@ -448,6 +451,7 @@ + //we need to recalculate the framerate + //TODO: this needs to be set on a streamchange instead + ResetFrameRateCalc(); ++ m_droppingStats.Reset(); + + m_stalled = true; + m_started = false; +@@ -465,6 +469,8 @@ + m_speed = static_cast(pMsg)->m_value; + if(m_speed == DVD_PLAYSPEED_PAUSE) + m_iNrOfPicturesNotToSkip = 0; ++ g_renderManager.SetSpeed(m_speed); ++ m_droppingStats.Reset(); + } + else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) + { +@@ -499,6 +505,28 @@ + m_iNrOfPicturesNotToSkip = 1; + } + ++ bRequestDrop = false; ++ iDropDirective = CalcDropRequirement(pts); ++ if (iDropDirective & EOS_VERYLATE) ++ { ++ if (m_bAllowDrop) ++ { ++ m_pullupCorrection.Flush(); ++ bRequestDrop = true; ++ } ++ } ++ int codecControl = 0; ++ if (iDropDirective & EOS_BUFFER_LEVEL) ++ codecControl |= DVP_FLAG_DRAIN; ++ if (m_speed > DVD_PLAYSPEED_NORMAL) ++ codecControl |= DVP_FLAG_NO_POSTPROC; ++ m_pVideoCodec->SetCodecControl(codecControl); ++ if (iDropDirective & EOS_DROPPED) ++ { ++ m_iDroppedFrames++; ++ iDropped++; ++ } ++ + #ifdef PROFILE + bRequestDrop = false; + #else +@@ -508,6 +536,7 @@ + bRequestDrop = false; + m_iDroppedRequest = 0; + m_iLateFrames = 0; ++ m_droppingStats.m_requestOutputDrop = false; + } + #endif + +@@ -555,15 +584,8 @@ + } + + m_videoStats.AddSampleBytes(pPacket->iSize); +- // assume decoder dropped a picture if it didn't give us any +- // picture from a demux packet, this should be reasonable +- // for libavformat as a demuxer as it normally packetizes +- // pictures when they come from demuxer +- if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE)) +- { +- m_iDroppedFrames++; +- iDropped++; +- } ++ ++ bRequestDrop = false; + + // loop while no error + while (!m_bStop) +@@ -586,6 +608,8 @@ + + m_pVideoCodec->Reset(); + m_packets.clear(); ++ picture.iFlags &= ~DVP_FLAG_ALLOCATED; ++ g_renderManager.DiscardBuffer(); + break; + } + +@@ -695,6 +719,8 @@ + CDVDCodecUtils::FreePicture(pTempYUVPackedPicture); + #endif + ++ frametime = (double)DVD_TIME_BASE/m_fFrameRate; ++ + if(m_started == false) + { + m_codecname = m_pVideoCodec->GetName(); +@@ -1004,7 +1030,7 @@ + || m_output.height != pPicture->iHeight + || m_output.dwidth != pPicture->iDisplayWidth + || m_output.dheight != pPicture->iDisplayHeight +- || m_output.framerate != config_framerate ++ || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 ) + || m_output.color_format != (unsigned int)pPicture->format + || m_output.extended_format != pPicture->extended_format + || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified +@@ -1088,47 +1114,69 @@ + } + + CStdString formatstr; ++ bool buffering; + + switch(pPicture->format) + { + case RENDER_FMT_YUV420P: + formatstr = "YV12"; ++ buffering = true; + break; + case RENDER_FMT_YUV420P16: + formatstr = "YV12P16"; ++ buffering = true; + break; + case RENDER_FMT_YUV420P10: + formatstr = "YV12P10"; ++ buffering = true; + break; + case RENDER_FMT_NV12: + formatstr = "NV12"; ++ buffering = true; + break; + case RENDER_FMT_UYVY422: + formatstr = "UYVY"; ++ buffering = true; + break; + case RENDER_FMT_YUYV422: + formatstr = "YUY2"; ++ buffering = true; + break; + case RENDER_FMT_VDPAU: + formatstr = "VDPAU"; ++ buffering = true; ++ break; ++ case RENDER_FMT_VDPAU_420: ++ formatstr = "VDPAU_420"; ++ buffering = true; + break; + case RENDER_FMT_DXVA: + formatstr = "DXVA"; ++ buffering = true; + break; + case RENDER_FMT_VAAPI: + formatstr = "VAAPI"; ++ buffering = false; + break; + case RENDER_FMT_OMXEGL: + formatstr = "OMXEGL"; ++ buffering = false; + break; + case RENDER_FMT_CVBREF: + formatstr = "BGRA"; ++ buffering = false; + break; + case RENDER_FMT_BYPASS: + formatstr = "BYPASS"; ++ buffering = false; + break; + case RENDER_FMT_NONE: + formatstr = "NONE"; ++ buffering = false; ++ break; ++ case RENDER_FMT_XVBA: ++ formatstr = "XVBA"; ++ buffering = true; + break; + } + +@@ -1139,7 +1187,7 @@ + } + + CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str()); +- if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation)) ++ if(!g_renderManager.Configure(pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight, config_framerate, flags, pPicture->format, pPicture->extended_format, m_hints.orientation, buffering)) + { + CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); + return EOS_ABORT; +@@ -1149,7 +1197,7 @@ + m_output.height = pPicture->iHeight; + m_output.dwidth = pPicture->iDisplayWidth; + m_output.dheight = pPicture->iDisplayHeight; +- m_output.framerate = config_framerate; ++ m_output.framerate = config_framerate == 0.0 ? g_graphicsContext.GetFPS() : config_framerate; + m_output.color_format = pPicture->format; + m_output.extended_format = pPicture->extended_format; + m_output.color_matrix = pPicture->color_matrix; +@@ -1222,66 +1270,30 @@ + else + iSleepTime = iFrameSleep + (iClockSleep - iFrameSleep) / m_autosync; + +-#ifdef PROFILE /* during profiling, try to play as fast as possible */ +- iSleepTime = 0; +-#endif +- +- // present the current pts of this frame to user, and include the actual +- // presentation delay, to allow him to adjust for it +- if( m_stalled ) +- m_iCurrentPts = DVD_NOPTS_VALUE; +- else +- m_iCurrentPts = pts - max(0.0, iSleepTime); +- +- // timestamp when we think next picture should be displayed based on current duration +- m_FlipTimeStamp = iCurrentClock; +- m_FlipTimeStamp += max(0.0, iSleepTime); +- m_FlipTimeStamp += iFrameDuration; +- +- if (iSleepTime <= 0 && m_speed) +- m_iLateFrames++; +- else +- m_iLateFrames = 0; +- +- // ask decoder to drop frames next round, as we are very late +- if(m_iLateFrames > 10) ++ if ((m_droppingStats.m_requestOutputDrop && !(pPicture->iFlags & DVP_FLAG_NOSKIP)) ++ || (pPicture->iFlags & DVP_FLAG_DROPPED)) + { +- if (!(pPicture->iFlags & DVP_FLAG_NOSKIP)) +- { +- //if we're calculating the framerate, +- //don't drop frames until we've calculated a stable framerate +- if (m_bAllowDrop || m_speed != DVD_PLAYSPEED_NORMAL) +- { +- result |= EOS_VERYLATE; +- m_pullupCorrection.Flush(); //dropped frames mess up the pattern, so just flush it +- } +- +- //if we requested 5 drops in a row and we're still late, drop on output +- //this keeps a/v sync if the decoder can't drop, or we're still calculating the framerate +- if (m_iDroppedRequest > 5) +- { +- m_iDroppedRequest--; //decrease so we only drop half the frames +- return result | EOS_DROPPED; +- } +- m_iDroppedRequest++; +- } +- } +- else +- { +- m_iDroppedRequest = 0; ++ m_droppingStats.AddOutputDropGain(pts, 1/m_fFrameRate); ++ m_droppingStats.m_requestOutputDrop = false; ++ CLog::Log(LOGDEBUG,"%s - dropped in output", __FUNCTION__); ++ return result | EOS_DROPPED; + } if( m_speed < 0 ) { -- double decoderPts = m_droppingStats.m_lastDecoderPts; +- if( iClockSleep < -DVD_MSEC_TO_TIME(200) +- && !(pPicture->iFlags & DVP_FLAG_NOSKIP) ) + double inputPts = m_droppingStats.m_lastPts; - double renderPts = m_droppingStats.m_lastRenderPts; - if (pts > renderPts) - { -- if (decoderPts >= renderPts) ++ double renderPts = m_droppingStats.m_lastRenderPts; ++ if (pts > renderPts) ++ { + if (inputPts >= renderPts) - { -- Sleep(200); ++ { + Sleep(50); - } ++ } return result | EOS_DROPPED; - } -@@ -1584,7 +1584,7 @@ double CDVDPlayerVideo::GetCurrentPts() - - if( m_stalled ) - iRenderPts = DVD_NOPTS_VALUE; -- else -+ else if ( m_speed == DVD_PLAYSPEED_NORMAL) - iRenderPts = iRenderPts - max(0.0, iSleepTime); - - return iRenderPts; -@@ -1684,6 +1684,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) - int iSkippedDeint = 0; - int iBufferLevel; - -+ m_droppingStats.m_lastPts = pts; -+ - // get decoder stats - if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) - iDecoderPts = pts; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -index 509d5f7..7cddda7 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h -@@ -51,6 +51,7 @@ class CDroppingStats - double m_totalGain; - double m_lastDecoderPts; - double m_lastRenderPts; -+ double m_lastPts; - unsigned int m_lateFrames; - unsigned int m_dropRequests; - bool m_requestOutputDrop; --- -1.7.10 - - -From d4c4fafbcd0bce6f566e2e65e1f9009dc445f832 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 72/88] xrandr: fix query for multiple screens - ---- - xbmc/windowing/X11/XRandR.cpp | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index cc933b9..533e03d 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -57,12 +57,14 @@ bool CXRandR::Query(bool force) - - m_outputs.clear(); - // query all screens -+ // we are happy if at least one screen returns results -+ bool success = false; - for(unsigned int screennum=0; screennumiFlags & DVP_FLAG_DROPPED) ) +- return result | EOS_DROPPED; +- +- if( m_speed != DVD_PLAYSPEED_NORMAL && limited ) ++ if( m_speed != DVD_PLAYSPEED_NORMAL && m_speed >= 0 && limited ) + { + // calculate frame dropping pattern to render at this speed + // we do that by deciding if this or next frame is closest +@@ -1317,6 +1329,16 @@ + mDisplayField = FS_BOT; + } + ++ int buffer = g_renderManager.WaitForBuffer(m_bStop); ++ while (buffer < 0 && !CThread::m_bStop && ++ CDVDClock::GetAbsoluteClock(false) < iCurrentClock + iSleepTime + DVD_MSEC_TO_TIME(500) ) ++ { ++ Sleep(1); ++ buffer = g_renderManager.WaitForBuffer(m_bStop); ++ } ++ if (buffer < 0) ++ return EOS_DROPPED; ++ + ProcessOverlays(pPicture, pts); + AutoCrop(pPicture); + +@@ -1333,7 +1355,7 @@ + if (index < 0) + return EOS_DROPPED; + +- g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, -1, mDisplayField); ++ g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts, -1, mDisplayField); + + return result; + #else +@@ -1552,6 +1574,22 @@ + g_advancedSettings.m_videoFpsDetect == 0; } - bool CXRandR::Query(bool force, int screennum) -@@ -70,7 +72,7 @@ bool CXRandR::Query(bool force, int screennum) - CStdString cmd; - cmd = getenv("XBMC_BIN_HOME"); - cmd += "/xbmc-xrandr"; -- cmd.append("-q --screen %d", screennum); -+ cmd.AppendFormat(" -q --screen %d", screennum); - - FILE* file = popen(cmd.c_str(),"r"); - if (!file) --- -1.7.10 - - -From a4d6cfe137f6a6a91443cdc3f464a7564efb49eb Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 2 Dec 2012 15:46:55 +0100 -Subject: [PATCH 73/88] X11: add debug log to print out refresh after xrr - event - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index ef83133..76c6362 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -685,6 +685,12 @@ void CWinSystemX11::NotifyXRREvent() - XOutput *out = g_xrandr.GetOutput(currentOutput); - XMode mode = g_xrandr.GetCurrentMode(currentOutput); - -+ if (out) -+ CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ -+ , out->name.c_str(), mode.id.c_str(), mode.hz); -+ else -+ CLog::Log(LOGWARNING, "%s - output name not set", __FUNCTION__); ++double CDVDPlayerVideo::GetCurrentPts() ++{ ++ double iSleepTime, iRenderPts; ++ int iBufferLevel; + - RESOLUTION_INFO res; - unsigned int i; - bool found(false); --- -1.7.10 - - -From ea768fa98309706665097abbf7d642ab9ee2ceae Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 74/88] X11: dont call XCloseDisplay on shutdown, it crashes - when powered doen by cec on ATI - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index 76c6362..e4e25b2 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -108,7 +108,8 @@ bool CWinSystemX11::DestroyWindowSystem() - //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy - //so instead we just let m_dpy die on exit - // i have seen core dumps on ATI if the display is not closed here -- XCloseDisplay(m_dpy); -+ // crashes when shutting down via cec -+// XCloseDisplay(m_dpy); ++ // get render stats ++ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); ++ ++ if( m_stalled ) ++ iRenderPts = DVD_NOPTS_VALUE; ++ else if ( m_speed == DVD_PLAYSPEED_NORMAL) ++ iRenderPts = iRenderPts - max(0.0, iSleepTime); ++ ++ return iRenderPts; ++} ++ + #define MAXFRAMERATEDIFF 0.01 + #define MAXFRAMESERR 1000 + +@@ -1576,7 +1614,7 @@ + double frameduration = m_pullupCorrection.GetFrameDuration(); + + if (frameduration == DVD_NOPTS_VALUE || +- (g_advancedSettings.m_videoFpsDetect == 1 && m_pullupCorrection.GetPatternLength() > 1)) ++ (g_advancedSettings.m_videoFpsDetect == 1 && (m_pullupCorrection.GetPatternLength() > 1 && !m_bFpsInvalid))) + { + //reset the stored framerates if no good framerate was detected + m_fStableFrameRate = 0.0; +@@ -1632,3 +1670,147 @@ + m_iFrameRateCount = 0; + } + } ++ ++int CDVDPlayerVideo::CalcDropRequirement(double pts) ++{ ++ int result = 0; ++ double iSleepTime; ++ double iDecoderPts, iRenderPts; ++ double iInterval; ++ int interlaced; ++ double iGain; ++ double iLateness; ++ bool bNewFrame; ++ int iSkippedDeint = 0; ++ int iBufferLevel; ++ ++ m_droppingStats.m_lastPts = pts; ++ ++ // get decoder stats ++ if (!m_pVideoCodec->GetCodecStats(iDecoderPts, iSkippedDeint, interlaced)) ++ iDecoderPts = pts; ++ if (iDecoderPts == DVD_NOPTS_VALUE) ++ iDecoderPts = pts; ++ ++ // get render stats ++ g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); ++ ++ if (iBufferLevel < 0) ++ result |= EOS_BUFFER_LEVEL; ++ else if (iBufferLevel < 2) ++ { ++ result |= EOS_BUFFER_LEVEL; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - hurry: %d", iBufferLevel); ++ } ++ ++ bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts; ++ ++ if (interlaced) ++ iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE; ++ else ++ iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; ++ ++ ++ m_FlipTimeStamp = m_pClock->GetAbsoluteClock() + max(0.0, iSleepTime) + iInterval; ++ ++ if( m_stalled ) ++ m_iCurrentPts = DVD_NOPTS_VALUE; ++ else ++ m_iCurrentPts = iRenderPts - max(0.0, iSleepTime); ++ ++ ++ if (m_droppingStats.m_lastDecoderPts > 0 ++ && bNewFrame ++ && m_bAllowDrop ++ && m_droppingStats.m_dropRequests > 0) ++ { ++ iGain = (iDecoderPts - m_droppingStats.m_lastDecoderPts - iInterval)/(double)DVD_TIME_BASE; ++ if (iSkippedDeint) ++ { ++ CDroppingStats::CGain gain; ++ gain.gain = 1/m_fFrameRate; ++ gain.pts = iDecoderPts; ++ m_droppingStats.m_gain.push_back(gain); ++ m_droppingStats.m_totalGain += gain.gain; ++ result |= EOS_DROPPED; ++ m_droppingStats.m_dropRequests = 0; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped de-interlacing cycle, Sleeptime: %f, Bufferlevel: %d", iSleepTime, iBufferLevel); ++ } ++ else if (iGain > 1/m_fFrameRate) ++ { ++ CDroppingStats::CGain gain; ++ gain.gain = iGain; ++ gain.pts = iDecoderPts; ++ m_droppingStats.m_gain.push_back(gain); ++ m_droppingStats.m_totalGain += iGain; ++ result |= EOS_DROPPED; ++ m_droppingStats.m_dropRequests = 0; ++ CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped in decoder, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain); ++ } ++ } ++ m_droppingStats.m_lastDecoderPts = iDecoderPts; ++ ++ // subtract gains ++ while (!m_droppingStats.m_gain.empty() && ++ iRenderPts >= m_droppingStats.m_gain.front().pts) ++ { ++ m_droppingStats.m_totalGain -= m_droppingStats.m_gain.front().gain; ++ m_droppingStats.m_gain.pop_front(); ++ } ++ ++ // calculate lateness ++ iLateness = iSleepTime + m_droppingStats.m_totalGain; ++ if (iLateness < 0 && m_speed) ++ { ++ if (bNewFrame) ++ m_droppingStats.m_lateFrames++; ++ ++ // if lateness is smaller than frametime, we observe this state ++ // for 10 cycles ++ if (m_droppingStats.m_lateFrames > 10 || iLateness < -2/m_fFrameRate) ++ { ++ // is frame allowed to skip ++ if (m_iNrOfPicturesNotToSkip <= 0) ++ { ++ result |= EOS_VERYLATE; ++ ++ // drop in output ++ if (m_droppingStats.m_dropRequests > 7 && g_graphicsContext.IsFullScreenVideo()) ++ { ++ m_droppingStats.m_dropRequests--; //decrease so we only drop half the frames ++ m_droppingStats.m_requestOutputDrop = true; ++ } ++ else if (bNewFrame) ++ m_droppingStats.m_dropRequests++; ++ } ++ } ++ } ++ else ++ { ++ m_droppingStats.m_dropRequests = 0; ++ m_droppingStats.m_lateFrames = 0; ++ m_droppingStats.m_requestOutputDrop = false; ++ } ++ m_droppingStats.m_lastRenderPts = iRenderPts; ++ return result; ++} ++ ++void CDroppingStats::Reset() ++{ ++ m_gain.clear(); ++ m_totalGain = 0; ++ m_lastDecoderPts = 0; ++ m_lastRenderPts = 0; ++ m_lateFrames = 0; ++ m_dropRequests = 0; ++ m_requestOutputDrop = false; ++} ++ ++void CDroppingStats::AddOutputDropGain(double pts, double frametime) ++{ ++ CDroppingStats::CGain gain; ++ gain.gain = frametime; ++ gain.pts = pts; ++ m_gain.push_back(gain); ++ m_totalGain += frametime; ++} +diff -Naur xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayerVideo.h xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayerVideo.h +--- xbmc-12.0.4/xbmc/cores/dvdplayer/DVDPlayerVideo.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/dvdplayer/DVDPlayerVideo.h 2013-03-10 13:00:12.328988127 +0100 +@@ -37,6 +37,27 @@ + + #define VIDEO_PICTURE_QUEUE_SIZE 1 + ++class CDroppingStats ++{ ++public: ++ void Reset(); ++ void AddOutputDropGain(double pts, double frametime); ++ struct CGain ++ { ++ double gain; ++ double pts; ++ }; ++ std::deque m_gain; ++ double m_totalGain; ++ double m_lastDecoderPts; ++ double m_lastRenderPts; ++ double m_lastPts; ++ unsigned int m_lateFrames; ++ unsigned int m_dropRequests; ++ bool m_requestOutputDrop; ++}; ++ ++ + class CDVDPlayerVideo : public CThread + { + public: +@@ -88,7 +109,7 @@ + + bool InitializedOutputDevice(); + +- double GetCurrentPts() { return m_iCurrentPts; } ++ double GetCurrentPts(); + int GetPullupCorrection() { return m_pullupCorrection.GetPatternLength(); } + + double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */ +@@ -110,6 +131,7 @@ + #define EOS_ABORT 1 + #define EOS_DROPPED 2 + #define EOS_VERYLATE 4 ++#define EOS_BUFFER_LEVEL 8 + + void AutoCrop(DVDVideoPicture* pPicture); + void AutoCrop(DVDVideoPicture *pPicture, RECT &crop); +@@ -135,6 +157,7 @@ + + void ResetFrameRateCalc(); + void CalcFrameRate(); ++ int CalcDropRequirement(double pts); + + double m_fFrameRate; //framerate of the video currently playing + bool m_bCalcFrameRate; //if we should calculate the framerate from the timestamps +@@ -195,5 +218,7 @@ + CPullupCorrection m_pullupCorrection; + + std::list m_packets; ++ ++ CDroppingStats m_droppingStats; + }; + +diff -Naur xbmc-12.0.4/xbmc/cores/omxplayer/OMXPlayerVideo.cpp xbmc-12.0.4.patch/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +--- xbmc-12.0.4/xbmc/cores/omxplayer/OMXPlayerVideo.cpp 2013-03-10 12:59:17.639379413 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/omxplayer/OMXPlayerVideo.cpp 2013-03-10 13:01:10.564569304 +0100 +@@ -338,25 +338,16 @@ + m_dropbase = 0.0f; + #endif + +- // DVDPlayer sleeps until m_iSleepEndTime here before calling FlipPage. +- // Video playback in asynchronous in OMXPlayer, so we don't want to do that here, as it prevents the video fifo from being kept full. +- // So, we keep track of when FlipPage would have been called on DVDPlayer and return early if it is not time. +- // m_iSleepEndTime == DVD_NOPTS_VALUE means we are not waiting to call FlipPage, otherwise it is the time we want to call FlipPage +- if (m_iSleepEndTime == DVD_NOPTS_VALUE) { +- m_iSleepEndTime = iCurrentClock + iSleepTime; +- } +- +- if (!CThread::m_bStop && m_av_clock->GetAbsoluteClock(false) < m_iSleepEndTime + DVD_MSEC_TO_TIME(500)) ++ int buffer = g_renderManager.WaitForBuffer(m_bStop, 0); ++ if (buffer < 0) + return; + +- double pts_media = m_av_clock->OMXMediaTime(false, false); +- ProcessOverlays(iGroupId, pts_media); +- +- g_renderManager.FlipPage(CThread::m_bStop, m_iSleepEndTime / DVD_TIME_BASE, -1, FS_NONE); +- +- m_iSleepEndTime = DVD_NOPTS_VALUE; ++ double pts_overlay = m_av_clock->OMXMediaTime(false, false) ++ + 2* (double)DVD_TIME_BASE / g_graphicsContext.GetFPS(); ++ ProcessOverlays(iGroupId, pts_overlay); + +- //m_av_clock->WaitAbsoluteClock((iCurrentClock + iSleepTime)); ++ double timestamp = CDVDClock::GetAbsoluteClock(false) + 2 / g_graphicsContext.GetFPS(); ++ g_renderManager.FlipPage(CThread::m_bStop, timestamp, -1, FS_NONE); + } + + void OMXPlayerVideo::Process() +@@ -789,7 +780,7 @@ + + if(!g_renderManager.Configure(width, height, + iDisplayWidth, iDisplayHeight, m_fFrameRate, flags, format, 0, +- m_hints.orientation)) ++ m_hints.orientation, true)) + { + CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); + return; +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/BaseRenderer.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/BaseRenderer.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/BaseRenderer.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/BaseRenderer.h 2013-03-10 13:00:12.284988442 +0100 +@@ -26,10 +26,11 @@ + + #define MAX_PLANES 3 + #define MAX_FIELDS 3 ++#define NUM_BUFFERS 10 + + typedef struct YV12Image + { +- BYTE * plane[MAX_PLANES]; ++ uint8_t* plane[MAX_PLANES]; + int planesize[MAX_PLANES]; + unsigned stride[MAX_PLANES]; + unsigned width; +@@ -80,10 +81,13 @@ + void GetVideoRect(CRect &source, CRect &dest); + float GetAspectRatio() const; + +- virtual bool AddVideoPicture(DVDVideoPicture* picture) { return false; } ++ virtual bool AddVideoPicture(DVDVideoPicture* picture, int index) { return false; } + virtual void Flush() {}; + + virtual unsigned int GetProcessorSize() { return 0; } ++ virtual unsigned int GetMaxBufferSize() { return 0; } ++ virtual void SetBufferSize(int numBuffers) { } ++ virtual void ReleaseBuffer(int idx) { } + + virtual bool Supports(ERENDERFEATURE feature) { return false; } + +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp 2013-03-10 13:00:12.333988091 +0100 +@@ -63,6 +63,9 @@ + VA_MICRO_VERSION == 0 && VA_SDS_VERSION < 5))) + + #endif ++#ifdef HAVE_LIBXVBA ++#include "cores/dvdplayer/DVDCodecs/Video/XVBA.h" ++#endif + + #ifdef TARGET_DARWIN + #include "osx/CocoaInterface.h" +@@ -129,6 +132,9 @@ + #ifdef HAVE_LIBVDPAU + vdpau = NULL; + #endif ++#ifdef HAVE_LIBXVBA ++ xvba = NULL; ++#endif + } + + CLinuxRendererGL::YUVBUFFER::~YUVBUFFER() +@@ -235,14 +241,6 @@ + return true; + } + +- +-void CLinuxRendererGL::ManageTextures() +-{ +- m_NumYV12Buffers = 2; +- //m_iYV12RenderBuffer = 0; +- return; +-} +- + bool CLinuxRendererGL::ValidateRenderTarget() + { + if (!m_bValidated) +@@ -259,7 +257,7 @@ + // function pointer for texture might change in + // call to LoadShaders + glFinish(); +- for (int i = 0 ; i < m_NumYV12Buffers ; i++) ++ for (int i = 0 ; i < NUM_BUFFERS ; i++) + (this->*m_textureDelete)(i); + + // trigger update of video filters +@@ -603,13 +601,31 @@ + glFinish(); + m_bValidated = false; + m_fbo.fbo.Cleanup(); ++ m_iYV12RenderBuffer = 0; ++} ++ ++void CLinuxRendererGL::ReleaseBuffer(int idx) ++{ ++ YUVBUFFER &buf = m_buffers[idx]; ++#ifdef HAVE_LIBVDPAU ++ SAFE_RELEASE(buf.vdpau); ++#endif ++#ifdef HAVE_LIBXVBA ++ SAFE_RELEASE(buf.xvba); ++#endif ++#ifdef HAVE_LIBVA ++ buf.vaapi.surface.reset(); ++#endif ++#ifdef TARGET_DARWIN ++ if (buf.cvBufferRef) ++ CVBufferRelease(buf.cvBufferRef); ++#endif + } + + void CLinuxRendererGL::Update(bool bPauseDrawing) + { + if (!m_bConfigured) return; + ManageDisplay(); +- ManageTextures(); + } + + void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha) +@@ -625,7 +641,6 @@ } - // m_SDLSurface is free()'d by SDL_Quit(). --- -1.7.10 - - -From aaf6be8480620bed4631c9da17b62c15d260d298 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Gr=C3=A9gory=20Coutant?= -Date: Wed, 12 Dec 2012 19:49:47 +0100 -Subject: [PATCH 75/88] x11: support for multiple x screens - ---- - xbmc/windowing/X11/XRandR.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 533e03d..7a16488 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -92,7 +92,7 @@ bool CXRandR::Query(bool force, int screennum) - pclose(file); + ManageDisplay(); +- ManageTextures(); - TiXmlElement *pRootElement = xmlDoc.RootElement(); -- if (strcasecmp(pRootElement->Value(), "screen") != screennum) -+ if (atoi(pRootElement->Attribute("id")) != screennum) + g_graphicsContext.BeginPaint(); + +@@ -763,11 +778,6 @@ + + m_buffers[m_iYV12RenderBuffer].flipindex = ++m_flipindex; + +-#ifdef HAVE_LIBVDPAU +- if((m_renderMethod & RENDER_VDPAU) && m_buffers[m_iYV12RenderBuffer].vdpau) +- m_buffers[m_iYV12RenderBuffer].vdpau->Present(); +-#endif +- + return; + } + +@@ -782,7 +792,6 @@ + m_resolution = RES_DESKTOP; + + m_iYV12RenderBuffer = 0; +- m_NumYV12Buffers = 2; + + m_formats.push_back(RENDER_FMT_YUV420P); + GLint size; +@@ -851,6 +860,14 @@ + m_scalingMethod = VS_SCALINGMETHOD_LINEAR; + } + ++ // no need to scale if source equals dest ++ bool scale = ((float)m_sourceHeight != m_destRect.Height()) || ++ ((float)m_sourceWidth != m_destRect.Width()); ++ if(!scale) ++ { ++ m_scalingMethod = VS_SCALINGMETHOD_LINEAR; ++ } ++ + if (m_pVideoFilterShader) { - // TODO ERROR - return false; --- -1.7.10 - - -From 5c8a99221143e88cc2d076516d78106e09ac2a60 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 20 Dec 2012 19:35:38 +0100 -Subject: [PATCH 76/88] fix compile error after recent change - ---- - xbmc/settings/GUIWindowSettingsCategory.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index b9f18e4..cacb32a 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -2453,7 +2453,7 @@ void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) - { - // we expect "videoscreen.monitor" but it might be hidden on some platforms, - // so check that we actually have a visable control. -- CBaseSettingControl *control = GetSetting(strSetting); -+ BaseSettingControlPtr control = GetSetting(strSetting); - if (control) - { - control->SetDelayed(); --- -1.7.10 - - -From 9c3bd38c6e2f8da31d8627115f176f2c19e7504e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 77/88] pvr: increase changes counter of stream on stream - change, cosmetics after - dd307930d39d92f145a01a16600cd00e01ec39be - ---- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -index 8c984f6..034e545 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp -@@ -348,9 +348,7 @@ void CDVDDemuxPVRClient::RequestStreams() - if (stm) - { - st = dynamic_cast(stm); -- if (!st -- || (st->codec != (CodecID)props.stream[i].iCodecId) -- || (st->iChannels != props.stream[i].iChannels)) -+ if (!st || (st->codec != (CodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) -@@ -367,6 +365,7 @@ void CDVDDemuxPVRClient::RequestStreams() - st->iBitsPerSample = props.stream[i].iBitsPerSample; - m_streams[i] = st; - st->m_parser_split = true; -+ st->changes++; - } - else if (props.stream[i].iCodecType == AVMEDIA_TYPE_VIDEO) + m_pVideoFilterShader->Free(); +@@ -879,7 +896,7 @@ + case VS_SCALINGMETHOD_LINEAR: + SetTextureFilter(m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR); + m_renderQuality = RQ_SINGLEPASS; +- if (((m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) && m_nonLinStretch) ++ if (((m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || (m_renderMethod & RENDER_XVBA)) && m_nonLinStretch) { --- -1.7.10 - - -From 8f0c31f9d2f2cb438c74e83185480dc1d6ff1f1a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 78/88] X11: add keymapping for XF86XK_Sleep - ---- - xbmc/windowing/WinEventsX11.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index c31877e..ed31c04 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -143,6 +143,7 @@ - , {XK_Break, XBMCK_BREAK} - , {XK_Menu, XBMCK_MENU} - , {XF86XK_PowerOff, XBMCK_POWER} -+, {XF86XK_Sleep, XBMCK_SLEEP} - , {XK_EcuSign, XBMCK_EURO} - , {XK_Undo, XBMCK_UNDO} - /* Media keys */ --- -1.7.10 - - -From 9e099b7ba03687449ae5c725b48bda3ee378408b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 79/88] X11: remove toggle full screen after resume - ---- - xbmc/powermanagement/PowerManager.cpp | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp -index a5534c9..7e2ddc6 100644 ---- a/xbmc/powermanagement/PowerManager.cpp -+++ b/xbmc/powermanagement/PowerManager.cpp -@@ -223,11 +223,6 @@ void CPowerManager::OnWake() + m_pVideoFilterShader = new StretchFilterShader(); + if (!m_pVideoFilterShader->CompileAndLink()) +@@ -965,6 +982,11 @@ + CLog::Log(LOGNOTICE, "GL: Using CVBREF render method"); + m_renderMethod = RENDER_CVREF; + } ++ else if (m_format == RENDER_FMT_XVBA) ++ { ++ CLog::Log(LOGNOTICE, "GL: Using XVBA render method"); ++ m_renderMethod = RENDER_XVBA; ++ } + else + { + int requestedMethod = g_guiSettings.GetInt("videoplayer.rendermethod"); +@@ -1095,6 +1117,12 @@ + m_textureCreate = &CLinuxRendererGL::CreateVDPAUTexture; + m_textureDelete = &CLinuxRendererGL::DeleteVDPAUTexture; + } ++ else if (m_format == RENDER_FMT_VDPAU_420) ++ { ++ m_textureUpload = &CLinuxRendererGL::UploadVDPAUTexture420; ++ m_textureCreate = &CLinuxRendererGL::CreateVDPAUTexture420; ++ m_textureDelete = &CLinuxRendererGL::DeleteVDPAUTexture420; ++ } + else if (m_format == RENDER_FMT_VAAPI) + { + m_textureUpload = &CLinuxRendererGL::UploadVAAPITexture; +@@ -1107,6 +1135,12 @@ + m_textureCreate = &CLinuxRendererGL::CreateCVRefTexture; + m_textureDelete = &CLinuxRendererGL::DeleteCVRefTexture; + } ++ else if (m_format == RENDER_FMT_XVBA) ++ { ++ m_textureUpload = &CLinuxRendererGL::UploadXVBATexture; ++ m_textureCreate = &CLinuxRendererGL::CreateXVBATexture; ++ m_textureDelete = &CLinuxRendererGL::DeleteXVBATexture; ++ } + else + { + // setup default YV12 texture handlers +@@ -1170,7 +1204,10 @@ + m_currentField = FIELD_FULL; + + // call texture load function ++ m_skipRender = false; + (this->*m_textureUpload)(renderBuffer); ++ if (m_skipRender) ++ return; + + if (m_renderMethod & RENDER_GLSL) + { +@@ -1179,12 +1216,21 @@ + { + case RQ_LOW: + case RQ_SINGLEPASS: +- RenderSinglePass(renderBuffer, m_currentField); ++ if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL) ++ RenderProgressiveWeave(renderBuffer, m_currentField); ++ else ++ RenderSinglePass(renderBuffer, m_currentField); + VerifyGLState(); + break; + + case RQ_MULTIPASS: +- RenderMultiPass(renderBuffer, m_currentField); ++ if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL) ++ RenderProgressiveWeave(renderBuffer, m_currentField); ++ else ++ { ++ RenderToFBO(renderBuffer, m_currentField); ++ RenderFromFBO(); ++ } + VerifyGLState(); + break; + } +@@ -1207,6 +1253,13 @@ + RenderVAAPI(renderBuffer, m_currentField); + } + #endif ++#ifdef HAVE_LIBXVBA ++ else if (m_renderMethod & RENDER_XVBA) ++ { ++ UpdateVideoFilter(); ++ RenderXVBA(renderBuffer, m_currentField); ++ } ++#endif + else + { + // RENDER_CVREF uses the same render as the default case +@@ -1307,13 +1360,7 @@ + VerifyGLState(); + } + +-void CLinuxRendererGL::RenderMultiPass(int index, int field) +-{ +- RenderToFBO(index, field); +- RenderFromFBO(); +-} +- +-void CLinuxRendererGL::RenderToFBO(int index, int field) ++void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/) + { + YUVPLANES &planes = m_buffers[index].fields[field]; + +@@ -1415,6 +1462,8 @@ + } + m_fbo.width *= planes[0].pixpertex_x; + m_fbo.height *= planes[0].pixpertex_y; ++ if (weave) ++ m_fbo.height *= 2; + + // 1st Pass to video frame size + glBegin(GL_QUADS); +@@ -1533,20 +1582,40 @@ + VerifyGLState(); + } + ++void CLinuxRendererGL::RenderProgressiveWeave(int index, int field) ++{ ++ bool scaleUp = (int)m_sourceHeight < g_graphicsContext.GetHeight() || (int)m_sourceWidth < g_graphicsContext.GetWidth(); ++ ++ if (m_fbo.fbo.IsSupported() && (scaleUp || m_renderQuality == RQ_MULTIPASS)) ++ { ++ glEnable(GL_POLYGON_STIPPLE); ++ glPolygonStipple(stipple_weave); ++ RenderToFBO(index, FIELD_TOP, true); ++ glPolygonStipple(stipple_weave+4); ++ RenderToFBO(index, FIELD_BOT, true); ++ glDisable(GL_POLYGON_STIPPLE); ++ RenderFromFBO(); ++ } ++ else ++ { ++ glEnable(GL_POLYGON_STIPPLE); ++ glPolygonStipple(stipple_weave); ++ RenderSinglePass(index, FIELD_TOP); ++ glPolygonStipple(stipple_weave+4); ++ RenderSinglePass(index, FIELD_BOT); ++ glDisable(GL_POLYGON_STIPPLE); ++ } ++} ++ + void CLinuxRendererGL::RenderVDPAU(int index, int field) + { + #ifdef HAVE_LIBVDPAU +- YUVPLANE &plane = m_buffers[index].fields[field][0]; +- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; +- +- if (!vdpau) +- return; ++ YUVPLANE &plane = m_buffers[index].fields[0][1]; + + glEnable(m_textureTarget); + glActiveTextureARB(GL_TEXTURE0); +- glBindTexture(m_textureTarget, plane.id); + +- vdpau->BindPixmap(); ++ glBindTexture(m_textureTarget, plane.id); + + // Try some clamping or wrapping + glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +@@ -1604,8 +1673,6 @@ + if (m_pVideoFilterShader) + m_pVideoFilterShader->Disable(); + +- vdpau->ReleasePixmap(); +- + glBindTexture (m_textureTarget, 0); + glDisable(m_textureTarget); + #endif +@@ -1700,6 +1767,77 @@ + #endif + } + ++void CLinuxRendererGL::RenderXVBA(int index, int field) ++{ ++#ifdef HAVE_LIBXVBA ++ YUVPLANE &plane = m_buffers[index].fields[0][1]; ++ ++ glEnable(m_textureTarget); ++ glActiveTextureARB(GL_TEXTURE0); ++ ++ glBindTexture(m_textureTarget, plane.id); ++ ++ // Try some clamping or wrapping ++ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ ++ if (m_pVideoFilterShader) ++ { ++ GLint filter; ++ if (!m_pVideoFilterShader->GetTextureFilter(filter)) ++ filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR; ++ ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter); ++ m_pVideoFilterShader->SetSourceTexture(0); ++ m_pVideoFilterShader->SetWidth(m_sourceWidth); ++ m_pVideoFilterShader->SetHeight(m_sourceHeight); ++ ++ //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer ++ //having non-linear stretch on breaks the alignment ++ if (g_application.m_pPlayer && g_application.m_pPlayer->IsInMenu()) ++ m_pVideoFilterShader->SetNonLinStretch(1.0); ++ else ++ m_pVideoFilterShader->SetNonLinStretch(pow(g_settings.m_fPixelRatio, g_advancedSettings.m_videoNonLinStretchRatio)); ++ ++ m_pVideoFilterShader->Enable(); ++ } ++ else ++ { ++ GLint filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR; ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter); ++ } ++ ++ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); ++ VerifyGLState(); ++ ++ glBegin(GL_QUADS); ++ if (m_textureTarget==GL_TEXTURE_2D) ++ { ++ glTexCoord2f(plane.rect.x1, plane.rect.y1); glVertex2f(m_destRect.x1, m_destRect.y1); ++ glTexCoord2f(plane.rect.x2, plane.rect.y1); glVertex2f(m_destRect.x2, m_destRect.y1); ++ glTexCoord2f(plane.rect.x2, plane.rect.y2); glVertex2f(m_destRect.x2, m_destRect.y2); ++ glTexCoord2f(plane.rect.x1, plane.rect.y2); glVertex2f(m_destRect.x1, m_destRect.y2); ++ } ++ else ++ { ++ glTexCoord2f(m_destRect.x1, m_destRect.y1); glVertex4f(m_destRect.x1, m_destRect.y1, 0.0f, 0.0f); ++ glTexCoord2f(m_destRect.x2, m_destRect.y1); glVertex4f(m_destRect.x2, m_destRect.y1, 1.0f, 0.0f); ++ glTexCoord2f(m_destRect.x2, m_destRect.y2); glVertex4f(m_destRect.x2, m_destRect.y2, 1.0f, 1.0f); ++ glTexCoord2f(m_destRect.x1, m_destRect.y2); glVertex4f(m_destRect.x1, m_destRect.y2, 0.0f, 1.0f); ++ } ++ glEnd(); ++ VerifyGLState(); ++ ++ if (m_pVideoFilterShader) ++ m_pVideoFilterShader->Disable(); ++ ++ glBindTexture (m_textureTarget, 0); ++ glDisable(m_textureTarget); ++#endif ++} ++ + void CLinuxRendererGL::RenderSoftware(int index, int field) + { + // used for textues uploaded from rgba or CVPixelBuffers. +@@ -2290,12 +2428,14 @@ + { + #ifdef HAVE_LIBVDPAU + YUVPLANE &plane = m_buffers[index].fields[0][0]; ++ YUVFIELDS &fields = m_buffers[index].fields; + + SAFE_RELEASE(m_buffers[index].vdpau); + + if(plane.id && glIsTexture(plane.id)) + glDeleteTextures(1, &plane.id); + plane.id = 0; ++ fields[0][1].id = 0; + #endif + } + +@@ -2329,11 +2469,152 @@ + void CLinuxRendererGL::UploadVDPAUTexture(int index) + { + #ifdef HAVE_LIBVDPAU ++ VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau; ++ ++ unsigned int flipindex = m_buffers[index].flipindex; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ YUVPLANE &plane = fields[0][0]; ++ ++ if (!vdpau || !vdpau->valid) ++ { ++ m_eventTexturesDone[index]->Set(); ++ m_skipRender = true; ++ return; ++ } ++ ++ fields[0][1].id = vdpau->texture[0]; ++ + m_eventTexturesDone[index]->Set(); +- glPixelStorei(GL_UNPACK_ALIGNMENT,1); //what's this for? + #endif + } + ++void CLinuxRendererGL::DeleteVDPAUTexture420(int index) ++{ ++#ifdef HAVE_LIBVDPAU ++ YUVPLANE &plane = m_buffers[index].fields[0][0]; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ ++ SAFE_RELEASE(m_buffers[index].vdpau); ++ ++ if(plane.id && glIsTexture(plane.id)) ++ glDeleteTextures(1, &plane.id); ++ plane.id = 0; ++ fields[1][0].id = 0; ++ fields[1][1].id = 0; ++ fields[2][0].id = 0; ++ fields[2][1].id = 0; ++ ++#endif ++} ++ ++bool CLinuxRendererGL::CreateVDPAUTexture420(int index) ++{ ++#ifdef HAVE_LIBVDPAU ++ YV12Image &im = m_buffers[index].image; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ YUVPLANE &plane = fields[0][0]; ++ GLuint *pbo = m_buffers[index].pbo; ++ ++ DeleteVDPAUTexture420(index); ++ ++ memset(&im , 0, sizeof(im)); ++ memset(&fields, 0, sizeof(fields)); ++ ++ im.cshift_x = 1; ++ im.cshift_y = 1; ++ ++ im.plane[0] = NULL; ++ im.plane[1] = NULL; ++ im.plane[2] = NULL; ++ ++ for(int p = 0;p<3;p++) ++ { ++ pbo[p] = None; ++ } ++ ++ glEnable(m_textureTarget); ++ glGenTextures(1, &plane.id); ++ glDisable(m_textureTarget); ++ ++ m_eventTexturesDone[index]->Set(); ++#endif ++ return true; ++} ++ ++void CLinuxRendererGL::UploadVDPAUTexture420(int index) ++{ ++#ifdef HAVE_LIBVDPAU ++ VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau; ++ YV12Image &im = m_buffers[index].image; ++ ++ unsigned int flipindex = m_buffers[index].flipindex; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ YUVPLANE &plane = fields[0][0]; ++ ++ if (!vdpau || !vdpau->valid) ++ { ++ m_eventTexturesDone[index]->Set(); ++ m_skipRender = true; ++ return; ++ } ++ ++ im.height = vdpau->texHeight; ++ im.width = vdpau->texWidth; ++ ++ // YUV ++ for (int f = FIELD_FULL; f<=FIELD_BOT ; f++) ++ { ++ int fieldshift = (f==FIELD_FULL) ? 0 : 1; ++ YUVPLANES &planes = fields[f]; ++ ++ planes[0].texwidth = im.width; ++ planes[0].texheight = im.height >> fieldshift; ++ ++ planes[1].texwidth = planes[0].texwidth >> im.cshift_x; ++ planes[1].texheight = planes[0].texheight >> im.cshift_y; ++ planes[2].texwidth = planes[1].texwidth; ++ planes[2].texheight = planes[1].texheight; ++ ++ for (int p = 0; p < 3; p++) ++ { ++ planes[p].pixpertex_x = 1; ++ planes[p].pixpertex_y = 1; ++ } ++ } ++ // crop ++// m_sourceRect.x1 += vdpau->crop.x1; ++// m_sourceRect.x2 -= vdpau->crop.x2; ++// m_sourceRect.y1 += vdpau->crop.y1; ++// m_sourceRect.y2 -= vdpau->crop.y2; ++ ++ // set textures ++ fields[1][0].id = vdpau->texture[0]; ++ fields[1][1].id = vdpau->texture[2]; ++ fields[2][0].id = vdpau->texture[1]; ++ fields[2][1].id = vdpau->texture[3]; ++ ++ glEnable(m_textureTarget); ++ for (int f = 1; f < 3; f++) ++ { ++ for (int p=0;p<2;p++) ++ { ++ glBindTexture(m_textureTarget,fields[f][p].id); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ ++ glBindTexture(m_textureTarget,0); ++ VerifyGLState(); ++ } ++ fields[f][2].id = fields[f][1].id; ++ } ++ CalculateTextureSourceRects(index, 3); ++ glDisable(m_textureTarget); ++ ++ m_eventTexturesDone[index]->Set(); ++#endif ++} + + void CLinuxRendererGL::DeleteVAAPITexture(int index) + { +@@ -2465,7 +2746,7 @@ + || status == VA_STATUS_ERROR_INVALID_DISPLAY) + { + va.display->lost(true); +- for(int i = 0; i < NUM_BUFFERS; i++) ++ for(int i = 0; i < m_NumYV12Buffers; i++) + { + m_buffers[i].vaapi.display.reset(); + m_buffers[i].vaapi.surface.reset(); +@@ -2608,6 +2889,91 @@ + return true; + } + ++void CLinuxRendererGL::DeleteXVBATexture(int index) ++{ ++#ifdef HAVE_LIBXVBA ++ YUVPLANE &plane = m_buffers[index].fields[0][0]; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ ++ SAFE_RELEASE(m_buffers[index].xvba); ++ ++ if(plane.id && glIsTexture(plane.id)) ++ glDeleteTextures(1, &plane.id); ++ plane.id = 0; ++ fields[0][1].id = 0; ++#endif ++} ++ ++bool CLinuxRendererGL::CreateXVBATexture(int index) ++{ ++#ifdef HAVE_LIBXVBA ++ YV12Image &im = m_buffers[index].image; ++ YUVFIELDS &fields = m_buffers[index].fields; ++ YUVPLANE &plane = fields[0][0]; ++ ++ DeleteXVBATexture(index); ++ ++ memset(&im , 0, sizeof(im)); ++ memset(&fields, 0, sizeof(fields)); ++ ++ glGenTextures(1, &plane.id); ++ ++ m_eventTexturesDone[index]->Set(); ++#endif ++ return true; ++} ++ ++void CLinuxRendererGL::UploadXVBATexture(int index) ++{ ++#ifdef HAVE_LIBXVBA ++ XVBA::CXvbaRenderPicture *xvba = m_buffers[index].xvba; ++ YV12Image &im = m_buffers[index].image; ++ ++ YUVFIELDS &fields = m_buffers[index].fields; ++ YUVPLANE &plane = fields[0][1]; ++ ++ if (!xvba || !xvba->valid) ++ { ++ m_eventTexturesDone[index]->Set(); ++ m_skipRender = true; ++ return; ++ } ++ ++ plane.id = xvba->texture; ++ ++ im.height = xvba->texHeight; ++ im.width = xvba->texWidth; ++ ++ plane.texwidth = xvba->texWidth; ++ plane.texheight = xvba->texHeight; ++ plane.pixpertex_x = 1; ++ plane.pixpertex_y = 1; ++ ++ plane.rect = m_sourceRect; ++ plane.width = im.width; ++ plane.height = im.height; ++ ++ plane.height /= plane.pixpertex_y; ++ plane.rect.y1 /= plane.pixpertex_y; ++ plane.rect.y2 /= plane.pixpertex_y; ++ plane.width /= plane.pixpertex_x; ++ plane.rect.x1 /= plane.pixpertex_x; ++ plane.rect.x2 /= plane.pixpertex_x; ++ ++ if (m_textureTarget == GL_TEXTURE_2D) ++ { ++ plane.height /= plane.texheight; ++ plane.rect.y1 /= plane.texheight; ++ plane.rect.y2 /= plane.texheight; ++ plane.width /= plane.texwidth; ++ plane.rect.x1 /= plane.texwidth; ++ plane.rect.x2 /= plane.texwidth; ++ } ++ ++ m_eventTexturesDone[index]->Set(); ++#endif ++} ++ + void CLinuxRendererGL::UploadYUV422PackedTexture(int source) + { + YUVBUFFER& buf = m_buffers[source]; +@@ -3187,12 +3553,15 @@ + { + if(feature == RENDERFEATURE_BRIGHTNESS) + { +- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) ++ if (m_renderMethod & RENDER_VDPAU) + return true; + + if (m_renderMethod & RENDER_VAAPI) + return false; + ++ if (m_renderMethod & RENDER_XVBA) ++ return false; ++ + return (m_renderMethod & RENDER_GLSL) + || (m_renderMethod & RENDER_ARB) + || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); +@@ -3200,12 +3569,15 @@ + + if(feature == RENDERFEATURE_CONTRAST) + { +- if ((m_renderMethod & RENDER_VDPAU) && !g_guiSettings.GetBool("videoplayer.vdpaustudiolevel")) ++ if (m_renderMethod & RENDER_VDPAU) + return true; + + if (m_renderMethod & RENDER_VAAPI) + return false; + ++ if (m_renderMethod & RENDER_XVBA) ++ return false; ++ + return (m_renderMethod & RENDER_GLSL) + || (m_renderMethod & RENDER_ARB) + || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); +@@ -3229,7 +3601,8 @@ + if (feature == RENDERFEATURE_NONLINSTRETCH) + { + if (((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT)) || +- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) ++ (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || ++ (m_renderMethod & RENDER_XVBA)) + return true; + } + +@@ -3271,12 +3644,13 @@ + if(method == VS_INTERLACEMETHOD_AUTO) + return true; + +- if(m_renderMethod & RENDER_VDPAU) ++ if(m_renderMethod & RENDER_VDPAU || ++ m_format == RENDER_FMT_VDPAU_420) + { + #ifdef HAVE_LIBVDPAU +- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; +- if(vdpau) +- return vdpau->Supports(method); ++ VDPAU::CVdpauRenderPicture *vdpauPic = m_buffers[m_iYV12RenderBuffer].vdpau; ++ if(vdpauPic && vdpauPic->vdpau) ++ return vdpauPic->vdpau->Supports(method); + #endif + return false; + } +@@ -3300,6 +3674,16 @@ + return false; + } + ++ if(m_renderMethod & RENDER_XVBA) ++ { ++#ifdef HAVE_LIBXVBA ++ XVBA::CXvbaRenderPicture *xvba = m_buffers[m_iYV12RenderBuffer].xvba; ++ if(xvba) ++ return xvba->xvba->Supports(method); ++#endif ++ return false; ++ } ++ + #ifdef TARGET_DARWIN + // YADIF too slow for HD but we have no methods to fall back + // to something that works so just turn it off. +@@ -3342,7 +3726,7 @@ + || method == VS_SCALINGMETHOD_LANCZOS3) + { + if ((glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL)) || +- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) ++ (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI) || (m_renderMethod & RENDER_XVBA)) + { + // spline36 and lanczos3 are only allowed through advancedsettings.xml + if(method != VS_SCALINGMETHOD_SPLINE36 +@@ -3362,14 +3746,7 @@ + return VS_INTERLACEMETHOD_NONE; + + if(m_renderMethod & RENDER_VDPAU) +- { +-#ifdef HAVE_LIBVDPAU +- CVDPAU *vdpau = m_buffers[m_iYV12RenderBuffer].vdpau; +- if(vdpau) +- return vdpau->AutoInterlaceMethod(); +-#endif + return VS_INTERLACEMETHOD_NONE; +- } + + if(Supports(VS_INTERLACEMETHOD_RENDER_BOB)) + return VS_INTERLACEMETHOD_RENDER_BOB; +@@ -3412,26 +3789,27 @@ + } + + #ifdef HAVE_LIBVDPAU +-void CLinuxRendererGL::AddProcessor(CVDPAU* vdpau) ++void CLinuxRendererGL::AddProcessor(VDPAU::CVdpauRenderPicture *vdpau, int index) + { +- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; ++ YUVBUFFER &buf = m_buffers[index]; ++ VDPAU::CVdpauRenderPicture *pic = vdpau->Acquire(); + SAFE_RELEASE(buf.vdpau); +- buf.vdpau = (CVDPAU*)vdpau->Acquire(); ++ buf.vdpau = pic; + } + #endif + + #ifdef HAVE_LIBVA +-void CLinuxRendererGL::AddProcessor(VAAPI::CHolder& holder) ++void CLinuxRendererGL::AddProcessor(VAAPI::CHolder& holder, int index) + { +- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; ++ YUVBUFFER &buf = m_buffers[index]; + buf.vaapi.surface = holder.surface; + } + #endif + + #ifdef TARGET_DARWIN +-void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef) ++void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) + { +- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; ++ YUVBUFFER &buf = m_buffers[index]; + if (buf.cvBufferRef) + CVBufferRelease(buf.cvBufferRef); + buf.cvBufferRef = cvBufferRef; +@@ -3440,4 +3818,14 @@ + } + #endif + ++#ifdef HAVE_LIBXVBA ++void CLinuxRendererGL::AddProcessor(XVBA::CXvbaRenderPicture* xvba, int index) ++{ ++ YUVBUFFER &buf = m_buffers[index]; ++ XVBA::CXvbaRenderPicture *pic = xvba->Acquire(); ++ SAFE_RELEASE(buf.xvba); ++ buf.xvba = pic; ++} ++#endif ++ + #endif +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp 2013-03-10 13:00:12.277988493 +0100 +@@ -135,13 +135,6 @@ + delete m_dllSwScale; + } + +-void CLinuxRendererGLES::ManageTextures() +-{ +- m_NumYV12Buffers = 2; +- //m_iYV12RenderBuffer = 0; +- return; +-} +- + bool CLinuxRendererGLES::ValidateRenderTarget() + { + if (!m_bValidated) +@@ -395,7 +388,6 @@ + { + if (!m_bConfigured) return; + ManageDisplay(); +- ManageTextures(); + } + + void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha) +@@ -409,7 +401,6 @@ + if (m_renderMethod & RENDER_BYPASS) + { + ManageDisplay(); +- ManageTextures(); + // 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) +@@ -449,7 +440,6 @@ + return; + + ManageDisplay(); +- ManageTextures(); + + g_graphicsContext.BeginPaint(); + +@@ -1982,16 +1972,16 @@ + } + + #ifdef HAVE_LIBOPENMAX +-void CLinuxRendererGLES::AddProcessor(COpenMax* openMax, DVDVideoPicture *picture) ++void CLinuxRendererGLES::AddProcessor(COpenMax* openMax, DVDVideoPicture *picture, int index) + { +- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; ++ YUVBUFFER &buf = m_buffers[index]; + buf.openMaxBuffer = picture->openMaxBuffer; + } + #endif + #ifdef HAVE_VIDEOTOOLBOXDECODER +-void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef) ++void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef, int index) + { +- YUVBUFFER &buf = m_buffers[NextYV12Texture()]; ++ YUVBUFFER &buf = m_buffers[index]; + if (buf.cvBufferRef) + CVBufferRelease(buf.cvBufferRef); + buf.cvBufferRef = cvBufferRef; +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGLES.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2013-03-10 13:00:12.284988442 +0100 +@@ -41,8 +41,6 @@ + class COpenMaxVideo; + typedef std::vector Features; + +-#define NUM_BUFFERS 3 +- + + #undef ALIGN + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) +@@ -138,6 +136,9 @@ + virtual void UnInit(); + virtual void Reset(); /* resets renderer after seek for example */ + virtual void ReorderDrawPoints(); ++ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } ++ virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } + + virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); + +@@ -153,16 +154,15 @@ + virtual std::vector SupportedFormats() { return m_formats; } + + #ifdef HAVE_LIBOPENMAX +- virtual void AddProcessor(COpenMax* openMax, DVDVideoPicture *picture); ++ virtual void AddProcessor(COpenMax* openMax, DVDVideoPicture *picture, int index); + #endif + #ifdef HAVE_VIDEOTOOLBOXDECODER +- virtual void AddProcessor(struct __CVBuffer *cvBufferRef); ++ virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); + #endif + + protected: + virtual void Render(DWORD flags, int index); + +- virtual void ManageTextures(); + int NextYV12Texture(); + virtual bool ValidateRenderTarget(); + virtual void LoadShaders(int field=FIELD_FULL); +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGL.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGL.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/LinuxRendererGL.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/LinuxRendererGL.h 2013-03-10 13:00:12.323988163 +0100 +@@ -38,13 +38,12 @@ + + class CRenderCapture; + +-class CVDPAU; + class CBaseTexture; + namespace Shaders { class BaseYUV2RGBShader; } + namespace Shaders { class BaseVideoFilterShader; } + namespace VAAPI { struct CHolder; } +- +-#define NUM_BUFFERS 3 ++namespace VDPAU { class CVdpauRenderPicture; } ++namespace XVBA { class CXvbaRenderPicture; } + + + #undef ALIGN +@@ -91,6 +90,7 @@ + RENDER_POT=0x10, + RENDER_VAAPI=0x20, + RENDER_CVREF = 0x40, ++ RENDER_XVBA=0x80, + }; + + enum RenderQuality +@@ -138,17 +138,23 @@ + virtual void UnInit(); + virtual void Reset(); /* resets renderer after seek for example */ + virtual void Flush(); ++ virtual void ReleaseBuffer(int idx); ++ virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } ++ virtual unsigned int GetProcessorSize() { return m_NumYV12Buffers; } + + #ifdef HAVE_LIBVDPAU +- virtual void AddProcessor(CVDPAU* vdpau); ++ virtual void AddProcessor(VDPAU::CVdpauRenderPicture* vdpau, int index); + #endif + #ifdef HAVE_LIBVA +- virtual void AddProcessor(VAAPI::CHolder& holder); ++ virtual void AddProcessor(VAAPI::CHolder& holder, int index); + #endif + #ifdef TARGET_DARWIN +- virtual void AddProcessor(struct __CVBuffer *cvBufferRef); ++ virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); ++#endif ++#ifdef HAVE_LIBXVBA ++ virtual void AddProcessor(XVBA::CXvbaRenderPicture* xvba, int index); + #endif +- + virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); + + // Feature support +@@ -168,7 +174,6 @@ + void DrawBlackBars(); + + bool ValidateRenderer(); +- virtual void ManageTextures(); + int NextYV12Texture(); + virtual bool ValidateRenderTarget(); + virtual void LoadShaders(int field=FIELD_FULL); +@@ -192,6 +197,10 @@ + void DeleteVDPAUTexture(int index); + bool CreateVDPAUTexture(int index); + ++ void UploadVDPAUTexture420(int index); ++ void DeleteVDPAUTexture420(int index); ++ bool CreateVDPAUTexture420(int index); ++ + void UploadVAAPITexture(int index); + void DeleteVAAPITexture(int index); + bool CreateVAAPITexture(int index); +@@ -204,6 +213,10 @@ + void DeleteYUV422PackedTexture(int index); + bool CreateYUV422PackedTexture(int index); + ++ void UploadXVBATexture(int index); ++ void DeleteXVBATexture(int index); ++ bool CreateXVBATexture(int index); ++ + void UploadRGBTexture(int index); + void ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsigned flipIndexBuf); + void ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, unsigned flipIndexPlaneBot, unsigned flipIndexBuf); +@@ -212,13 +225,14 @@ + void CalculateTextureSourceRects(int source, int num_planes); + + // renderers +- void RenderMultiPass(int renderBuffer, int field); // multi pass glsl renderer +- void RenderToFBO(int renderBuffer, int field); ++ void RenderToFBO(int renderBuffer, int field, bool weave = false); + void RenderFromFBO(); + void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer + void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer + void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware ++ void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware + void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware ++ void RenderXVBA(int renderBuffer, int field); // render using xvba hardware + + struct + { +@@ -278,7 +292,7 @@ + GLuint pbo[MAX_PLANES]; + + #ifdef HAVE_LIBVDPAU +- CVDPAU* vdpau; ++ VDPAU::CVdpauRenderPicture *vdpau; + #endif + #ifdef HAVE_LIBVA + VAAPI::CHolder& vaapi; +@@ -286,6 +300,9 @@ + #ifdef TARGET_DARWIN_OSX + struct __CVBuffer *cvBufferRef; + #endif ++#ifdef HAVE_LIBXVBA ++ XVBA::CXvbaRenderPicture *xvba; ++#endif + }; + + typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS]; +@@ -324,6 +341,7 @@ + bool m_nonLinStretch; + bool m_nonLinStretchGui; + float m_pixelRatio; ++ bool m_skipRender; + }; + + +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/OverlayRenderer.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/OverlayRenderer.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/OverlayRenderer.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/OverlayRenderer.cpp 2013-03-10 13:00:12.289988407 +0100 +@@ -89,29 +89,32 @@ + CRenderer::CRenderer() + { + m_render = 0; +- m_decode = (m_render + 1) % 2; + } + + CRenderer::~CRenderer() + { +- for(int i = 0; i < 2; i++) ++ for(int i = 0; i < NUM_BUFFERS; i++) + Release(m_buffers[i]); + } + +-void CRenderer::AddOverlay(CDVDOverlay* o, double pts) ++void CRenderer::AddOverlay(CDVDOverlay* o, double pts, int index) + { + CSingleLock lock(m_section); + ++ m_decode = index; ++ + SElement e; + e.pts = pts; + e.overlay_dvd = o->Acquire(); + m_buffers[m_decode].push_back(e); + } + +-void CRenderer::AddOverlay(COverlay* o, double pts) ++void CRenderer::AddOverlay(COverlay* o, double pts, int index) + { + CSingleLock lock(m_section); + ++ m_decode = index; ++ + SElement e; + e.pts = pts; + e.overlay = o->Acquire(); +@@ -124,18 +127,22 @@ + m_cleanup.push_back(o->Acquire()); + } + +-void CRenderer::Release(SElementV& list) ++bool CRenderer::Release(SElementV& list) + { + SElementV l = list; + list.clear(); + ++ bool change = false; + for(SElementV::iterator it = l.begin(); it != l.end(); it++) + { + if(it->overlay) + it->overlay->Release(); + if(it->overlay_dvd) + it->overlay_dvd->Release(); ++ ++ change = true; + } ++ return change; + } + + void CRenderer::Release(COverlayV& list) +@@ -151,20 +158,26 @@ + { + CSingleLock lock(m_section); + +- for(int i = 0; i < 2; i++) ++ for(int i = 0; i < m_iNumBuffers; i++) + Release(m_buffers[i]); + ++ m_render = 0; + Release(m_cleanup); + } + +-void CRenderer::Flip() ++void CRenderer::Flip(int source) + { + CSingleLock lock(m_section); ++ if( source >= 0 && source < m_iNumBuffers ) ++ m_render = source; ++ else ++ m_render = (m_render + 1) % m_iNumBuffers; ++} + +- m_render = m_decode; +- m_decode =(m_decode + 1) % 2; +- +- Release(m_buffers[m_decode]); ++long CRenderer::ReleaseBuffer(int idx) ++{ ++ CSingleLock lock(m_section); ++ return Release(m_buffers[idx]); + } + + void CRenderer::Render() +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/OverlayRenderer.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/OverlayRenderer.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/OverlayRenderer.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/OverlayRenderer.h 2013-03-10 13:00:12.289988407 +0100 +@@ -23,6 +23,7 @@ + #pragma once + + #include "threads/CriticalSection.h" ++#include "BaseRenderer.h" + + #include + +@@ -92,12 +93,14 @@ + CRenderer(); + ~CRenderer(); + +- void AddOverlay(CDVDOverlay* o, double pts); +- void AddOverlay(COverlay* o, double pts); ++ void AddOverlay(CDVDOverlay* o, double pts, int index); ++ void AddOverlay(COverlay* o, double pts, int index); + void AddCleanup(COverlay* o); +- void Flip(); ++ void Flip(int source); + void Render(); + void Flush(); ++ void SetNumBuffers(int numBuffers) { m_iNumBuffers = numBuffers; } ++ long ReleaseBuffer(int idx); + + protected: + +@@ -121,10 +124,11 @@ + COverlay* Convert(CDVDOverlaySSA* o, double pts); + + void Release(COverlayV& list); +- void Release(SElementV& list); ++ bool Release(SElementV& list); + + CCriticalSection m_section; +- SElementV m_buffers[2]; ++ SElementV m_buffers[NUM_BUFFERS]; ++ int m_iNumBuffers; + int m_decode; + int m_render; + +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderFormats.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderFormats.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderFormats.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderFormats.h 2013-03-10 13:00:12.323988163 +0100 +@@ -26,6 +26,7 @@ + RENDER_FMT_YUV420P10, + RENDER_FMT_YUV420P16, + RENDER_FMT_VDPAU, ++ RENDER_FMT_VDPAU_420, + RENDER_FMT_NV12, + RENDER_FMT_UYVY422, + RENDER_FMT_YUYV422, +@@ -34,6 +35,7 @@ + RENDER_FMT_OMXEGL, + RENDER_FMT_CVBREF, + RENDER_FMT_BYPASS, ++ RENDER_FMT_XVBA, + }; + + #endif +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderManager.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderManager.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderManager.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderManager.cpp 2013-03-10 13:00:12.333988091 +0100 +@@ -28,6 +28,7 @@ + #include "utils/MathUtils.h" + #include "threads/SingleLock.h" + #include "utils/log.h" ++#include "utils/TimeUtils.h" + + #include "Application.h" + #include "ApplicationMessenger.h" +@@ -227,7 +228,7 @@ + return state; + } + +-bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation) ++bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering) + { + /* make sure any queued frame was fully presented */ + double timeout = m_presenttime + 0.1; +@@ -247,6 +248,9 @@ + return false; + } + ++ // set buffering ++ m_bCodecSupportsBuffering = buffering; ++ + bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation); + if(result) + { +@@ -261,6 +265,8 @@ + m_bReconfigured = true; + m_presentstep = PRESENT_IDLE; + m_presentevent.Set(); ++ ResetRenderBuffer(); ++ EnableBuffering(buffering); + } + + return result; +@@ -292,9 +298,13 @@ + if (!m_pRenderer) + return; + ++ if (m_presentstep == PRESENT_IDLE) ++ PrepareNextRender(); ++ + if(m_presentstep == PRESENT_FLIP) + { +- m_overlays.Flip(); ++ FlipRenderBuffer(); ++ m_overlays.Flip(m_presentsource); + m_pRenderer->FlipPage(m_presentsource); + m_presentstep = PRESENT_FRAME; + m_presentevent.Set(); +@@ -338,6 +348,10 @@ + + UpdateDisplayLatency(); + ++ m_bUseBuffering = false; ++ m_bCodecSupportsBuffering = true; ++ ResetRenderBuffer(); ++ + return m_pRenderer->PreInit(); + } + +@@ -366,7 +380,9 @@ + + CRetakeLock lock(m_sharedSection); + m_pRenderer->Flush(); ++ m_overlays.Flush(); + m_flushEvent.Set(); ++ ResetRenderBuffer(); + } + else + { +@@ -534,25 +550,21 @@ + m_pRenderer->SetViewMode(iViewMode); + } + +-void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) ++void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0LL*/, double pts /* = 0 */, int source /*= -1*/, EFIELDSYNC sync /*= FS_NONE*/) + { +- if(timestamp - GetPresentTime() > MAXPRESENTDELAY) +- timestamp = GetPresentTime() + MAXPRESENTDELAY; +- +- /* can't flip, untill timestamp */ +- if(!g_graphicsContext.IsFullScreenVideo()) +- WaitPresentTime(timestamp); +- +- /* make sure any queued frame was fully presented */ +- double timeout = m_presenttime + 1.0; +- while(m_presentstep != PRESENT_IDLE && !bStop) ++ if (!m_bUseBuffering) + { +- if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) ++ /* make sure any queued frame was fully presented */ ++ double timeout = m_presenttime + 1.0; ++ while(m_presentstep != PRESENT_IDLE && !bStop) + { +- CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for previous frame"); +- return; ++ if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) ++ { ++ CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for previous frame"); ++ return; ++ } + } +- }; ++ } + + if(bStop) + return; +@@ -560,58 +572,70 @@ + { CRetakeLock lock(m_sharedSection); + if(!m_pRenderer) return; + +- m_presenttime = timestamp; +- m_presentfield = sync; +- m_presentstep = PRESENT_FLIP; +- m_presentsource = source; ++ EFIELDSYNC presentfield = sync; ++ EPRESENTMETHOD presentmethod; ++ + EDEINTERLACEMODE deinterlacemode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; + EINTERLACEMETHOD interlacemethod = AutoInterlaceMethodInternal(g_settings.m_currentVideoSettings.m_InterlaceMethod); + + bool invert = false; + + if (deinterlacemode == VS_DEINTERLACEMODE_OFF) +- m_presentmethod = PRESENT_METHOD_SINGLE; ++ presentmethod = PRESENT_METHOD_SINGLE; + else + { +- if (deinterlacemode == VS_DEINTERLACEMODE_AUTO && m_presentfield == FS_NONE) +- m_presentmethod = PRESENT_METHOD_SINGLE; ++ if (deinterlacemode == VS_DEINTERLACEMODE_AUTO && presentfield == FS_NONE) ++ presentmethod = PRESENT_METHOD_SINGLE; + else + { +- if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BLEND) m_presentmethod = PRESENT_METHOD_BLEND; +- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE) m_presentmethod = PRESENT_METHOD_WEAVE; +- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE_INVERTED) { m_presentmethod = PRESENT_METHOD_WEAVE ; invert = true; } +- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB) m_presentmethod = PRESENT_METHOD_BOB; +- else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB_INVERTED) { m_presentmethod = PRESENT_METHOD_BOB; invert = true; } +- else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BOB) m_presentmethod = PRESENT_METHOD_BOB; +- else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BEST) m_presentmethod = PRESENT_METHOD_BOB; +- else m_presentmethod = PRESENT_METHOD_SINGLE; ++ if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BLEND) presentmethod = PRESENT_METHOD_BLEND; ++ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE) presentmethod = PRESENT_METHOD_WEAVE; ++ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_WEAVE_INVERTED) { presentmethod = PRESENT_METHOD_WEAVE ; invert = true; } ++ else if (interlacemethod == VS_INTERLACEMETHOD_RENDER_BOB) presentmethod = PRESENT_METHOD_BOB; ++ 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 presentmethod = PRESENT_METHOD_SINGLE; + + /* default to odd field if we want to deinterlace and don't know better */ +- if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && m_presentfield == FS_NONE) +- m_presentfield = FS_TOP; ++ if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && presentfield == FS_NONE) ++ presentfield = FS_TOP; + + /* invert present field */ + if(invert) + { +- if( m_presentfield == FS_BOT ) +- m_presentfield = FS_TOP; ++ if( presentfield == FS_BOT ) ++ presentfield = FS_TOP; + else +- m_presentfield = FS_BOT; ++ presentfield = FS_BOT; + } + } + } + ++ if (FlipFreeBuffer() >= 0) ++ { ++ m_renderBuffers[m_iOutputRenderBuffer].pts = pts; ++ m_renderBuffers[m_iOutputRenderBuffer].timestamp = timestamp; ++ m_renderBuffers[m_iOutputRenderBuffer].presentfield = presentfield; ++ m_renderBuffers[m_iOutputRenderBuffer].presentmethod = presentmethod; ++ if (!m_bUseBuffering) ++ PrepareNextRender(); ++ } + } + + g_application.NewFrame(); +- /* wait untill render thread have flipped buffers */ +- timeout = m_presenttime + 1.0; +- while(m_presentstep == PRESENT_FLIP && !bStop) ++ ++ if (!m_bUseBuffering) + { +- if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) ++ /* wait untill render thread have flipped buffers */ ++ double timeout = m_presenttime + 1.0; ++ while(m_presentstep == PRESENT_FLIP && !bStop) + { +- CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for flip to complete"); +- return; ++ if(!m_presentevent.WaitMSec(100) && GetPresentTime() > timeout && !bStop) ++ { ++ CLog::Log(LOGWARNING, "CRenderManager::FlipPage - timeout waiting for flip to complete"); ++ return; ++ } + } + } + } +@@ -675,9 +699,13 @@ + if (!m_pRenderer) + return; + ++ if (m_presentstep == PRESENT_IDLE) ++ PrepareNextRender(); ++ + if(m_presentstep == PRESENT_FLIP) + { +- m_overlays.Flip(); ++ FlipRenderBuffer(); ++ m_overlays.Flip(m_presentsource); + m_pRenderer->FlipPage(m_presentsource); + m_presentstep = PRESENT_FRAME; + m_presentevent.Set(); +@@ -800,14 +828,17 @@ + if (!m_pRenderer) + return -1; + +- if(m_pRenderer->AddVideoPicture(&pic)) ++ int index = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; ++ ++ if(m_pRenderer->AddVideoPicture(&pic, index)) ++ { ++ m_bRenderBufferUsed = true; + return 1; ++ } + + YV12Image image; +- int index = m_pRenderer->GetImage(&image); +- +- if(index < 0) +- return index; ++ if (m_pRenderer->GetImage(&image, index) < 0) ++ return -1; + + if(pic.format == RENDER_FMT_YUV420P + || pic.format == RENDER_FMT_YUV420P10 +@@ -829,26 +860,39 @@ + CDVDCodecUtils::CopyDXVA2Picture(&image, &pic); + } + #ifdef HAVE_LIBVDPAU +- else if(pic.format == RENDER_FMT_VDPAU) +- m_pRenderer->AddProcessor(pic.vdpau); ++ else if(pic.format == RENDER_FMT_VDPAU ++ || pic.format == RENDER_FMT_VDPAU_420) ++ m_pRenderer->AddProcessor(pic.vdpau, index); + #endif + #ifdef HAVE_LIBOPENMAX + else if(pic.format == RENDER_FMT_OMXEGL) +- m_pRenderer->AddProcessor(pic.openMax, &pic); ++ m_pRenderer->AddProcessor(pic.openMax, &pic, index); + #endif + #ifdef TARGET_DARWIN + else if(pic.format == RENDER_FMT_CVBREF) +- m_pRenderer->AddProcessor(pic.cvBufferRef); ++ m_pRenderer->AddProcessor(pic.cvBufferRef, index); + #endif + #ifdef HAVE_LIBVA + else if(pic.format == RENDER_FMT_VAAPI) +- m_pRenderer->AddProcessor(*pic.vaapi); ++ m_pRenderer->AddProcessor(*pic.vaapi, index); ++#endif ++#ifdef HAVE_LIBXVBA ++ else if(pic.format == RENDER_FMT_XVBA) ++ m_pRenderer->AddProcessor(pic.xvba, index); + #endif + m_pRenderer->ReleaseImage(index, false); + ++ m_bRenderBufferUsed = true; + return index; + } + ++void CXBMCRenderManager::AddOverlay(CDVDOverlay* o, double pts) ++{ ++ CSharedLock lock(m_sharedSection); ++ m_overlays.AddOverlay(o, pts, (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); ++ m_bRenderBufferUsed = true; ++} ++ + bool CXBMCRenderManager::Supports(ERENDERFEATURE feature) + { + CSharedLock lock(m_sharedSection); +@@ -904,3 +948,227 @@ + + return mInt; + } ++ ++int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout) ++{ ++ CSharedLock lock(m_sharedSection); ++ if (!m_pRenderer) ++ return -1; ++ ++ XbmcThreads::EndTime endtime(timeout); ++ while(!HasFreeBuffer() && !bStop) ++ { ++ lock.Leave(); ++ m_flipEvent.WaitMSec(std::min(50, timeout)); ++ if(endtime.IsTimePast()) ++ { ++ if (timeout != 0 && !bStop) ++ CLog::Log(LOGWARNING, "CRenderManager::WaitForBuffer - timeout waiting for buffer"); ++ return -1; ++ } ++ lock.Enter(); ++ } ++ lock.Leave(); ++ ++ if (bStop) ++ return -1; ++ ++ // make sure overlay buffer is released, this won't happen on AddOverlay ++ m_overlays.ReleaseBuffer((m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers); ++ return 1; ++} ++ ++int CXBMCRenderManager::GetNextRenderBufferIndex() ++{ ++ if (m_iOutputRenderBuffer == m_iCurrentRenderBuffer) ++ return -1; ++ return (m_iCurrentRenderBuffer + 1) % m_iNumRenderBuffers; ++} ++ ++void CXBMCRenderManager::FlipRenderBuffer() ++{ ++ m_iCurrentRenderBuffer = GetNextRenderBufferIndex(); ++} ++ ++int CXBMCRenderManager::FlipFreeBuffer() ++{ ++ // See "Render Buffer State Description" in header for information. ++ if (HasFreeBuffer()) ++ { ++ if (!m_bRenderBufferUsed && !m_bOverlayReleased) ++ { ++ return -1; ++ } ++ m_bRenderBufferUsed = false; ++ m_bOverlayReleased = false; ++ m_bAllRenderBuffersDisplayed = false; ++ m_iOutputRenderBuffer = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; ++ return m_iOutputRenderBuffer; ++ } ++ else ++ return -1; ++} ++ ++bool CXBMCRenderManager::HasFreeBuffer() ++{ ++ if (!m_bUseBuffering) ++ { ++ if (m_iOutputRenderBuffer != m_iCurrentRenderBuffer) ++ return false; ++ else ++ return true; ++ } ++ ++ int outputPlus1 = (m_iOutputRenderBuffer + 1) % m_iNumRenderBuffers; ++ if ((m_iOutputRenderBuffer == m_iDisplayedRenderBuffer && !m_bAllRenderBuffersDisplayed) ++ || outputPlus1 == m_iCurrentRenderBuffer) ++ return false; ++ else ++ return true; ++} ++ ++void CXBMCRenderManager::ResetRenderBuffer() ++{ ++ m_iNumRenderBuffers = m_pRenderer->GetMaxBufferSize(); ++ m_iNumRenderBuffers = std::min(5, m_iNumRenderBuffers); ++ m_iNumRenderBuffers = std::max(2, m_iNumRenderBuffers); ++ ++ if (!m_bCodecSupportsBuffering) ++ m_iNumRenderBuffers = 2; ++ ++ CLog::Log(LOGNOTICE,"CXBMCRenderManager::ResetRenderBuffer - using %d render buffers", m_iNumRenderBuffers); ++ m_overlays.SetNumBuffers(m_iNumRenderBuffers); ++ m_pRenderer->SetBufferSize(m_iNumRenderBuffers); ++ ++ m_iCurrentRenderBuffer = 0; ++ m_iOutputRenderBuffer = 0; ++ m_iDisplayedRenderBuffer = 0; ++ m_bAllRenderBuffersDisplayed = true; ++ m_sleeptime = 1.0; ++ m_speed = DVD_PLAYSPEED_NORMAL; ++ m_presentPts = DVD_NOPTS_VALUE; ++ m_bRenderBufferUsed = false; ++ m_bOverlayReleased = false; ++} ++ ++void CXBMCRenderManager::PrepareNextRender() ++{ ++ int idx = GetNextRenderBufferIndex(); ++ if (idx < 0) ++ { ++ if (m_speed >= DVD_PLAYSPEED_NORMAL && g_graphicsContext.IsFullScreenVideo()) ++ CLog::Log(LOGDEBUG,"%s no buffer, out: %d, current: %d, display: %d", ++ __FUNCTION__, m_iOutputRenderBuffer, m_iCurrentRenderBuffer, m_iDisplayedRenderBuffer); ++ return; ++ } ++ ++ double clocktime = GetPresentTime(); ++ double frametime = 1 / g_graphicsContext.GetFPS(); ++ ++ // look ahead in the queue ++ // if the next frame is already late, skip the one we are about to render ++// while (idx != m_iOutputRenderBuffer) ++// { ++// int idx_next = (idx + 1) % m_iNumRenderBuffers; ++// if (m_renderBuffers[idx_next].timestamp <= clocktime) ++// { ++// FlipRenderBuffer(); ++// idx = GetNextRenderBufferIndex(); ++// CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); ++// } ++// else ++// break; ++// } ++ ++ double presenttime = m_renderBuffers[idx].timestamp; ++ ++ if(presenttime - clocktime > MAXPRESENTDELAY) ++ presenttime = clocktime + MAXPRESENTDELAY; ++ ++ m_sleeptime = presenttime - clocktime; ++ ++ if (g_graphicsContext.IsFullScreenVideo() || presenttime <= clocktime + frametime) ++ { ++ m_presentPts = m_renderBuffers[idx].pts; ++ m_presenttime = presenttime; ++ m_presentmethod = m_renderBuffers[idx].presentmethod; ++ m_presentfield = m_renderBuffers[idx].presentfield; ++ m_presentstep = PRESENT_FLIP; ++ m_presentsource = idx; ++ } ++} ++ ++void CXBMCRenderManager::EnableBuffering(bool enable) ++{ ++ CRetakeLock lock(m_sharedSection); ++ ++ if (m_iNumRenderBuffers < 3) ++ { ++ m_bUseBuffering = false; ++ return; ++ } ++ ++ m_bUseBuffering = enable; ++ if (!m_bUseBuffering) ++ m_iOutputRenderBuffer = m_iCurrentRenderBuffer; ++ ++ CLog::Log(LOGDEBUG, "CXBMCRenderManager::EnableBuffering - %d", m_bUseBuffering); ++} ++ ++void CXBMCRenderManager::DiscardBuffer() ++{ ++ CRetakeLock lock(m_sharedSection); ++ m_iOutputRenderBuffer = m_iCurrentRenderBuffer; ++} ++ ++void CXBMCRenderManager::SetSpeed(int speed) ++{ ++ m_speed = speed; ++} ++ ++void CXBMCRenderManager::NotifyDisplayFlip() ++{ ++ CRetakeLock lock(m_sharedSection); ++ if (!m_pRenderer) ++ return; ++ ++ if (m_iNumRenderBuffers >= 3) ++ { ++ int last = m_iDisplayedRenderBuffer; ++ m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; ++ ++ if (last != m_iDisplayedRenderBuffer ++ && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) ++ { ++ m_pRenderer->ReleaseBuffer(m_iDisplayedRenderBuffer); ++ if (m_overlays.ReleaseBuffer(m_iDisplayedRenderBuffer)) ++ m_bOverlayReleased = true; ++ } ++ } ++ ++ lock.Leave(); ++ m_flipEvent.Set(); ++} ++ ++bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel) ++{ ++ CSharedLock lock(m_sharedSection); ++ sleeptime = m_sleeptime; ++ pts = m_presentPts; ++ if (m_iNumRenderBuffers < 3) ++ bufferLevel = -1; ++ else ++ bufferLevel = (m_iOutputRenderBuffer - m_iCurrentRenderBuffer + m_iNumRenderBuffers) % m_iNumRenderBuffers; ++ return true; ++} ++ ++bool CXBMCRenderManager::HasFrame() ++{ ++ CSharedLock lock(m_sharedSection); ++ if (m_presentstep == PRESENT_IDLE && ++ GetNextRenderBufferIndex() < 0 && ++ m_speed > 0) ++ return false; ++ else ++ return true; ++} +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderManager.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderManager.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/RenderManager.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/RenderManager.h 2013-03-10 13:00:12.295988364 +0100 +@@ -31,10 +31,11 @@ + #include "OverlayRenderer.h" + + class CRenderCapture; ++class CDVDClock; + + namespace DXVA { class CProcessor; } + namespace VAAPI { class CSurfaceHolder; } +-class CVDPAU; ++namespace VDPAU { class CVdpauRenderPicture; } + struct DVDVideoPicture; + + #define ERRORBUFFSIZE 30 +@@ -65,21 +66,44 @@ + void SetViewMode(int iViewMode); + + // Functions called from mplayer +- bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation); ++ /** ++ * Called by video player to configure renderer ++ * @param width width of decoded frame ++ * @param height height of decoded frame ++ * @param d_width displayed width of frame (aspect ratio) ++ * @param d_height displayed height of frame ++ * @param fps frames per second of video ++ * @param flags see RenderFlags.h ++ * @param format see RenderFormats.h ++ * @param extended_format used by DXVA ++ * @param orientation ++ * @param buffering enable buffering in renderer, defaults to false ++ */ ++ bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, bool buffering = false); + bool IsConfigured(); + + int AddVideoPicture(DVDVideoPicture& picture); + +- void FlipPage(volatile bool& bStop, double timestamp = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); ++ /** ++ * Called by video player to flip render buffers ++ * If buffering is enabled this method does not block. In case of disabled buffering ++ * this method blocks waiting for the render thread to pass by. ++ * When buffering is used there might be no free buffer available after the call to ++ * this method. Player has to call WaitForBuffer. A free buffer will become ++ * available after the main thread has flipped front / back buffers. ++ * ++ * @param bStop reference to stop flag of calling thread ++ * @param timestamp of frame delivered with AddVideoPicture ++ * @param pts used for lateness detection ++ * @param source depreciated ++ * @param sync signals frame, top, or bottom field ++ */ ++ void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE); + unsigned int PreInit(); + void UnInit(); + bool Flush(); + +- void AddOverlay(CDVDOverlay* o, double pts) +- { +- CSharedLock lock(m_sharedSection); +- m_overlays.AddOverlay(o, pts); +- } ++ void AddOverlay(CDVDOverlay* o, double pts); + + void AddCleanup(OVERLAY::COverlay* o) + { +@@ -132,6 +156,49 @@ + + void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn); + ++ /** ++ * If player uses buffering it has to wait for a buffer before it calls ++ * AddVideoPicture and AddOverlay. It waits for max 50 ms before it returns -1 ++ * in case no buffer is available. Player may call this in a loop and decides ++ * by itself when it wants to drop a frame. ++ * If no buffering is requested in Configure, player does not need to call this, ++ * because FlipPage will block. ++ */ ++ int WaitForBuffer(volatile bool& bStop, int timeout = 100); ++ ++ /** ++ * Called by application right after flip. The buffer which has been rendered to ++ * display becomes available for player to deliver a new frame. ++ */ ++ void NotifyDisplayFlip(); ++ ++ /** ++ * Called by application (main thread) to query if there is any frame to render ++ */ ++ bool HasFrame(); ++ ++ /** ++ * Can be called by player for lateness detection. This is done best by ++ * looking at the end of the queue. ++ */ ++ bool GetStats(double &sleeptime, double &pts, int &bufferLevel); ++ ++ /** ++ * Video player can dynamically enable/disable buffering. In situations like ++ * rewind buffering is not ideal. ++ */ ++ void EnableBuffering(bool enable); ++ ++ /** ++ * Video player call this on flush in oder to discard any queued frames ++ */ ++ void DiscardBuffer(); ++ ++ /** ++ * notify RenderManager about play speed ++ */ ++ void SetSpeed(int speed); ++ + protected: + void Render(bool clear, DWORD flags, DWORD alpha); + +@@ -139,6 +206,13 @@ + void PresentFields(bool clear, DWORD flags, DWORD alpha); + void PresentBlend(bool clear, DWORD flags, DWORD alpha); + ++ int GetNextRenderBufferIndex(); ++ void FlipRenderBuffer(); ++ int FlipFreeBuffer(); ++ bool HasFreeBuffer(); ++ void ResetRenderBuffer(); ++ void PrepareNextRender(); ++ + EINTERLACEMETHOD AutoInterlaceMethodInternal(EINTERLACEMETHOD mInt); + + bool m_bPauseDrawing; // true if we should pause rendering +@@ -169,6 +243,40 @@ + double m_displayLatency; + void UpdateDisplayLatency(); + ++ // Render Buffer State Description: ++ // ++ // Output: is the buffer about to or having its texture prepared for render (ie from output thread). ++ // Cannot go past the "Displayed" buffer (otherwise we will probably overwrite buffers not yet ++ // displayed or even rendered). ++ // Current: is the current buffer being or having been submitted for render to back buffer. ++ // Cannot go past "Output" buffer (else it would be rendering old output). ++ // Displayed: is the buffer that is now considered to be safely copied from back buffer to front buffer ++ // (we assume that after two swap-buffer flips for the same "Current" render buffer that that ++ // buffer will be safe, but otherwise we consider that only the previous-to-"Current" is guaranteed). ++ ++ int m_iCurrentRenderBuffer; ++ int m_iNumRenderBuffers; ++ int m_iOutputRenderBuffer; ++ int m_iDisplayedRenderBuffer; ++ bool m_bAllRenderBuffersDisplayed; ++ bool m_bUseBuffering; ++ bool m_bCodecSupportsBuffering; ++ int m_speed; ++ bool m_bRenderBufferUsed; ++ bool m_bOverlayReleased; ++ CEvent m_flipEvent; ++ ++ struct ++ { ++ double pts; ++ double timestamp; ++ EFIELDSYNC presentfield; ++ EPRESENTMETHOD presentmethod; ++ }m_renderBuffers[5]; ++ ++ double m_sleeptime; ++ double m_presentPts; ++ + double m_presenttime; + double m_presentcorr; + double m_presenterr; +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp 2013-03-10 13:00:12.295988364 +0100 +@@ -201,6 +201,8 @@ + m_defines += "#define XBMC_YUY2\n"; + else if (m_format == RENDER_FMT_UYVY422) + m_defines += "#define XBMC_UYVY\n"; ++ else if (RENDER_FMT_VDPAU_420) ++ m_defines += "#define XBMC_VDPAU_NV12\n"; + else + CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); + +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/WinRenderer.cpp xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/WinRenderer.cpp +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/WinRenderer.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/WinRenderer.cpp 2013-03-10 13:00:12.278988486 +0100 +@@ -103,21 +103,19 @@ + + void CWinRenderer::ManageTextures() + { +- int neededbuffers = 2; +- +- if( m_NumYV12Buffers < neededbuffers ) ++ if( m_NumYV12Buffers < m_neededBuffers ) + { +- for(int i = m_NumYV12Buffers; i neededbuffers ) ++ else if( m_NumYV12Buffers > m_neededBuffers ) + { +- m_NumYV12Buffers = neededbuffers; ++ m_NumYV12Buffers = m_neededBuffers; + m_iYV12RenderBuffer = m_iYV12RenderBuffer % m_NumYV12Buffers; + +- for(int i = m_NumYV12Buffers-1; i>=neededbuffers;i--) ++ for(int i = m_NumYV12Buffers-1; i>=m_neededBuffers;i--) + DeleteYV12Texture(i); + } + } +@@ -253,12 +251,12 @@ + return -1; + } + +-bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture) ++bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture, int index) + { + if (m_renderMethod == RENDER_DXVA) + { +- int source = NextYV12Texture(); +- if(source < 0) ++ int source = index; ++ if(source < 0 || NextYV12Texture() < 0) + return false; + + DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source]; +@@ -274,7 +272,7 @@ + if( source == AUTOSOURCE ) + source = NextYV12Texture(); + +- if( source < 0 ) ++ if( source < 0 || NextYV12Texture() < 0) + return -1; + + YUVBuffer *buf = (YUVBuffer*)m_VideoBuffers[source]; +diff -Naur xbmc-12.0.4/xbmc/cores/VideoRenderers/WinRenderer.h xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/WinRenderer.h +--- xbmc-12.0.4/xbmc/cores/VideoRenderers/WinRenderer.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/cores/VideoRenderers/WinRenderer.h 2013-03-10 13:00:12.285988435 +0100 +@@ -32,14 +32,6 @@ + #include "cores/VideoRenderers/RenderFlags.h" + #include "cores/VideoRenderers/RenderFormats.h" + +-//#define MP_DIRECTRENDERING +- +-#ifdef MP_DIRECTRENDERING +-#define NUM_BUFFERS 3 +-#else +-#define NUM_BUFFERS 2 +-#endif +- + #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) + #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a )) + +@@ -157,7 +149,7 @@ + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation); + virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false); + virtual void ReleaseImage(int source, bool preserve = false); +- virtual bool AddVideoPicture(DVDVideoPicture* picture); ++ virtual bool AddVideoPicture(DVDVideoPicture* picture, int index); + virtual void FlipPage(int source); + virtual unsigned int PreInit(); + virtual void UnInit(); +@@ -176,6 +168,8 @@ + void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); + + virtual unsigned int GetProcessorSize() { return m_processor.Size(); } ++ virtual void SetBufferSize(int numBuffers) { m_neededBuffers = numBuffers; } ++ virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; } + + protected: + virtual void Render(DWORD flags); +@@ -245,6 +239,8 @@ + // the separable HQ scalers need this info, but could the m_destRect be used instead? + unsigned int m_destWidth; + unsigned int m_destHeight; ++ ++ int m_neededBuffers; + }; + + #else +diff -Naur xbmc-12.0.4/xbmc/input/XBMC_keytable.cpp xbmc-12.0.4.patch/xbmc/input/XBMC_keytable.cpp +--- xbmc-12.0.4/xbmc/input/XBMC_keytable.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/input/XBMC_keytable.cpp 2013-03-10 13:00:12.316988213 +0100 +@@ -179,6 +179,8 @@ + , { XBMCK_LAUNCH_APP2, 0, 0, XBMCVK_LAUNCH_APP2, "launch_app2_pc_icon" } + , { XBMCK_LAUNCH_FILE_BROWSER, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER, "launch_file_browser" } + , { XBMCK_LAUNCH_MEDIA_CENTER, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER, "launch_media_center" } ++, { XBMCK_PLAY, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE, "play_pause" } ++, { XBMCK_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" } + + // Function keys + , { XBMCK_F1, 0, 0, XBMCVK_F1, "f1"} +diff -Naur xbmc-12.0.4/xbmc/powermanagement/PowerManager.cpp xbmc-12.0.4.patch/xbmc/powermanagement/PowerManager.cpp +--- xbmc-12.0.4/xbmc/powermanagement/PowerManager.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/powermanagement/PowerManager.cpp 2013-03-10 13:00:12.330988113 +0100 +@@ -223,11 +223,6 @@ #if defined(_WIN32) ShowWindow(g_hWnd,SW_RESTORE); SetForegroundWindow(g_hWnd); @@ -20547,181 +12500,10 @@ index a5534c9..7e2ddc6 100644 #endif } g_application.ResetScreenSaver(); --- -1.7.10 - - -From b1420829ab0a6ab832f2bf36ed49a46e6e5e8d9f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 80/88] xrandr: set screen on mode change command - ---- - xbmc/windowing/X11/XRandR.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp -index 7a16488..6531ba3 100644 ---- a/xbmc/windowing/X11/XRandR.cpp -+++ b/xbmc/windowing/X11/XRandR.cpp -@@ -246,7 +246,7 @@ bool CXRandR::SetMode(XOutput output, XMode mode) - m_currentMode = modeFound.id; - char cmd[255]; - if (getenv("XBMC_BIN_HOME")) -- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str()); -+ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); - else - return false; - CLog::Log(LOGINFO, "XRANDR: %s", cmd); --- -1.7.10 - - -From 2855a651752902838fd69fd298261cd9770132c0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 81/88] X11: recreate glx context when output changes - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- - xbmc/windowing/X11/WinSystemX11.h | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index e4e25b2..b87e264 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -409,11 +409,11 @@ bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) - return true; - } - --bool CWinSystemX11::RefreshGlxContext() -+bool CWinSystemX11::RefreshGlxContext(bool force) - { - bool retVal = false; - -- if (m_glContext) -+ if (m_glContext && !force) - { - CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); - glXMakeCurrent(m_dpy, None, NULL); -@@ -930,7 +930,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - } - - CDirtyRegionList dr; -- RefreshGlxContext(); -+ RefreshGlxContext(!m_currentOutput.Equals(output)); - XSync(m_dpy, FALSE); - g_graphicsContext.Clear(0); - g_graphicsContext.Flip(dr); -diff --git a/xbmc/windowing/X11/WinSystemX11.h b/xbmc/windowing/X11/WinSystemX11.h -index 0b7c10a..33b1739 100644 ---- a/xbmc/windowing/X11/WinSystemX11.h -+++ b/xbmc/windowing/X11/WinSystemX11.h -@@ -74,7 +74,7 @@ class CWinSystemX11 : public CWinSystemBase - void NotifyMouseCoverage(bool covered); - - protected: -- bool RefreshGlxContext(); -+ bool RefreshGlxContext(bool force); - void CheckDisplayEvents(); - void OnLostDevice(); - bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); --- -1.7.10 - - -From 171c0cde342915677b0b9467675eba4b89961ee8 Mon Sep 17 00:00:00 2001 -From: unknown -Date: Fri, 18 Jan 2013 15:16:38 +0100 -Subject: [PATCH 82/88] multi-screen: fix compilation on windows - ---- - xbmc/settings/GUIWindowSettingsCategory.cpp | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp -index cacb32a..cbf0acb 100644 ---- a/xbmc/settings/GUIWindowSettingsCategory.cpp -+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp -@@ -528,12 +528,14 @@ void CGUIWindowSettingsCategory::CreateSettings() - FillInRefreshRates(strSetting, g_guiSettings.GetResolution(), false); - continue; - } -+#if defined(HAS_GLX) - else if (strSetting.Equals("videoscreen.monitor")) - { - AddSetting(pSetting, group->GetWidth(), iControlID); - FillInMonitors(strSetting); - continue; - } -+#endif - else if (strSetting.Equals("lookandfeel.skintheme")) - { - AddSetting(pSetting, group->GetWidth(), iControlID); -@@ -1483,6 +1485,7 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting - // Cascade - FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); - } -+#if defined(HAS_GLX) - else if (strSetting.Equals("videoscreen.monitor")) - { - CSettingString *pSettingString = (CSettingString *)pSettingControl->GetSetting(); -@@ -1497,6 +1500,7 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting - FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); - } - } -+#endif - else if (strSetting.Equals("videoscreen.resolution")) - { - RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution"); -@@ -2451,6 +2455,7 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES - - void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) - { -+#if defined(HAS_GLX) - // we expect "videoscreen.monitor" but it might be hidden on some platforms, - // so check that we actually have a visable control. - BaseSettingControlPtr control = GetSetting(strSetting); -@@ -2476,6 +2481,7 @@ void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) - pControl->SetValue(currentMonitor); - g_guiSettings.SetString("videoscreen.monitor", g_settings.m_ResInfo[RES_DESKTOP].strOutput); - } -+#endif - } - - -@@ -2607,7 +2613,10 @@ void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes) - RESOLUTION lastRes = g_graphicsContext.GetVideoResolution(); - bool cancelled = false; - -- bool outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); -+ bool outputChanged = true; -+#if defined(HAS_GLX) -+ outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); -+#endif - - g_guiSettings.SetResolution(nextRes); - g_graphicsContext.SetVideoResolution(nextRes, outputChanged); --- -1.7.10 - - -From b4c3030639f4f89678d96597596c98ed49abb8c0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 14 Dec 2012 14:19:15 +0100 -Subject: [PATCH 83/88] pvr: do not show selection dialog for a single menu - hook - ---- - xbmc/pvr/addons/PVRClients.cpp | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp -index ae11936..69d8b0d 100644 ---- a/xbmc/pvr/addons/PVRClients.cpp -+++ b/xbmc/pvr/addons/PVRClients.cpp -@@ -717,16 +717,19 @@ void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat) +diff -Naur xbmc-12.0.4/xbmc/pvr/addons/PVRClients.cpp xbmc-12.0.4.patch/xbmc/pvr/addons/PVRClients.cpp +--- xbmc-12.0.4/xbmc/pvr/addons/PVRClients.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/pvr/addons/PVRClients.cpp 2013-03-10 13:00:12.331988105 +0100 +@@ -717,16 +717,19 @@ if (GetConnectedClient(iClientID, client) && client->HaveMenuHooks(cat)) { hooks = client->GetMenuHooks(); @@ -20749,37 +12531,2074 @@ index ae11936..69d8b0d 100644 if (selection >= 0) client->CallMenuHook(hooks->at(selection)); } --- -1.7.10 - - -From fe99ee421cb83fea7342729fe89153c9ba4c1842 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 3 Feb 2013 08:17:16 +0100 -Subject: [PATCH 84/88] X11: use default screen parameters if no output - connected - ---- - xbmc/windowing/X11/WinSystemX11.cpp | 55 +++++++++++++++++++++-------------- - 1 file changed, 33 insertions(+), 22 deletions(-) - -diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp -index b87e264..3cadd13 100644 ---- a/xbmc/windowing/X11/WinSystemX11.cpp -+++ b/xbmc/windowing/X11/WinSystemX11.cpp -@@ -203,25 +203,27 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl +diff -Naur xbmc-12.0.4/xbmc/rendering/gl/RenderSystemGL.h xbmc-12.0.4.patch/xbmc/rendering/gl/RenderSystemGL.h +--- xbmc-12.0.4/xbmc/rendering/gl/RenderSystemGL.h 2013-03-08 13:01:27.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/rendering/gl/RenderSystemGL.h 2013-03-10 13:00:12.312988242 +0100 +@@ -44,6 +44,7 @@ + virtual bool IsExtSupported(const char* extension); + + virtual void SetVSync(bool vsync); ++ virtual void ResetVSync() { m_bVsyncInit = false; } + + virtual void SetViewPort(CRect& viewPort); + virtual void GetViewPort(CRect& viewPort); +diff -Naur xbmc-12.0.4/xbmc/settings/AdvancedSettings.cpp xbmc-12.0.4.patch/xbmc/settings/AdvancedSettings.cpp +--- xbmc-12.0.4/xbmc/settings/AdvancedSettings.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/AdvancedSettings.cpp 2013-03-10 13:00:12.327988134 +0100 +@@ -98,14 +98,18 @@ + m_videoIgnoreSecondsAtStart = 3*60; + m_videoIgnorePercentAtEnd = 8.0f; + m_videoPlayCountMinimumPercent = 90.0f; +- m_videoVDPAUScaling = false; ++ m_videoVDPAUScaling = -1; + m_videoNonLinStretchRatio = 0.5f; + m_videoEnableHighQualityHwScalers = false; + m_videoAutoScaleMaxFps = 30.0f; +- m_videoAllowMpeg4VDPAU = false; ++ m_videoAllowMpeg4VDPAU = true; + m_videoAllowMpeg4VAAPI = false; + m_videoDisableBackgroundDeinterlace = false; + m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect ++ m_videoVDPAUdeintHD = -1; ++ m_videoVDPAUdeintSD = -1; ++ m_videoVDPAUtelecine = false; ++ m_videoVDPAUdeintSkipChromaHD = false; + m_DXVACheckCompatibility = false; + m_DXVACheckCompatibilityPresent = false; + m_DXVAForceProcessorRenderer = true; +@@ -493,7 +497,7 @@ + XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp); + XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint); + XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc); +- XMLUtils::GetBoolean(pElement,"vdpauscaling",m_videoVDPAUScaling); ++ XMLUtils::GetInt(pElement,"vdpauscaling",m_videoVDPAUScaling); + XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f); + XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); + XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); +@@ -501,6 +505,10 @@ + XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI); + 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); + + TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate"); + if (pAdjustRefreshrate) +diff -Naur xbmc-12.0.4/xbmc/settings/AdvancedSettings.h xbmc-12.0.4.patch/xbmc/settings/AdvancedSettings.h +--- xbmc-12.0.4/xbmc/settings/AdvancedSettings.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/AdvancedSettings.h 2013-03-10 13:00:12.327988134 +0100 +@@ -133,6 +133,10 @@ + int m_videoPercentSeekBackwardBig; + CStdString m_videoPPFFmpegDeint; + CStdString m_videoPPFFmpegPostProc; ++ int m_videoVDPAUdeintHD; ++ int m_videoVDPAUdeintSD; ++ bool m_videoVDPAUtelecine; ++ bool m_videoVDPAUdeintSkipChromaHD; + bool m_musicUseTimeSeeking; + int m_musicTimeSeekForward; + int m_musicTimeSeekBackward; +@@ -148,7 +152,7 @@ + CStdString m_audioHost; + bool m_audioApplyDrc; + +- bool m_videoVDPAUScaling; ++ int m_videoVDPAUScaling; + float m_videoNonLinStretchRatio; + bool m_videoEnableHighQualityHwScalers; + float m_videoAutoScaleMaxFps; +diff -Naur xbmc-12.0.4/xbmc/settings/GUISettings.cpp xbmc-12.0.4.patch/xbmc/settings/GUISettings.cpp +--- xbmc-12.0.4/xbmc/settings/GUISettings.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/GUISettings.cpp 2013-03-10 13:00:12.325988148 +0100 +@@ -392,11 +392,16 @@ + AddGroup(SETTINGS_SYSTEM, 13000); + CSettingsCategory* vs = AddCategory(SETTINGS_SYSTEM, "videoscreen", 21373); + ++#if defined(HAS_GLX) ++ AddString(vs, "videoscreen.monitor", 246, "", SPIN_CONTROL_TEXT); ++#endif ++ + // this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode. + // contains a DISPLAYMODE + #if !defined(TARGET_DARWIN_IOS_ATV2) && !defined(TARGET_RASPBERRY_PI) + AddInt(vs, "videoscreen.screen", 240, 0, -1, 1, 32, SPIN_CONTROL_TEXT); + #endif ++ + // this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode. + // contains an index to the g_settings.m_ResInfo array. the only meaningful fields are iScreen, iWidth, iHeight. + #if defined(TARGET_DARWIN) +@@ -685,10 +690,14 @@ + + #ifdef HAVE_LIBVDPAU + AddBool(vp, "videoplayer.usevdpau", 13425, true); ++ AddBool(vp, "videoplayer.usevdpaumixer", 13436, true); + #endif + #ifdef HAVE_LIBVA + AddBool(vp, "videoplayer.usevaapi", 13426, true); + #endif ++#ifdef HAVE_LIBXVBA ++ AddBool(vp, "videoplayer.usexvba", 13437, true); ++#endif + #ifdef HAS_DX + AddBool(g_sysinfo.IsVistaOrHigher() ? vp: NULL, "videoplayer.usedxva2", 13427, g_sysinfo.IsVistaOrHigher() ? true : false); + #endif +@@ -763,7 +772,6 @@ + AddSeparator(vp, "videoplayer.sep1.5"); + #ifdef HAVE_LIBVDPAU + AddBool(NULL, "videoplayer.vdpauUpscalingLevel", 13121, false); +- AddBool(vp, "videoplayer.vdpaustudiolevel", 13122, false); + #endif + #endif + AddSeparator(vp, "videoplayer.sep5"); +diff -Naur xbmc-12.0.4/xbmc/settings/GUIWindowSettingsCategory.cpp xbmc-12.0.4.patch/xbmc/settings/GUIWindowSettingsCategory.cpp +--- xbmc-12.0.4/xbmc/settings/GUIWindowSettingsCategory.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/GUIWindowSettingsCategory.cpp 2013-03-10 13:00:12.331988105 +0100 +@@ -528,6 +528,14 @@ + FillInRefreshRates(strSetting, g_guiSettings.GetResolution(), false); + continue; + } ++#if defined(HAS_GLX) ++ else if (strSetting.Equals("videoscreen.monitor")) ++ { ++ AddSetting(pSetting, group->GetWidth(), iControlID); ++ FillInMonitors(strSetting); ++ continue; ++ } ++#endif + else if (strSetting.Equals("lookandfeel.skintheme")) + { + AddSetting(pSetting, group->GetWidth(), iControlID); +@@ -596,6 +604,23 @@ + pControl->SetEnabled(true); + } + } ++ else if (strSetting.Equals("videoplayer.usevdpaumixer")) ++ { ++ bool hasInterop = true; ++#ifndef GL_NV_vdpau_interop ++ hasInterop = false; ++#endif ++ CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID()); ++ if (pControl && hasInterop && glewIsSupported("GL_NV_vdpau_interop")) ++ { ++ pControl->SetEnabled(true); ++ } ++ else ++ { ++ pControl->SetEnabled(false); ++ g_guiSettings.SetBool("videoplayer.usevdpaumixer",true); ++ } ++ } + else + #endif + if (strSetting.Equals("videoscreen.resolution")) +@@ -1460,6 +1485,22 @@ + // Cascade + FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); } - - XMode currmode = g_xrandr.GetCurrentMode(out.name); -- -- // flip h/w when rotated -- if (m_bIsRotated) -+ if (!currmode.name.empty()) ++#if defined(HAS_GLX) ++ else if (strSetting.Equals("videoscreen.monitor")) ++ { ++ CSettingString *pSettingString = (CSettingString *)pSettingControl->GetSetting(); ++ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(pSettingControl->GetID()); ++ CStdString currentMonitor = pControl->GetCurrentLabel(); ++ if (!g_Windowing.IsCurrentOutput(currentMonitor)) ++ { ++ g_guiSettings.SetString("videoscreen.monitor", currentMonitor); ++ g_Windowing.UpdateResolutions(); ++ DisplayMode mode = g_guiSettings.GetInt("videoscreen.screen"); ++ // Cascade ++ FillInResolutions("videoscreen.resolution", mode, RES_DESKTOP, true); ++ } ++ } ++#endif + else if (strSetting.Equals("videoscreen.resolution")) { -- int w = mode.w; -- mode.w = mode.h; -- mode.h = w; + RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution"); +@@ -2396,11 +2437,15 @@ + if (g_advancedSettings.m_canWindowed) + pControl->AddLabel(g_localizeStrings.Get(242), -1); + ++#if !defined(HAS_GLX) + for (int idx = 0; idx < g_Windowing.GetNumScreens(); idx++) + { + strScreen.Format(g_localizeStrings.Get(241), g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen + 1); + pControl->AddLabel(strScreen, g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen); + } ++#else ++ pControl->AddLabel(g_localizeStrings.Get(244), 0); ++#endif + pControl->SetValue(mode); + g_guiSettings.SetInt("videoscreen.screen", mode); + } +@@ -2408,6 +2453,38 @@ + return mode; + } + ++void CGUIWindowSettingsCategory::FillInMonitors(CStdString strSetting) ++{ ++#if defined(HAS_GLX) ++ // we expect "videoscreen.monitor" but it might be hidden on some platforms, ++ // so check that we actually have a visable control. ++ BaseSettingControlPtr control = GetSetting(strSetting); ++ if (control) ++ { ++ control->SetDelayed(); ++ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID()); ++ pControl->Clear(); ++ ++ std::vector monitors; ++ g_Windowing.GetConnectedOutputs(&monitors); ++ ++ int currentMonitor = 0; ++ for (unsigned int i=0; iAddLabel(monitors[i], i); ++ } ++ ++ pControl->SetValue(currentMonitor); ++ g_guiSettings.SetString("videoscreen.monitor", g_settings.m_ResInfo[RES_DESKTOP].strOutput); ++ } ++#endif ++} ++ ++ + void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, DisplayMode mode, RESOLUTION res, bool UserChange) + { + BaseSettingControlPtr control = GetSetting(strSetting); +@@ -2536,13 +2613,18 @@ + RESOLUTION lastRes = g_graphicsContext.GetVideoResolution(); + bool cancelled = false; + ++ bool outputChanged = true; ++#if defined(HAS_GLX) ++ outputChanged = !g_Windowing.IsCurrentOutput(g_guiSettings.GetString("videoscreen.monitor")); ++#endif ++ + g_guiSettings.SetResolution(nextRes); +- g_graphicsContext.SetVideoResolution(nextRes); ++ g_graphicsContext.SetVideoResolution(nextRes, outputChanged); + + if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000)) + { + g_guiSettings.SetResolution(lastRes); +- g_graphicsContext.SetVideoResolution(lastRes); ++ g_graphicsContext.SetVideoResolution(lastRes, outputChanged); + + DisplayMode mode = FillInScreens("videoscreen.screen", lastRes); + FillInResolutions("videoscreen.resolution", mode, lastRes, false); +diff -Naur xbmc-12.0.4/xbmc/settings/GUIWindowSettingsCategory.h xbmc-12.0.4.patch/xbmc/settings/GUIWindowSettingsCategory.h +--- xbmc-12.0.4/xbmc/settings/GUIWindowSettingsCategory.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/GUIWindowSettingsCategory.h 2013-03-10 13:00:12.313988234 +0100 +@@ -51,6 +51,7 @@ + void FillInSoundSkins(CSetting *pSetting); + void FillInLanguages(CSetting *pSetting, const std::vector &languages = std::vector(), const std::vector &languageKeys = std::vector()); + DisplayMode FillInScreens(CStdString strSetting, RESOLUTION res); ++ void FillInMonitors(CStdString strSetting); + void FillInResolutions(CStdString strSetting, DisplayMode mode, RESOLUTION res, bool UserChange); + void FillInRefreshRates(CStdString strSetting, RESOLUTION res, bool UserChange); + void OnRefreshRateChanged(RESOLUTION resolution); +diff -Naur xbmc-12.0.4/xbmc/settings/Settings.cpp xbmc-12.0.4.patch/xbmc/settings/Settings.cpp +--- xbmc-12.0.4/xbmc/settings/Settings.cpp 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/Settings.cpp 2013-03-10 13:00:12.315988220 +0100 +@@ -55,6 +55,7 @@ + #include "filesystem/File.h" + #include "filesystem/DirectoryCache.h" + #include "DatabaseManager.h" ++#include "windowing/WindowingFactory.h" + + using namespace std; + using namespace XFILE; +diff -Naur xbmc-12.0.4/xbmc/settings/VideoSettings.h xbmc-12.0.4.patch/xbmc/settings/VideoSettings.h +--- xbmc-12.0.4/xbmc/settings/VideoSettings.h 2013-03-08 13:01:31.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/settings/VideoSettings.h 2013-03-10 13:00:12.325988148 +0100 +@@ -65,6 +65,8 @@ + VS_INTERLACEMETHOD_SW_BLEND = 20, + VS_INTERLACEMETHOD_AUTO_ION = 21, + ++ VS_INTERLACEMETHOD_XVBA = 22, ++ + VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value. + }; + +diff -Naur xbmc-12.0.4/xbmc/system.h xbmc-12.0.4.patch/xbmc/system.h +--- xbmc-12.0.4/xbmc/system.h 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/system.h 2013-03-10 13:00:12.308988270 +0100 +@@ -162,16 +162,21 @@ + #define HAS_GL + #ifdef HAVE_X11 + #define HAS_GLX ++#define HAS_X11_WIN_EVENTS + #endif + #ifdef HAVE_SDL + #define HAS_SDL + #ifndef HAS_SDL_OPENGL + #define HAS_SDL_OPENGL + #endif ++#ifndef HAVE_X11 + #define HAS_SDL_WIN_EVENTS ++#endif + #else ++#ifndef HAVE_X11 + #define HAS_LINUX_EVENTS + #endif ++#endif + #define HAS_LINUX_NETWORK + #define HAS_LIRC + #ifdef HAVE_LIBPULSE +diff -Naur xbmc-12.0.4/xbmc/utils/ActorProtocol.cpp xbmc-12.0.4.patch/xbmc/utils/ActorProtocol.cpp +--- xbmc-12.0.4/xbmc/utils/ActorProtocol.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/utils/ActorProtocol.cpp 2013-03-10 13:00:12.300988328 +0100 +@@ -0,0 +1,253 @@ ++/* ++ * Copyright (C) 2005-2012 Team XBMC ++ * http://www.xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "ActorProtocol.h" ++ ++using namespace Actor; ++ ++void Message::Release() ++{ ++ bool skip; ++ origin->Lock(); ++ skip = isSync ? !isSyncFini : false; ++ isSyncFini = true; ++ origin->Unlock(); ++ ++ if (skip) ++ return; ++ ++ // free data buffer ++ if (data != buffer) ++ delete [] data; ++ ++ // delete event in case of sync message ++ if (event) ++ delete event; ++ ++ origin->ReturnMessage(this); ++} ++ ++bool Message::Reply(int sig, void *data /* = NULL*/, int size /* = 0 */) ++{ ++ if (!isSync) ++ { ++ if (isOut) ++ return origin->SendInMessage(sig, data, size); ++ else ++ return origin->SendOutMessage(sig, data, size); ++ } ++ ++ origin->Lock(); ++ ++ if (!isSyncTimeout) ++ { ++ Message *msg = origin->GetMessage(); ++ msg->signal = sig; ++ msg->isOut = !isOut; ++ replyMessage = msg; ++ if (data) ++ { ++ if (size > MSG_INTERNAL_BUFFER_SIZE) ++ msg->data = new uint8_t[size]; ++ else ++ msg->data = msg->buffer; ++ memcpy(msg->data, data, size); ++ } ++ } ++ ++ origin->Unlock(); ++ ++ if (event) ++ event->Set(); ++ ++ return true; ++} ++ ++Protocol::~Protocol() ++{ ++ Message *msg; ++ Purge(); ++ while (!freeMessageQueue.empty()) ++ { ++ msg = freeMessageQueue.front(); ++ freeMessageQueue.pop(); ++ delete msg; ++ } ++} ++ ++Message *Protocol::GetMessage() ++{ ++ Message *msg; ++ ++ CSingleLock lock(criticalSection); ++ ++ if (!freeMessageQueue.empty()) ++ { ++ msg = freeMessageQueue.front(); ++ freeMessageQueue.pop(); ++ } ++ else ++ msg = new Message(); ++ ++ msg->isSync = false; ++ msg->isSyncFini = false; ++ msg->isSyncTimeout = false; ++ msg->event = NULL; ++ msg->data = NULL; ++ msg->payloadSize = 0; ++ msg->replyMessage = NULL; ++ msg->origin = this; ++ ++ return msg; ++} ++ ++void Protocol::ReturnMessage(Message *msg) ++{ ++ CSingleLock lock(criticalSection); ++ ++ freeMessageQueue.push(msg); ++} ++ ++bool Protocol::SendOutMessage(int signal, void *data /* = NULL */, int size /* = 0 */, Message *outMsg /* = NULL */) ++{ ++ Message *msg; ++ if (outMsg) ++ msg = outMsg; ++ else ++ msg = GetMessage(); ++ ++ msg->signal = signal; ++ msg->isOut = true; ++ ++ if (data) ++ { ++ if (size > MSG_INTERNAL_BUFFER_SIZE) ++ msg->data = new uint8_t[size]; ++ else ++ msg->data = msg->buffer; ++ memcpy(msg->data, data, size); ++ } ++ ++ { CSingleLock lock(criticalSection); ++ outMessages.push(msg); ++ } ++ containerOutEvent->Set(); ++ ++ return true; ++} ++ ++bool Protocol::SendInMessage(int signal, void *data /* = NULL */, int size /* = 0 */, Message *outMsg /* = NULL */) ++{ ++ Message *msg; ++ if (outMsg) ++ msg = outMsg; ++ else ++ msg = GetMessage(); ++ ++ msg->signal = signal; ++ msg->isOut = false; ++ ++ if (data) ++ { ++ if (size > MSG_INTERNAL_BUFFER_SIZE) ++ msg->data = new uint8_t[size]; ++ else ++ msg->data = msg->buffer; ++ memcpy(msg->data, data, size); ++ } ++ ++ { CSingleLock lock(criticalSection); ++ inMessages.push(msg); ++ } ++ containerInEvent->Set(); ++ ++ return true; ++} ++ ++ ++bool Protocol::SendOutMessageSync(int signal, Message **retMsg, int timeout, void *data /* = NULL */, int size /* = 0 */) ++{ ++ Message *msg = GetMessage(); ++ msg->isOut = true; ++ msg->isSync = true; ++ msg->event = new CEvent; ++ msg->event->Reset(); ++ SendOutMessage(signal, data, size, msg); ++ ++ if (!msg->event->WaitMSec(timeout)) ++ { ++ msg->origin->Lock(); ++ if (msg->replyMessage) ++ *retMsg = msg->replyMessage; ++ else ++ { ++ *retMsg = NULL; ++ msg->isSyncTimeout = true; ++ } ++ msg->origin->Unlock(); ++ } ++ else ++ *retMsg = msg->replyMessage; ++ ++ msg->Release(); ++ ++ if (*retMsg) ++ return true; ++ else ++ return false; ++} ++ ++bool Protocol::ReceiveOutMessage(Message **msg) ++{ ++ CSingleLock lock(criticalSection); ++ ++ if (outMessages.empty() || outDefered) ++ return false; ++ ++ *msg = outMessages.front(); ++ outMessages.pop(); ++ ++ return true; ++} ++ ++bool Protocol::ReceiveInMessage(Message **msg) ++{ ++ CSingleLock lock(criticalSection); ++ ++ if (inMessages.empty() || inDefered) ++ return false; ++ ++ *msg = inMessages.front(); ++ inMessages.pop(); ++ ++ return true; ++} ++ ++ ++void Protocol::Purge() ++{ ++ Message *msg; ++ ++ while (ReceiveInMessage(&msg)) ++ msg->Release(); ++ ++ while (ReceiveOutMessage(&msg)) ++ msg->Release(); ++} +diff -Naur xbmc-12.0.4/xbmc/utils/ActorProtocol.h xbmc-12.0.4.patch/xbmc/utils/ActorProtocol.h +--- xbmc-12.0.4/xbmc/utils/ActorProtocol.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/utils/ActorProtocol.h 2013-03-10 13:00:12.300988328 +0100 +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (C) 2005-2012 Team XBMC ++ * http://www.xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#pragma once ++ ++#include "threads/Thread.h" ++#include "utils/log.h" ++#include ++#include "memory.h" ++ ++#define MSG_INTERNAL_BUFFER_SIZE 32 ++ ++namespace Actor ++{ ++ ++class Protocol; ++ ++class Message ++{ ++ friend class Protocol; ++public: ++ int signal; ++ bool isSync; ++ bool isSyncFini; ++ bool isOut; ++ bool isSyncTimeout; ++ int payloadSize; ++ uint8_t buffer[MSG_INTERNAL_BUFFER_SIZE]; ++ uint8_t *data; ++ Message *replyMessage; ++ Protocol *origin; ++ CEvent *event; ++ ++ void Release(); ++ bool Reply(int sig, void *data = NULL, int size = 0); ++ ++private: ++ Message() {isSync = false; data = NULL; event = NULL; replyMessage = NULL;}; ++}; ++ ++class Protocol ++{ ++public: ++ Protocol(std::string name, CEvent* inEvent, CEvent *outEvent) ++ : portName(name), inDefered(false), outDefered(false) {containerInEvent = inEvent; containerOutEvent = outEvent;}; ++ virtual ~Protocol(); ++ Message *GetMessage(); ++ void ReturnMessage(Message *msg); ++ bool SendOutMessage(int signal, void *data = NULL, int size = 0, Message *outMsg = NULL); ++ bool SendInMessage(int signal, void *data = NULL, int size = 0, Message *outMsg = NULL); ++ bool SendOutMessageSync(int signal, Message **retMsg, int timeout, void *data = NULL, int size = 0); ++ bool ReceiveOutMessage(Message **msg); ++ bool ReceiveInMessage(Message **msg); ++ void Purge(); ++ void DeferIn(bool value) {inDefered = value;}; ++ void DeferOut(bool value) {outDefered = value;}; ++ void Lock() {criticalSection.lock();}; ++ void Unlock() {criticalSection.unlock();}; ++ std::string portName; ++ ++protected: ++ CEvent *containerInEvent, *containerOutEvent; ++ CCriticalSection criticalSection; ++ std::queue outMessages; ++ std::queue inMessages; ++ std::queue freeMessageQueue; ++ bool inDefered, outDefered; ++}; ++ ++} +diff -Naur xbmc-12.0.4/xbmc/utils/Makefile xbmc-12.0.4.patch/xbmc/utils/Makefile +--- xbmc-12.0.4/xbmc/utils/Makefile 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/utils/Makefile 2013-03-10 13:00:12.300988328 +0100 +@@ -70,6 +70,7 @@ + Weather.cpp \ + XBMCTinyXML.cpp \ + XMLUtils.cpp \ ++ ActorProtocol.cpp \ + + LIB=utils.a + +diff -Naur xbmc-12.0.4/xbmc/video/dialogs/GUIDialogVideoSettings.cpp xbmc-12.0.4.patch/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +--- xbmc-12.0.4/xbmc/video/dialogs/GUIDialogVideoSettings.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/video/dialogs/GUIDialogVideoSettings.cpp 2013-03-10 13:00:12.325988148 +0100 +@@ -103,13 +103,14 @@ + entries.push_back(make_pair(VS_INTERLACEMETHOD_INVERSE_TELECINE , 16314)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL , 16311)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL , 16310)); +- entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_BOB , 16021)); ++ entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_BOB , 16325)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF, 16318)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF , 16317)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE , 16314)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_DXVA_BOB , 16320)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_DXVA_BEST , 16321)); + entries.push_back(make_pair(VS_INTERLACEMETHOD_AUTO_ION , 16325)); ++ entries.push_back(make_pair(VS_INTERLACEMETHOD_XVBA , 16326)); + + /* remove unsupported methods */ + for(vector >::iterator it = entries.begin(); it != entries.end();) +diff -Naur xbmc-12.0.4/xbmc/video/VideoReferenceClock.cpp xbmc-12.0.4.patch/xbmc/video/VideoReferenceClock.cpp +--- xbmc-12.0.4/xbmc/video/VideoReferenceClock.cpp 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/video/VideoReferenceClock.cpp 2013-03-10 13:00:12.317988206 +0100 +@@ -30,6 +30,7 @@ + #include + #include + #include "windowing/WindowingFactory.h" ++ #include "guilib/GraphicContext.h" + #define NVSETTINGSCMD "nvidia-settings -nt -q RefreshRate3" + #elif defined(TARGET_DARWIN_OSX) + #include +@@ -135,12 +136,23 @@ + m_Context = NULL; + m_pixmap = None; + m_glPixmap = None; +- m_RREventBase = 0; +- m_UseNvSettings = true; ++ m_UseNvSettings = false; + m_bIsATI = false; + #endif + } + ++CVideoReferenceClock::~CVideoReferenceClock() ++{ ++#if defined(HAS_GLX) ++ // some ATI voodoo, if we don't close the display, we crash on exit ++ if (m_Dpy) ++ { ++ XCloseDisplay(m_Dpy); ++ m_Dpy = NULL; ++ } ++#endif ++} ++ + void CVideoReferenceClock::Process() + { + bool SetupSuccess = false; +@@ -151,6 +163,10 @@ + m_D3dCallback.Reset(); + g_Windowing.Register(&m_D3dCallback); + #endif ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ g_Windowing.Register(this); ++ m_xrrEvent = false; ++#endif + + while(!m_bStop) + { +@@ -211,6 +227,16 @@ + //clean up the vblank clock + #if defined(HAS_GLX) && defined(HAS_XRANDR) + CleanupGLX(); ++ if (m_xrrEvent) ++ { ++ m_releaseEvent.Set(); ++ while (!m_bStop) ++ { ++ if (m_resetEvent.WaitMSec(100)) ++ break; ++ } ++ m_xrrEvent = false; ++ } + #elif defined(_WIN32) && defined(HAS_DX) + CleanupD3D(); + #elif defined(TARGET_DARWIN) +@@ -222,6 +248,9 @@ + #if defined(_WIN32) && defined(HAS_DX) + g_Windowing.Unregister(&m_D3dCallback); + #endif ++#if defined(HAS_GLX) ++ g_Windowing.Unregister(this); ++#endif + } + + bool CVideoReferenceClock::WaitStarted(int MSecs) +@@ -231,6 +260,24 @@ + } + + #if defined(HAS_GLX) && defined(HAS_XRANDR) ++ ++void CVideoReferenceClock::OnLostDevice() ++{ ++ if (!m_xrrEvent) ++ { ++ m_releaseEvent.Reset(); ++ m_resetEvent.Reset(); ++ m_xrrEvent = true; ++ m_releaseEvent.Wait(); ++ } ++} ++ ++void CVideoReferenceClock::OnResetDevice() ++{ ++ m_xrrEvent = false; ++ m_resetEvent.Set(); ++} ++ + bool CVideoReferenceClock::SetupGLX() + { + int singleBufferAttributes[] = { +@@ -270,7 +317,7 @@ + } + + bool ExtensionFound = false; +- istringstream Extensions(glXQueryExtensionsString(m_Dpy, DefaultScreen(m_Dpy))); ++ istringstream Extensions(glXQueryExtensionsString(m_Dpy, g_Windowing.GetCurrentScreen())); + string ExtensionStr; + + while (!ExtensionFound) +@@ -297,7 +344,7 @@ + m_bIsATI = true; + } + +- m_vInfo = glXChooseVisual(m_Dpy, DefaultScreen(m_Dpy), singleBufferAttributes); ++ m_vInfo = glXChooseVisual(m_Dpy, g_Windowing.GetCurrentScreen(), singleBufferAttributes); + if (!m_vInfo) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: glXChooseVisual returned NULL"); +@@ -308,15 +355,16 @@ + { + Swa.border_pixel = 0; + Swa.event_mask = StructureNotifyMask; +- Swa.colormap = XCreateColormap(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), m_vInfo->visual, AllocNone ); ++ Swa.colormap = XCreateColormap(m_Dpy, g_Windowing.GetWindow(), m_vInfo->visual, AllocNone ); + SwaMask = CWBorderPixel | CWColormap | CWEventMask; + +- m_Window = XCreateWindow(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), 0, 0, 256, 256, 0, ++ m_Window = XCreateWindow(m_Dpy, g_Windowing.GetWindow(), 0, 0, 256, 256, 0, + m_vInfo->depth, InputOutput, m_vInfo->visual, SwaMask, &Swa); + } + else + { +- m_pixmap = XCreatePixmap(m_Dpy, DefaultRootWindow(m_Dpy), 256, 256, m_vInfo->depth); ++ Window window = g_Windowing.GetWindow(); ++ m_pixmap = XCreatePixmap(m_Dpy, window, 256, 256, m_vInfo->depth); + if (!m_pixmap) + { + CLog::Log(LOGDEBUG, "CVideoReferenceClock: unable to create pixmap"); +@@ -381,10 +429,6 @@ + return false; + } + +- //set up receiving of RandR events, we'll get one when the refreshrate changes +- XRRQueryExtension(m_Dpy, &m_RREventBase, &ReturnV); +- XRRSelectInput(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen), RRScreenChangeNotifyMask); +- + UpdateRefreshrate(true); //forced refreshrate update + m_MissedVblanks = 0; + +@@ -518,7 +562,7 @@ + int RefreshRate; + XRRScreenConfiguration *CurrInfo; + +- CurrInfo = XRRGetScreenInfo(m_Dpy, RootWindow(m_Dpy, m_vInfo->screen)); ++ CurrInfo = XRRGetScreenInfo(m_Dpy, g_Windowing.GetWindow()); + RefreshRate = XRRConfigCurrentRate(CurrInfo); + XRRFreeScreenConfigInfo(CurrInfo); + +@@ -585,6 +629,9 @@ + + while(!m_bStop) + { ++ if (m_xrrEvent) ++ return; ++ + //wait for the next vblank + if (!m_bIsATI) + { +@@ -648,7 +695,6 @@ + UpdateClock((int)(VblankCount - PrevVblankCount), true); + SingleLock.Leave(); + SendVblankSignal(); +- UpdateRefreshrate(); + IsReset = false; + } + else if (!m_bStop) +@@ -1185,23 +1231,10 @@ + + #if defined(HAS_GLX) && defined(HAS_XRANDR) + +- //check for RandR events +- bool GotEvent = Forced || m_RefreshChanged == 2; +- XEvent Event; +- while (XCheckTypedEvent(m_Dpy, m_RREventBase + RRScreenChangeNotify, &Event)) +- { +- if (Event.type == m_RREventBase + RRScreenChangeNotify) +- { +- CLog::Log(LOGDEBUG, "CVideoReferenceClock: Received RandR event %i", Event.type); +- GotEvent = true; +- } +- XRRUpdateConfiguration(&Event); - } +- + if (!Forced) + m_RefreshChanged = 0; + +- if (!GotEvent) //refreshrate did not change ++ if (!Forced) //refreshrate did not change + return false; + + //the refreshrate can be wrong on nvidia drivers, so read it from nvidia-settings when it's available +@@ -1222,7 +1255,7 @@ + } + + CSingleLock SingleLock(m_CritSection); +- m_RefreshRate = GetRandRRate(); ++ m_RefreshRate = MathUtils::round_int(g_graphicsContext.GetFPS()); + + CLog::Log(LOGDEBUG, "CVideoReferenceClock: Detected refreshrate: %i hertz", (int)m_RefreshRate); + +diff -Naur xbmc-12.0.4/xbmc/video/VideoReferenceClock.h xbmc-12.0.4.patch/xbmc/video/VideoReferenceClock.h +--- xbmc-12.0.4/xbmc/video/VideoReferenceClock.h 2013-03-08 13:01:28.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/video/VideoReferenceClock.h 2013-03-10 13:00:12.315988220 +0100 +@@ -30,6 +30,7 @@ + #include + #include + #include ++ #include "guilib/DispResource.h" + #elif defined(_WIN32) && defined(HAS_DX) + #include + #include "guilib/D3DResource.h" +@@ -56,9 +57,13 @@ + #endif + + class CVideoReferenceClock : public CThread ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ ,public IDispResource ++#endif + { + public: + CVideoReferenceClock(); ++ virtual ~CVideoReferenceClock(); + + int64_t GetTime(bool interpolated = true); + int64_t GetFrequency(); +@@ -75,6 +80,11 @@ + void VblankHandler(int64_t nowtime, double fps); + #endif + ++#if defined(HAS_GLX) && defined(HAS_XRANDR) ++ virtual void OnLostDevice(); ++ virtual void OnResetDevice(); ++#endif ++ + private: + void Process(); + bool UpdateRefreshrate(bool Forced = false); +@@ -121,7 +131,8 @@ + GLXContext m_Context; + Pixmap m_pixmap; + GLXPixmap m_glPixmap; +- int m_RREventBase; ++ bool m_xrrEvent; ++ CEvent m_releaseEvent, m_resetEvent; + + bool m_UseNvSettings; + bool m_bIsATI; +diff -Naur xbmc-12.0.4/xbmc/windowing/Makefile xbmc-12.0.4.patch/xbmc/windowing/Makefile +--- xbmc-12.0.4/xbmc/windowing/Makefile 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/Makefile 2013-03-10 13:00:12.308988270 +0100 +@@ -1,6 +1,7 @@ + SRCS=WinEventsSDL.cpp \ + WinEventsLinux.cpp \ + WinSystem.cpp \ ++ WinEventsX11.cpp \ + + LIB=windowing.a + +diff -Naur xbmc-12.0.4/xbmc/windowing/WinEvents.h xbmc-12.0.4.patch/xbmc/windowing/WinEvents.h +--- xbmc-12.0.4/xbmc/windowing/WinEvents.h 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/WinEvents.h 2013-03-10 13:00:12.308988270 +0100 +@@ -58,6 +58,10 @@ + #include "WinEventsSDL.h" + #define CWinEvents CWinEventsSDL + ++#elif defined(TARGET_LINUX) && defined(HAS_X11_WIN_EVENTS) ++#include "WinEventsX11.h" ++#define CWinEvents CWinEventsX11 ++ + #elif defined(TARGET_LINUX) && defined(HAS_LINUX_EVENTS) + #include "WinEventsLinux.h" + #define CWinEvents CWinEventsLinux +diff -Naur xbmc-12.0.4/xbmc/windowing/WinEventsX11.cpp xbmc-12.0.4.patch/xbmc/windowing/WinEventsX11.cpp +--- xbmc-12.0.4/xbmc/windowing/WinEventsX11.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/WinEventsX11.cpp 2013-03-10 13:00:12.330988113 +0100 +@@ -0,0 +1,750 @@ ++/* ++* Copyright (C) 2005-2012 Team XBMC ++* http://www.xbmc.org ++* ++* This Program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation; either version 2, or (at your option) ++* any later version. ++* ++* This Program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++* GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License ++* along with XBMC; see the file COPYING. If not, write to ++* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++* http://www.gnu.org/copyleft/gpl.html ++* ++*/ ++ ++#include "system.h" ++ ++#ifdef HAS_X11_WIN_EVENTS ++ ++#include "WinEvents.h" ++#include "WinEventsX11.h" ++#include "Application.h" ++#include "ApplicationMessenger.h" ++#include ++#include "X11/WinSystemX11GL.h" ++#include "X11/keysymdef.h" ++#include "X11/XF86keysym.h" ++#include "utils/log.h" ++#include "utils/CharsetConverter.h" ++#include "guilib/GUIWindowManager.h" ++#include "input/MouseStat.h" ++ ++#if defined(HAS_XRANDR) ++#include ++#endif ++ ++#ifdef HAS_SDL_JOYSTICK ++#include "input/SDLJoystick.h" ++#endif ++ ++CWinEventsX11* CWinEventsX11::WinEvents = 0; ++ ++static uint32_t SymMappingsX11[][2] = ++{ ++ {XK_BackSpace, XBMCK_BACKSPACE} ++, {XK_Tab, XBMCK_TAB} ++, {XK_Clear, XBMCK_CLEAR} ++, {XK_Return, XBMCK_RETURN} ++, {XK_Pause, XBMCK_PAUSE} ++, {XK_Escape, XBMCK_ESCAPE} ++, {XK_Delete, XBMCK_DELETE} ++// multi-media keys ++, {XF86XK_Back, XBMCK_BROWSER_BACK} ++, {XF86XK_Forward, XBMCK_BROWSER_FORWARD} ++, {XF86XK_Refresh, XBMCK_BROWSER_REFRESH} ++, {XF86XK_Stop, XBMCK_BROWSER_STOP} ++, {XF86XK_Search, XBMCK_BROWSER_SEARCH} ++, {XF86XK_Favorites, XBMCK_BROWSER_FAVORITES} ++, {XF86XK_HomePage, XBMCK_BROWSER_HOME} ++, {XF86XK_AudioMute, XBMCK_VOLUME_MUTE} ++, {XF86XK_AudioLowerVolume, XBMCK_VOLUME_DOWN} ++, {XF86XK_AudioRaiseVolume, XBMCK_VOLUME_UP} ++, {XF86XK_AudioNext, XBMCK_MEDIA_NEXT_TRACK} ++, {XF86XK_AudioPrev, XBMCK_MEDIA_PREV_TRACK} ++, {XF86XK_AudioStop, XBMCK_MEDIA_STOP} ++, {XF86XK_AudioPause, XBMCK_MEDIA_PLAY_PAUSE} ++, {XF86XK_Mail, XBMCK_LAUNCH_MAIL} ++, {XF86XK_Select, XBMCK_LAUNCH_MEDIA_SELECT} ++, {XF86XK_Launch0, XBMCK_LAUNCH_APP1} ++, {XF86XK_Launch1, XBMCK_LAUNCH_APP2} ++, {XF86XK_WWW, XBMCK_LAUNCH_FILE_BROWSER} ++, {XF86XK_AudioMedia, XBMCK_LAUNCH_MEDIA_CENTER } ++ // Numeric keypad ++, {XK_KP_0, XBMCK_KP0} ++, {XK_KP_1, XBMCK_KP1} ++, {XK_KP_2, XBMCK_KP2} ++, {XK_KP_3, XBMCK_KP3} ++, {XK_KP_4, XBMCK_KP4} ++, {XK_KP_5, XBMCK_KP5} ++, {XK_KP_6, XBMCK_KP6} ++, {XK_KP_7, XBMCK_KP7} ++, {XK_KP_8, XBMCK_KP8} ++, {XK_KP_9, XBMCK_KP9} ++, {XK_KP_Separator, XBMCK_KP_PERIOD} ++, {XK_KP_Divide, XBMCK_KP_DIVIDE} ++, {XK_KP_Multiply, XBMCK_KP_MULTIPLY} ++, {XK_KP_Subtract, XBMCK_KP_MINUS} ++, {XK_KP_Add, XBMCK_KP_PLUS} ++, {XK_KP_Enter, XBMCK_KP_ENTER} ++, {XK_KP_Equal, XBMCK_KP_EQUALS} ++ // Arrows + Home/End pad ++, {XK_Up, XBMCK_UP} ++, {XK_Down, XBMCK_DOWN} ++, {XK_Right, XBMCK_RIGHT} ++, {XK_Left, XBMCK_LEFT} ++, {XK_Insert, XBMCK_INSERT} ++, {XK_Home, XBMCK_HOME} ++, {XK_End, XBMCK_END} ++, {XK_Page_Up, XBMCK_PAGEUP} ++, {XK_Page_Down, XBMCK_PAGEDOWN} ++ // Function keys ++, {XK_F1, XBMCK_F1} ++, {XK_F2, XBMCK_F2} ++, {XK_F3, XBMCK_F3} ++, {XK_F4, XBMCK_F4} ++, {XK_F5, XBMCK_F5} ++, {XK_F6, XBMCK_F6} ++, {XK_F7, XBMCK_F7} ++, {XK_F8, XBMCK_F8} ++, {XK_F9, XBMCK_F9} ++, {XK_F10, XBMCK_F10} ++, {XK_F11, XBMCK_F11} ++, {XK_F12, XBMCK_F12} ++, {XK_F13, XBMCK_F13} ++, {XK_F14, XBMCK_F14} ++, {XK_F15, XBMCK_F15} ++ // Key state modifier keys ++, {XK_Num_Lock, XBMCK_NUMLOCK} ++, {XK_Caps_Lock, XBMCK_CAPSLOCK} ++, {XK_Scroll_Lock, XBMCK_SCROLLOCK} ++, {XK_Shift_R, XBMCK_RSHIFT} ++, {XK_Shift_L, XBMCK_LSHIFT} ++, {XK_Control_R, XBMCK_RCTRL} ++, {XK_Control_L, XBMCK_LCTRL} ++, {XK_Alt_R, XBMCK_RALT} ++, {XK_Alt_L, XBMCK_LALT} ++, {XK_Meta_R, XBMCK_RMETA} ++, {XK_Meta_L, XBMCK_LMETA} ++, {XK_Super_L, XBMCK_LSUPER} ++, {XK_Super_R, XBMCK_RSUPER} ++, {XK_Mode_switch, XBMCK_MODE} ++, {XK_Multi_key, XBMCK_COMPOSE} ++ // Miscellaneous function keys ++, {XK_Help, XBMCK_HELP} ++, {XK_Print, XBMCK_PRINT} ++//, {0, XBMCK_SYSREQ} ++, {XK_Break, XBMCK_BREAK} ++, {XK_Menu, XBMCK_MENU} ++, {XF86XK_PowerOff, XBMCK_POWER} ++, {XF86XK_Sleep, XBMCK_SLEEP} ++, {XK_EcuSign, XBMCK_EURO} ++, {XK_Undo, XBMCK_UNDO} ++ /* Media keys */ ++, {XF86XK_Eject, XBMCK_EJECT} ++, {XF86XK_Stop, XBMCK_STOP} ++, {XF86XK_AudioRecord, XBMCK_RECORD} ++, {XF86XK_AudioRewind, XBMCK_REWIND} ++, {XF86XK_Phone, XBMCK_PHONE} ++, {XF86XK_AudioPlay, XBMCK_PLAY} ++, {XF86XK_AudioRandomPlay, XBMCK_SHUFFLE} ++, {XF86XK_AudioForward, XBMCK_FASTFORWARD} ++}; ++ ++ ++CWinEventsX11::CWinEventsX11() ++{ ++ m_display = 0; ++ m_window = 0; ++ m_keybuf = 0; ++ m_keybuf_len = 0; ++} ++ ++CWinEventsX11::~CWinEventsX11() ++{ ++ if (m_keybuf); ++ { ++ free(m_keybuf); ++ m_keybuf = 0; ++ } ++ ++ if (m_xic) ++ { ++ XUnsetICFocus(m_xic); ++ XDestroyIC(m_xic); ++ m_xic = 0; ++ } ++ ++ if (m_xim) ++ { ++ XCloseIM(m_xim); ++ m_xim = 0; ++ } ++ ++ m_symLookupTable.clear(); ++} ++ ++bool CWinEventsX11::Init(Display *dpy, Window win) ++{ ++ if (WinEvents) ++ return true; ++ ++ WinEvents = new CWinEventsX11(); ++ WinEvents->m_display = dpy; ++ WinEvents->m_window = win; ++ WinEvents->m_keybuf_len = 32*sizeof(char); ++ WinEvents->m_keybuf = (char*)malloc(WinEvents->m_keybuf_len); ++ WinEvents->m_keymodState = 0; ++ WinEvents->m_wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); ++ WinEvents->m_structureChanged = false; ++ WinEvents->m_xrrEventPending = false; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); ++ ++ // open input method ++ char *old_locale = NULL, *old_modifiers = NULL; ++ char res_name[8]; ++ const char *p; ++ size_t n; ++ ++ // set resource name to xbmc, not used ++ strcpy(res_name, "xbmc"); ++ ++ // save current locale, this should be "C" ++ p = setlocale(LC_ALL, NULL); ++ if (p) ++ { ++ old_locale = (char*)malloc(strlen(p) +1); ++ strcpy(old_locale, p); ++ } ++ p = XSetLocaleModifiers(NULL); ++ if (p) ++ { ++ old_modifiers = (char*)malloc(strlen(p) +1); ++ strcpy(old_modifiers, p); ++ } ++ ++ // set users preferences and open input method ++ p = setlocale(LC_ALL, ""); ++ XSetLocaleModifiers(""); ++ WinEvents->m_xim = XOpenIM(WinEvents->m_display, NULL, res_name, res_name); ++ ++ // restore old locale ++ if (old_locale) ++ { ++ setlocale(LC_ALL, old_locale); ++ free(old_locale); ++ } ++ if (old_modifiers) ++ { ++ XSetLocaleModifiers(old_modifiers); ++ free(old_modifiers); ++ } ++ ++ WinEvents->m_xic = NULL; ++ if (WinEvents->m_xim) ++ { ++ WinEvents->m_xic = XCreateIC(WinEvents->m_xim, ++ XNClientWindow, WinEvents->m_window, ++ XNFocusWindow, WinEvents->m_window, ++ XNInputStyle, XIMPreeditNothing | XIMStatusNothing, ++ XNResourceName, res_name, ++ XNResourceClass, res_name, ++ NULL); ++ } ++ ++ if (!WinEvents->m_xic) ++ CLog::Log(LOGWARNING,"CWinEventsX11::Init - no input method found"); ++ ++ // build Keysym lookup table ++ for (unsigned int i = 0; i < sizeof(SymMappingsX11)/(2*sizeof(uint32_t)); ++i) ++ { ++ WinEvents->m_symLookupTable[SymMappingsX11[i][0]] = SymMappingsX11[i][1]; ++ } ++ ++ // register for xrandr events ++#if defined(HAS_XRANDR) ++ int iReturn; ++ XRRQueryExtension(WinEvents->m_display, &WinEvents->m_RREventBase, &iReturn); ++ XRRSelectInput(WinEvents->m_display, WinEvents->m_window, RRScreenChangeNotifyMask); ++#endif ++ ++ return true; ++} ++ ++void CWinEventsX11::Quit() ++{ ++ if (!WinEvents) ++ return; ++ ++ delete WinEvents; ++ WinEvents = 0; ++} ++ ++bool CWinEventsX11::HasStructureChanged() ++{ ++ if (!WinEvents) ++ return false; ++ ++ bool ret = WinEvents->m_structureChanged; ++ WinEvents->m_structureChanged = false; ++ return ret; ++} ++ ++void CWinEventsX11::SetXRRFailSafeTimer(int millis) ++{ ++ if (!WinEvents) ++ return; ++ ++ WinEvents->m_xrrFailSafeTimer.Set(millis); ++ WinEvents->m_xrrEventPending = true; ++} ++ ++bool CWinEventsX11::MessagePump() ++{ ++ if (!WinEvents) ++ return false; ++ ++ bool ret = false; ++ XEvent xevent; ++ unsigned long serial = 0; ++ ++ while (WinEvents && XPending(WinEvents->m_display)) ++ { ++ memset(&xevent, 0, sizeof (XEvent)); ++ XNextEvent(WinEvents->m_display, &xevent); ++ ++ // ignore events generated by auto-repeat ++ if (xevent.type == KeyRelease && XPending(WinEvents->m_display)) ++ { ++ XEvent peekevent; ++ XPeekEvent(WinEvents->m_display, &peekevent); ++ if ((peekevent.type == KeyPress) && ++ (peekevent.xkey.keycode == xevent.xkey.keycode) && ++ ((peekevent.xkey.time - xevent.xkey.time) < 2)) ++ { ++ XNextEvent(WinEvents->m_display, &peekevent); ++ continue; ++ } ++ } ++ ++ if (XFilterEvent(&xevent, None)) ++ continue; ++ ++ switch (xevent.type) ++ { ++ case MapNotify: ++ { ++ g_application.m_AppActive = true; ++ break; ++ } ++ ++ case UnmapNotify: ++ { ++ g_application.m_AppActive = false; ++ break; ++ } ++ ++ case FocusIn: ++ { ++ if (WinEvents->m_xic) ++ XSetICFocus(WinEvents->m_xic); ++ g_application.m_AppFocused = true; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); ++ WinEvents->m_keymodState = 0; ++ if (serial == xevent.xfocus.serial) ++ break; ++ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); ++ break; ++ } ++ ++ case FocusOut: ++ { ++ if (WinEvents->m_xic) ++ XUnsetICFocus(WinEvents->m_xic); ++ g_application.m_AppFocused = false; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(XBMC_Event)); ++ g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused); ++ serial = xevent.xfocus.serial; ++ break; ++ } ++ ++ case Expose: ++ { ++ g_windowManager.MarkDirty(); ++ break; ++ } ++ ++ case ConfigureNotify: ++ { ++ if (xevent.xconfigure.window != WinEvents->m_window) ++ break; ++ ++ WinEvents->m_structureChanged = true; ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_VIDEORESIZE; ++ newEvent.resize.w = xevent.xconfigure.width; ++ newEvent.resize.h = xevent.xconfigure.height; ++ ret |= g_application.OnEvent(newEvent); ++ g_windowManager.MarkDirty(); ++ break; ++ } ++ ++ case ClientMessage: ++ { ++ if (xevent.xclient.data.l[0] == WinEvents->m_wmDeleteMessage) ++ if (!g_application.m_bStop) CApplicationMessenger::Get().Quit(); ++ break; ++ } ++ ++ case KeyPress: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_KEYDOWN; ++ KeySym xkeysym; ++ ++ // fallback if we have no IM ++ if (!WinEvents->m_xic) ++ { ++ static XComposeStatus state; ++ char keybuf[32]; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ if (XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state)) ++ { ++ newEvent.key.keysym.unicode = keybuf[0]; ++ } ++ ret |= ProcessKey(newEvent, 500); ++ break; ++ } ++ ++ Status status; ++ int len; ++ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, ++ WinEvents->m_keybuf, WinEvents->m_keybuf_len, ++ &xkeysym, &status); ++ if (status == XBufferOverflow) ++ { ++ WinEvents->m_keybuf_len = len; ++ WinEvents->m_keybuf = (char*)realloc(WinEvents->m_keybuf, WinEvents->m_keybuf_len); ++ len = Xutf8LookupString(WinEvents->m_xic, &xevent.xkey, ++ WinEvents->m_keybuf, WinEvents->m_keybuf_len, ++ &xkeysym, &status); ++ } ++ switch (status) ++ { ++ case XLookupNone: ++ break; ++ case XLookupChars: ++ case XLookupBoth: ++ { ++ CStdString data(WinEvents->m_keybuf, len); ++ CStdStringW keys; ++ g_charsetConverter.utf8ToW(data, keys, false); ++ ++ if (keys.length() == 0) ++ { ++ break; ++ } ++ ++ for (unsigned int i = 0; i < keys.length() - 1; i++) ++ { ++ newEvent.key.keysym.sym = XBMCK_UNKNOWN; ++ newEvent.key.keysym.unicode = keys[i]; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 500); ++ } ++ if (keys.length() > 0) ++ { ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.keysym.unicode = keys[keys.length() - 1]; ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ++ ret |= ProcessKey(newEvent, 500); ++ } ++ break; ++ } ++ ++ case XLookupKeySym: ++ { ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 500); ++ break; ++ } ++ ++ }// switch status ++ break; ++ } //KeyPress ++ ++ case KeyRelease: ++ { ++ XBMC_Event newEvent; ++ KeySym xkeysym; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_KEYUP; ++ xkeysym = XLookupKeysym(&xevent.xkey, 0); ++ newEvent.key.keysym.scancode = xevent.xkey.keycode; ++ newEvent.key.keysym.sym = LookupXbmcKeySym(xkeysym); ++ newEvent.key.state = xevent.xkey.state; ++ newEvent.key.type = xevent.xkey.type; ++ ret |= ProcessKey(newEvent, 0); ++ break; ++ } ++ ++ case EnterNotify: ++ { ++ g_Windowing.NotifyMouseCoverage(true); ++ break; ++ } ++ ++ // lose mouse coverage ++ case LeaveNotify: ++ { ++ g_Windowing.NotifyMouseCoverage(false); ++ g_Mouse.SetActive(false); ++ break; ++ } ++ ++ case MotionNotify: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEMOTION; ++ newEvent.motion.xrel = (int16_t)xevent.xmotion.x_root; ++ newEvent.motion.yrel = (int16_t)xevent.xmotion.y_root; ++ newEvent.motion.x = (int16_t)xevent.xmotion.x; ++ newEvent.motion.y = (int16_t)xevent.xmotion.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ case ButtonPress: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEBUTTONDOWN; ++ newEvent.button.button = (unsigned char)xevent.xbutton.button; ++ newEvent.button.state = XBMC_PRESSED; ++ newEvent.button.x = (int16_t)xevent.xbutton.x; ++ newEvent.button.y = (int16_t)xevent.xbutton.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ case ButtonRelease: ++ { ++ XBMC_Event newEvent; ++ memset(&newEvent, 0, sizeof(newEvent)); ++ newEvent.type = XBMC_MOUSEBUTTONUP; ++ newEvent.button.button = (unsigned char)xevent.xbutton.button; ++ newEvent.button.state = XBMC_RELEASED; ++ newEvent.button.x = (int16_t)xevent.xbutton.x; ++ newEvent.button.y = (int16_t)xevent.xbutton.y; ++ ret |= g_application.OnEvent(newEvent); ++ break; ++ } ++ ++ default: ++ { ++ break; ++ } ++ }// switch event.type ++ ++#if defined(HAS_XRANDR) ++ if (WinEvents && (xevent.type == WinEvents->m_RREventBase + RRScreenChangeNotify)) ++ { ++ XRRUpdateConfiguration(&xevent); ++ if (xevent.xgeneric.serial != serial) ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ serial = xevent.xgeneric.serial; ++ } ++#endif ++ ++ }// while ++ ++ ret |= ProcessKeyRepeat(); ++ ++#if defined(HAS_XRANDR) ++ if (WinEvents && WinEvents->m_xrrEventPending && WinEvents->m_xrrFailSafeTimer.IsTimePast()) ++ { ++ CLog::Log(LOGERROR,"CWinEventsX11::MessagePump - missed XRR Events"); ++ g_Windowing.NotifyXRREvent(); ++ WinEvents->m_xrrEventPending = false; ++ } ++#endif ++ ++#ifdef HAS_SDL_JOYSTICK ++ SDL_Event event; ++ while (SDL_PollEvent(&event)) ++ { ++ switch(event.type) ++ { ++ case SDL_JOYBUTTONUP: ++ case SDL_JOYBUTTONDOWN: ++ case SDL_JOYAXISMOTION: ++ case SDL_JOYBALLMOTION: ++ case SDL_JOYHATMOTION: ++ g_Joystick.Update(event); ++ ret = true; ++ break; ++ ++ default: ++ break; ++ } ++ memset(&event, 0, sizeof(SDL_Event)); ++ } ++#endif ++ ++ return ret; ++} ++ ++bool CWinEventsX11::ProcessKey(XBMC_Event &event, int repeatDelay) ++{ ++ if (event.type == XBMC_KEYDOWN) ++ { ++ // check key modifiers ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_LSHIFT: ++ WinEvents->m_keymodState |= XBMCKMOD_LSHIFT; ++ break; ++ case XBMCK_RSHIFT: ++ WinEvents->m_keymodState |= XBMCKMOD_RSHIFT; ++ break; ++ case XBMCK_LCTRL: ++ WinEvents->m_keymodState |= XBMCKMOD_LCTRL; ++ break; ++ case XBMCK_RCTRL: ++ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LALT: ++ WinEvents->m_keymodState |= XBMCKMOD_LALT; ++ break; ++ case XBMCK_RALT: ++ WinEvents->m_keymodState |= XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LMETA: ++ WinEvents->m_keymodState |= XBMCKMOD_LMETA; ++ break; ++ case XBMCK_RMETA: ++ WinEvents->m_keymodState |= XBMCKMOD_RMETA; ++ break; ++ case XBMCK_MODE: ++ WinEvents->m_keymodState |= XBMCKMOD_MODE; ++ break; ++ default: ++ break; ++ } ++ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; ++ memcpy(&(WinEvents->m_lastKey), &event, sizeof(event)); ++ WinEvents->m_repeatKeyTimeout.Set(repeatDelay); ++ ++ bool ret = ProcessShortcuts(event); ++ if (ret) ++ return ret; ++ } ++ else if (event.type == XBMC_KEYUP) ++ { ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_LSHIFT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LSHIFT; ++ break; ++ case XBMCK_RSHIFT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RSHIFT; ++ break; ++ case XBMCK_LCTRL: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LCTRL; ++ break; ++ case XBMCK_RCTRL: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LALT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LALT; ++ break; ++ case XBMCK_RALT: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RCTRL; ++ break; ++ case XBMCK_LMETA: ++ WinEvents->m_keymodState &= ~XBMCKMOD_LMETA; ++ break; ++ case XBMCK_RMETA: ++ WinEvents->m_keymodState &= ~XBMCKMOD_RMETA; ++ break; ++ case XBMCK_MODE: ++ WinEvents->m_keymodState &= ~XBMCKMOD_MODE; ++ break; ++ default: ++ break; ++ } ++ event.key.keysym.mod = (XBMCMod)WinEvents->m_keymodState; ++ memset(&(WinEvents->m_lastKey), 0, sizeof(event)); ++ } ++ ++ return g_application.OnEvent(event); ++} ++ ++bool CWinEventsX11::ProcessShortcuts(XBMC_Event& event) ++{ ++ if (event.key.keysym.mod & XBMCKMOD_ALT) ++ { ++ switch(event.key.keysym.sym) ++ { ++ case XBMCK_TAB: // ALT+TAB to minimize/hide ++ g_application.Minimize(); ++ return true; ++ ++ default: ++ return false; ++ } ++ } ++ return false; ++} ++ ++bool CWinEventsX11::ProcessKeyRepeat() ++{ ++ if (WinEvents && (WinEvents->m_lastKey.type == XBMC_KEYDOWN)) ++ { ++ if (WinEvents->m_repeatKeyTimeout.IsTimePast()) ++ { ++ return ProcessKey(WinEvents->m_lastKey, 10); ++ } ++ } ++ return false; ++} ++ ++XBMCKey CWinEventsX11::LookupXbmcKeySym(KeySym keysym) ++{ ++ // try direct mapping first ++ std::map::iterator it; ++ it = WinEvents->m_symLookupTable.find(keysym); ++ if (it != WinEvents->m_symLookupTable.end()) ++ { ++ return (XBMCKey)(it->second); ++ } ++ ++ // try ascii mappings ++ if (keysym>>8 == 0x00) ++ return (XBMCKey)(keysym & 0xFF); ++ ++ return (XBMCKey)keysym; ++} ++#endif +diff -Naur xbmc-12.0.4/xbmc/windowing/WinEventsX11.h xbmc-12.0.4.patch/xbmc/windowing/WinEventsX11.h +--- xbmc-12.0.4/xbmc/windowing/WinEventsX11.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/WinEventsX11.h 2013-03-10 13:00:12.316988213 +0100 +@@ -0,0 +1,61 @@ ++/* ++* Copyright (C) 2005-2012 Team XBMC ++* http://www.xbmc.org ++* ++* This Program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation; either version 2, or (at your option) ++* any later version. ++* ++* This Program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++* GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License ++* along with XBMC; see the file COPYING. If not, write to ++* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++* http://www.gnu.org/copyleft/gpl.html ++* ++*/ ++#pragma once ++ ++#include "WinEvents.h" ++#include ++#include "threads/SystemClock.h" ++#include ++ ++class CWinEventsX11 : public CWinEventsBase ++{ ++public: ++ CWinEventsX11(); ++ virtual ~CWinEventsX11(); ++ static bool Init(Display *dpy, Window win); ++ static void Quit(); ++ static bool HasStructureChanged(); ++ static void PendingResize(int width, int height); ++ static void SetXRRFailSafeTimer(int millis); ++ static bool MessagePump(); ++ ++protected: ++ static XBMCKey LookupXbmcKeySym(KeySym keysym); ++ static bool ProcessKey(XBMC_Event &event, int repeatDelay); ++ static bool ProcessKeyRepeat(); ++ static bool ProcessShortcuts(XBMC_Event& event); ++ static CWinEventsX11 *WinEvents; ++ Display *m_display; ++ Window m_window; ++ Atom m_wmDeleteMessage; ++ char *m_keybuf; ++ size_t m_keybuf_len; ++ XIM m_xim; ++ XIC m_xic; ++ XBMC_Event m_lastKey; ++ XbmcThreads::EndTime m_repeatKeyTimeout; ++ std::map m_symLookupTable; ++ int m_keymodState; ++ bool m_structureChanged; ++ int m_RREventBase; ++ XbmcThreads::EndTime m_xrrFailSafeTimer; ++ bool m_xrrEventPending; ++}; +diff -Naur xbmc-12.0.4/xbmc/windowing/WinSystem.h xbmc-12.0.4.patch/xbmc/windowing/WinSystem.h +--- xbmc-12.0.4/xbmc/windowing/WinSystem.h 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/WinSystem.h 2013-03-10 13:00:12.315988220 +0100 +@@ -100,6 +100,7 @@ + std::vector ScreenResolutions(int screen); + std::vector RefreshRates(int screen, int width, int height, uint32_t dwFlags); + REFRESHRATE DefaultRefreshRate(int screen, std::vector rates); ++ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo) { return true; }; + + protected: + void UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen, int width, int height, float refreshRate, uint32_t dwFlags = 0); +diff -Naur xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11.cpp xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11.cpp +--- xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11.cpp 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11.cpp 2013-03-10 13:00:12.331988105 +0100 +@@ -22,7 +22,6 @@ + + #ifdef HAS_GLX + +-#include + #include "WinSystemX11.h" + #include "settings/Settings.h" + #include "guilib/Texture.h" +@@ -31,27 +30,33 @@ + #include "XRandR.h" + #include + #include "threads/SingleLock.h" +-#include + #include "cores/VideoRenderers/RenderManager.h" + #include "utils/TimeUtils.h" ++#include "settings/GUISettings.h" ++#include "windowing/WindowingFactory.h" ++#include + + #if defined(HAS_XRANDR) + #include + #endif + ++#include "../WinEvents.h" ++#include "input/MouseStat.h" ++ + using namespace std; + + CWinSystemX11::CWinSystemX11() : CWinSystemBase() + { + m_eWindowSystem = WINDOW_SYSTEM_X11; + m_glContext = NULL; +- m_SDLSurface = NULL; + m_dpy = NULL; + m_glWindow = 0; +- m_wmWindow = 0; + m_bWasFullScreenBeforeMinimize = false; + m_minimized = false; ++ m_bIgnoreNextFocusMessage = false; + m_dpyLostTime = 0; ++ m_invisibleCursor = 0; ++ m_bIsInternalXrr = false; + + XSetErrorHandler(XErrorHandler); + } +@@ -64,19 +69,8 @@ + { + if ((m_dpy = XOpenDisplay(NULL))) + { +- +- SDL_EnableUNICODE(1); +- // set repeat to 10ms to ensure repeat time < frame time +- // so that hold times can be reliably detected +- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10); +- +- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); +- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +- +- return CWinSystemBase::InitWindowSystem(); ++ bool ret = CWinSystemBase::InitWindowSystem(); ++ return ret; + } + else + CLog::Log(LOGERROR, "GLX Error: No Display found"); +@@ -87,9 +81,18 @@ + bool CWinSystemX11::DestroyWindowSystem() + { + #if defined(HAS_XRANDR) +- //restore videomode on exit ++ //restore desktop resolution on exit + if (m_bFullScreen) +- g_xrandr.RestoreState(); ++ { ++ XOutput out; ++ XMode mode; ++ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; ++ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; ++ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; ++ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; ++ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ g_xrandr.SetMode(out, mode); ++ } + #endif + + if (m_dpy) +@@ -104,6 +107,9 @@ + + //we don't call XCloseDisplay() here, since ati keeps a pointer to our m_dpy + //so instead we just let m_dpy die on exit ++ // i have seen core dumps on ATI if the display is not closed here ++ // crashes when shutting down via cec ++// XCloseDisplay(m_dpy); + } + + // m_SDLSurface is free()'d by SDL_Quit(). +@@ -113,45 +119,43 @@ + + bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) + { +- RESOLUTION_INFO& desktop = g_settings.m_ResInfo[RES_DESKTOP]; +- +- if (fullScreen && +- (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || +- res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) +- { +- //on the first call to SDL_SetVideoMode, SDL stores the current displaymode +- //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode +- //before the first call to SDL_SetVideoMode, SDL changes the displaymode back +- //to the wrong mode on exit +- +- CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); +- if (!SetFullScreen(true, desktop, false)) +- return false; +- } +- + if(!SetFullScreen(fullScreen, res, false)) + return false; + +- CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon.png"); +- +- if (iconTexture) +- SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); +- SDL_WM_SetCaption("XBMC Media Center", NULL); +- delete iconTexture; +- +- // register XRandR Events +-#if defined(HAS_XRANDR) +- int iReturn; +- XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn); +- XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask); +-#endif +- + m_bWindowCreated = true; + return true; + } + + bool CWinSystemX11::DestroyWindow() + { ++ if (!m_glWindow) ++ return true; ++ ++ if (m_glContext) ++ { ++ glFinish(); ++ glXMakeCurrent(m_dpy, None, NULL); ++ } ++ ++ if (m_invisibleCursor) ++ { ++ XUndefineCursor(m_dpy, m_glWindow); ++ XFreeCursor(m_dpy, m_invisibleCursor); ++ m_invisibleCursor = 0; ++ } ++ ++ CWinEvents::Quit(); ++ ++ XUnmapWindow(m_dpy, m_glWindow); ++ XSync(m_dpy,TRUE); ++ XUngrabKeyboard(m_dpy, CurrentTime); ++ XUngrabPointer(m_dpy, CurrentTime); ++ XDestroyWindow(m_dpy, m_glWindow); ++ m_glWindow = 0; ++ ++ if (m_icon) ++ XFreePixmap(m_dpy, m_icon); ++ + return true; + } + +@@ -161,107 +165,138 @@ + && m_nHeight == newHeight) + return true; + +- m_nWidth = newWidth; +- m_nHeight = newHeight; +- +- int options = SDL_OPENGL; +- if (m_bFullScreen) +- options |= SDL_FULLSCREEN; +- else +- options |= SDL_RESIZABLE; +- +- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) ++ if (!SetWindow(newWidth, newHeight, false, g_guiSettings.GetString("videoscreen.monitor"))) + { +- RefreshGlxContext(); +- return true; ++ return false; + } + ++ m_nWidth = newWidth; ++ m_nHeight = newHeight; ++ m_bFullScreen = false; ++ m_currentOutput = g_guiSettings.GetString("videoscreen.monitor"); ++ + return false; + } + + bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) + { +- m_nWidth = res.iWidth; +- m_nHeight = res.iHeight; +- m_bFullScreen = fullScreen; + + #if defined(HAS_XRANDR) + XOutput out; + XMode mode; +- out.name = res.strOutput; +- mode.w = res.iWidth; +- mode.h = res.iHeight; +- mode.hz = res.fRefreshRate; +- mode.id = res.strId; +- +- if(m_bFullScreen) ++ ++ if (fullScreen) + { +- OnLostDevice(); +- g_xrandr.SetMode(out, mode); ++ out.name = res.strOutput; ++ mode.w = res.iWidth; ++ mode.h = res.iHeight; ++ mode.hz = res.fRefreshRate; ++ mode.id = res.strId; + } + else +- g_xrandr.RestoreState(); +-#endif +- +- int options = SDL_OPENGL; +- if (m_bFullScreen) +- options |= SDL_FULLSCREEN; +- else +- options |= SDL_RESIZABLE; +- +- if ((m_SDLSurface = SDL_SetVideoMode(m_nWidth, m_nHeight, 0, options))) + { +- if ((m_SDLSurface->flags & SDL_OPENGL) != SDL_OPENGL) +- CLog::Log(LOGERROR, "CWinSystemX11::SetFullScreen SDL_OPENGL not set, SDL_GetError:%s", SDL_GetError()); +- +- RefreshGlxContext(); ++ out.name = g_settings.m_ResInfo[RES_DESKTOP].strOutput; ++ mode.w = g_settings.m_ResInfo[RES_DESKTOP].iWidth; ++ mode.h = g_settings.m_ResInfo[RES_DESKTOP].iHeight; ++ mode.hz = g_settings.m_ResInfo[RES_DESKTOP].fRefreshRate; ++ mode.id = g_settings.m_ResInfo[RES_DESKTOP].strId; ++ } ++ ++ XMode currmode = g_xrandr.GetCurrentMode(out.name); ++ if (!currmode.name.empty()) ++ { + // flip h/w when rotated + if (m_bIsRotated) + { @@ -20788,16 +14607,7 @@ index b87e264..3cadd13 100644 + mode.h = w; + } -- // only call xrandr if mode changes -- if (currmode.w != mode.w || currmode.h != mode.h || -- currmode.hz != mode.hz || currmode.id != mode.id) -- { -- CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr"); -- OnLostDevice(); -- m_bIsInternalXrr = true; -- g_xrandr.SetMode(out, mode); -- if (m_glWindow) -- return true; +- return true; + // only call xrandr if mode changes + if (currmode.w != mode.w || currmode.h != mode.h || + currmode.hz != mode.hz || currmode.id != mode.id) @@ -20810,13 +14620,59 @@ index b87e264..3cadd13 100644 + return true; + } } - #endif ++#endif -@@ -268,9 +270,10 @@ void CWinSystemX11::UpdateResolutions() +- return false; ++ if (!SetWindow(res.iWidth, res.iHeight, fullScreen, g_guiSettings.GetString("videoscreen.monitor"))) ++ return false; ++ ++ m_nWidth = res.iWidth; ++ m_nHeight = res.iHeight; ++ m_bFullScreen = fullScreen; ++ m_currentOutput = g_guiSettings.GetString("videoscreen.monitor"); ++ ++ return true; + } + + void CWinSystemX11::UpdateResolutions() + { + CWinSystemBase::UpdateResolutions(); + +- + #if defined(HAS_XRANDR) +- if(g_xrandr.Query()) ++ CStdString currentMonitor; ++ int numScreens = XScreenCount(m_dpy); ++ g_xrandr.SetNumScreens(numScreens); ++ if(g_xrandr.Query(true)) + { +- XOutput out = g_xrandr.GetCurrentOutput(); +- XMode mode = g_xrandr.GetCurrentMode(out.name); +- UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, mode.w, mode.h, mode.hz); ++ currentMonitor = g_guiSettings.GetString("videoscreen.monitor"); ++ // check if the monitor is connected ++ XOutput *out = g_xrandr.GetOutput(currentMonitor); ++ if (!out) ++ { ++ // choose first output ++ currentMonitor = g_xrandr.GetModes()[0].name; ++ out = g_xrandr.GetOutput(currentMonitor); ++ g_guiSettings.SetString("videoscreen.monitor", currentMonitor); ++ } ++ XMode mode = g_xrandr.GetCurrentMode(currentMonitor); ++ m_bIsRotated = out->isRotated; ++ if (!m_bIsRotated) ++ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], out->screen, mode.w, mode.h, mode.hz); ++ else ++ UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], out->screen, mode.h, mode.w, mode.hz); + g_settings.m_ResInfo[RES_DESKTOP].strId = mode.id; +- g_settings.m_ResInfo[RES_DESKTOP].strOutput = out.name; ++ g_settings.m_ResInfo[RES_DESKTOP].strOutput = currentMonitor; + } else #endif { -- int x11screen = m_nScreen; +- int x11screen = DefaultScreen(m_dpy); - int w = DisplayWidth(m_dpy, x11screen); - int h = DisplayHeight(m_dpy, x11screen); + g_guiSettings.SetString("videoscreen.monitor", "Default"); @@ -20826,17 +14682,467 @@ index b87e264..3cadd13 100644 UpdateDesktopResolution(g_settings.m_ResInfo[RES_DESKTOP], 0, w, h, 0.0); } -@@ -819,11 +822,19 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - Colormap cmap; - XSetWindowAttributes swa; - XVisualInfo *vi; +- + #if defined(HAS_XRANDR) + ++ // erase previous stored modes ++ if (g_settings.m_ResInfo.size() > RES_CUSTOM) ++ { ++ std::vector::iterator firstCustom = g_settings.m_ResInfo.begin()+RES_CUSTOM; ++ g_settings.m_ResInfo.erase(firstCustom, g_settings.m_ResInfo.end()); ++ } ++ + CLog::Log(LOGINFO, "Available videomodes (xrandr):"); +- vector::iterator outiter; +- vector outs; +- outs = g_xrandr.GetModes(); +- CLog::Log(LOGINFO, "Number of connected outputs: %"PRIdS"", outs.size()); ++ ++ XOutput *out = g_xrandr.GetOutput(currentMonitor); + string modename = ""; + +- for (outiter = outs.begin() ; outiter != outs.end() ; outiter++) ++ if (out != NULL) + { +- XOutput out = *outiter; + vector::iterator modeiter; +- CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out.name.c_str(), out.modes.size()); ++ CLog::Log(LOGINFO, "Output '%s' has %"PRIdS" modes", out->name.c_str(), out->modes.size()); + +- for (modeiter = out.modes.begin() ; modeiter!=out.modes.end() ; modeiter++) ++ for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++) + { + XMode mode = *modeiter; + CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", +@@ -271,17 +306,27 @@ + res.iHeight = mode.h; + res.iScreenWidth = mode.w; + res.iScreenHeight = mode.h; +- if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) +- res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); ++ if (!m_bIsRotated) ++ { ++ res.iWidth = mode.w; ++ res.iHeight = mode.h; ++ } ++ else ++ { ++ res.iWidth = mode.h; ++ res.iHeight = mode.w; ++ } ++ if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0) ++ res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h)); + else + res.fPixelRatio = 1.0f; + + CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio); + +- res.strMode.Format("%s: %s @ %.2fHz", out.name.c_str(), mode.name.c_str(), mode.hz); +- res.strOutput = out.name; ++ res.strMode.Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); ++ res.strOutput = out->name; + res.strId = mode.id; +- res.iSubtitles = (int)(0.95*mode.h); ++ res.iSubtitles = (int)(0.965*mode.h); + res.fRefreshRate = mode.hz; + res.bFullScreen = true; + +@@ -294,8 +339,57 @@ + g_settings.m_ResInfo.push_back(res); + } + } ++ g_settings.ApplyCalibrations(); + #endif ++} ++ ++bool CWinSystemX11::HasCalibration(const RESOLUTION_INFO &resInfo) ++{ ++ XOutput *out = g_xrandr.GetOutput(m_currentOutput); ++ ++ // keep calibrations done on a not connected output ++ if (!out->name.Equals(resInfo.strOutput)) ++ return true; ++ ++ // keep calibrations not updated with resolution data ++ if (resInfo.iWidth == 0) ++ return true; + ++ float fPixRatio; ++ if (resInfo.iHeight>0 && resInfo.iWidth>0 && out->hmm>0 && out->wmm>0) ++ fPixRatio = ((float)out->wmm/(float)resInfo.iWidth) / (((float)out->hmm/(float)resInfo.iHeight)); ++ else ++ fPixRatio = 1.0f; ++ ++ if (resInfo.Overscan.left != 0) ++ return true; ++ if (resInfo.Overscan.top != 0) ++ return true; ++ if (resInfo.Overscan.right != resInfo.iWidth) ++ return true; ++ if (resInfo.Overscan.bottom != resInfo.iHeight) ++ return true; ++ if (resInfo.fPixelRatio != fPixRatio) ++ return true; ++ if (resInfo.iSubtitles != (int)(0.965*resInfo.iHeight)) ++ return true; ++ ++ return false; ++} ++ ++void CWinSystemX11::GetConnectedOutputs(std::vector *outputs) ++{ ++ vector outs; ++ outs = g_xrandr.GetModes(); ++ for(unsigned int i=0; ipush_back(outs[i].name); ++ } ++} ++ ++bool CWinSystemX11::IsCurrentOutput(CStdString output) ++{ ++ return m_currentOutput.Equals(output); + } + + bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) +@@ -318,20 +412,13 @@ + return true; + } + +-bool CWinSystemX11::RefreshGlxContext() ++bool CWinSystemX11::RefreshGlxContext(bool force) + { + bool retVal = false; +- SDL_SysWMinfo info; +- SDL_VERSION(&info.version); +- if (SDL_GetWMInfo(&info) <= 0) +- { +- CLog::Log(LOGERROR, "Failed to get window manager info from SDL"); +- return false; +- } + +- if(m_glWindow == info.info.x11.window && m_glContext) ++ if (m_glContext && !force) + { +- CLog::Log(LOGERROR, "GLX: Same window as before, refreshing context"); ++ CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshGlxContext: refreshing context"); + glXMakeCurrent(m_dpy, None, NULL); + glXMakeCurrent(m_dpy, m_glWindow, m_glContext); + return true; +@@ -341,10 +428,8 @@ + XVisualInfo *visuals; + XVisualInfo *vInfo = NULL; + int availableVisuals = 0; +- vMask.screen = DefaultScreen(m_dpy); ++ vMask.screen = m_nScreen; + XWindowAttributes winAttr; +- m_glWindow = info.info.x11.window; +- m_wmWindow = info.info.x11.wmwindow; + + /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() + or XGetVisualInfo() fail. That shouldn't happen unless something is +@@ -395,6 +480,8 @@ + { + glXMakeCurrent(m_dpy, None, NULL); + glXDestroyContext(m_dpy, m_glContext); ++ XSync(m_dpy, FALSE); ++ m_newGlContext = true; + } + + if ((m_glContext = glXCreateContext(m_dpy, vInfo, NULL, True))) +@@ -415,7 +502,10 @@ + + void CWinSystemX11::ShowOSMouse(bool show) + { +- SDL_ShowCursor(show ? 1 : 0); ++ if (show) ++ XUndefineCursor(m_dpy,m_glWindow); ++ else if (m_invisibleCursor) ++ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); + } + + void CWinSystemX11::ResetOSScreensaver() +@@ -429,8 +519,6 @@ + { + m_screensaverReset.StartZero(); + XResetScreenSaver(m_dpy); +- //need to flush the output buffer, since we don't check for events on m_dpy +- XFlush(m_dpy); + } + } + else +@@ -439,20 +527,90 @@ + } + } + ++void CWinSystemX11::EnableSystemScreenSaver(bool bEnable) ++{ ++ if (!m_dpy) ++ return; ++ ++ if (bEnable) ++ XForceScreenSaver(m_dpy, ScreenSaverActive); ++ else ++ { ++ Window root_return, child_return; ++ int root_x_return, root_y_return; ++ int win_x_return, win_y_return; ++ unsigned int mask_return; ++ bool isInWin = XQueryPointer(m_dpy, RootWindow(m_dpy, m_nScreen), &root_return, &child_return, ++ &root_x_return, &root_y_return, ++ &win_x_return, &win_y_return, ++ &mask_return); ++ ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return+300, root_y_return+300); ++ XSync(m_dpy, FALSE); ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, 0, 0); ++ XSync(m_dpy, FALSE); ++ XWarpPointer(m_dpy, None, RootWindow(m_dpy, m_nScreen), 0, 0, 0, 0, root_x_return, root_y_return); ++ XSync(m_dpy, FALSE); ++ } ++} ++ + void CWinSystemX11::NotifyAppActiveChange(bool bActivated) + { +- if (bActivated && m_bWasFullScreenBeforeMinimize && !g_graphicsContext.IsFullScreenRoot()) ++ if (bActivated && m_bWasFullScreenBeforeMinimize && !m_bFullScreen) ++ { + g_graphicsContext.ToggleFullScreenRoot(); + ++ m_bWasFullScreenBeforeMinimize = false; ++ } + m_minimized = !bActivated; + } ++ ++void CWinSystemX11::NotifyAppFocusChange(bool bGaining) ++{ ++ if (bGaining && m_bWasFullScreenBeforeMinimize && !m_bIgnoreNextFocusMessage && ++ !m_bFullScreen) ++ { ++ m_bWasFullScreenBeforeMinimize = false; ++ g_graphicsContext.ToggleFullScreenRoot(); ++ m_minimized = false; ++ } ++ if (!bGaining) ++ m_bIgnoreNextFocusMessage = false; ++} ++ ++void CWinSystemX11::NotifyMouseCoverage(bool covered) ++{ ++ if (!m_bFullScreen) ++ return; ++ ++ if (covered) ++ { ++ int result = -1; ++ while (result != GrabSuccess && result != AlreadyGrabbed) ++ { ++ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); ++ XbmcThreads::ThreadSleep(100); ++ } ++ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ } ++ else ++ { ++ XUngrabKeyboard(m_dpy, CurrentTime); ++ XUngrabPointer(m_dpy, CurrentTime); ++ } ++} ++ + bool CWinSystemX11::Minimize() + { +- m_bWasFullScreenBeforeMinimize = g_graphicsContext.IsFullScreenRoot(); ++ m_bWasFullScreenBeforeMinimize = m_bFullScreen; + if (m_bWasFullScreenBeforeMinimize) ++ { ++ m_bIgnoreNextFocusMessage = true; + g_graphicsContext.ToggleFullScreenRoot(); ++ } ++ ++ XIconifyWindow(m_dpy, m_glWindow, m_nScreen); + +- SDL_WM_IconifyWindow(); + m_minimized = true; + return true; + } +@@ -462,13 +620,13 @@ + } + bool CWinSystemX11::Hide() + { +- XUnmapWindow(m_dpy, m_wmWindow); ++ XUnmapWindow(m_dpy, m_glWindow); + XSync(m_dpy, False); + return true; + } + bool CWinSystemX11::Show(bool raise) + { +- XMapWindow(m_dpy, m_wmWindow); ++ XMapWindow(m_dpy, m_glWindow); + XSync(m_dpy, False); + m_minimized = false; + return true; +@@ -476,7 +634,7 @@ + + void CWinSystemX11::CheckDisplayEvents() + { +-#if defined(HAS_XRANDR) ++#if defined(HAS_XRANDR) && defined(HAS_SDL_VIDEO_X11) + bool bGotEvent(false); + bool bTimeout(false); + XEvent Event; +@@ -499,13 +657,7 @@ + + if (bGotEvent || bTimeout) + { +- CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); +- +- CSingleLock lock(m_resourceSection); +- +- // tell any shared resources +- for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) +- (*i)->OnResetDevice(); ++ NotifyXRREvent(); + + // reset fail safe timer + m_dpyLostTime = 0; +@@ -513,6 +665,61 @@ + #endif + } + ++void CWinSystemX11::NotifyXRREvent() ++{ ++ CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__); ++ m_windowDirty = true; ++ ++ CSingleLock lock(g_graphicsContext); ++ ++ if (!g_xrandr.Query(true)) ++ { ++ CLog::Log(LOGERROR, "WinSystemX11::RefreshWindow - failed to query xrandr"); ++ return; ++ } ++ ++ // if external event update resolutions ++ if (!m_bIsInternalXrr) ++ { ++ UpdateResolutions(); ++ } ++ m_bIsInternalXrr = false; ++ ++ CStdString currentOutput = g_guiSettings.GetString("videoscreen.monitor"); ++ XOutput *out = g_xrandr.GetOutput(currentOutput); ++ XMode mode = g_xrandr.GetCurrentMode(currentOutput); ++ ++ if (out) ++ CLog::Log(LOGDEBUG, "%s - current output: %s, mode: %s, refresh: %.3f", __FUNCTION__ ++ , out->name.c_str(), mode.id.c_str(), mode.hz); ++ else ++ CLog::Log(LOGWARNING, "%s - output name not set", __FUNCTION__); ++ ++ RESOLUTION_INFO res; ++ unsigned int i; ++ bool found(false); ++ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i) ++ { ++ if (g_settings.m_ResInfo[i].strId == mode.id) ++ { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution"); ++ i = RES_DESKTOP; ++ } ++ ++ if (g_graphicsContext.IsFullScreenRoot()) ++ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true); ++ else ++ g_graphicsContext.SetVideoResolution(RES_WINDOW, true); ++ ++} ++ + void CWinSystemX11::OnLostDevice() + { + CLog::Log(LOGDEBUG, "%s - notify display change event", __FUNCTION__); +@@ -525,8 +732,12 @@ + (*i)->OnLostDevice(); + } + ++#if defined(HAS_SDL_VIDEO_X11) + // fail safe timer + m_dpyLostTime = CurrentHostCounter(); ++#else ++ CWinEvents::SetXRRFailSafeTimer(3000); ++#endif + } + + void CWinSystemX11::Register(IDispResource *resource) +@@ -558,4 +769,386 @@ + return m_minimized; + } + ++bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStdString &output) ++{ ++ bool changeWindow = false; ++ bool changeSize = false; ++ bool mouseActive = false; ++ float mouseX, mouseY; ++ ++ if (m_glWindow && ((m_bFullScreen != fullscreen) || !m_currentOutput.Equals(output) || m_windowDirty)) ++ { ++ mouseActive = g_Mouse.IsActive(); ++ if (mouseActive) ++ { ++ Window root_return, child_return; ++ int root_x_return, root_y_return; ++ int win_x_return, win_y_return; ++ unsigned int mask_return; ++ bool isInWin = XQueryPointer(m_dpy, m_glWindow, &root_return, &child_return, ++ &root_x_return, &root_y_return, ++ &win_x_return, &win_y_return, ++ &mask_return); ++ if (isInWin) ++ { ++ mouseX = (float)win_x_return/m_nWidth; ++ mouseY = (float)win_y_return/m_nHeight; ++ g_Mouse.SetActive(false); ++ } ++ else ++ mouseActive = false; ++ } ++ OnLostDevice(); ++ DestroyWindow(); ++ m_windowDirty = true; ++ } ++ ++ // create main window ++ if (!m_glWindow) ++ { ++ EnableSystemScreenSaver(false); ++ ++ GLint att[] = ++ { ++ GLX_RGBA, ++ GLX_RED_SIZE, 8, ++ GLX_GREEN_SIZE, 8, ++ GLX_BLUE_SIZE, 8, ++ GLX_ALPHA_SIZE, 8, ++ GLX_DEPTH_SIZE, 24, ++ GLX_DOUBLEBUFFER, ++ None ++ }; ++ Colormap cmap; ++ XSetWindowAttributes swa; ++ XVisualInfo *vi; + int x0 = 0; + int y0 = 0; - - XOutput *out = g_xrandr.GetOutput(output); - if (!out) - out = g_xrandr.GetOutput(m_currentOutput); -- m_nScreen = out->screen; ++ ++ XOutput *out = g_xrandr.GetOutput(output); ++ if (!out) ++ out = g_xrandr.GetOutput(m_currentOutput); + if (out) + { + m_nScreen = out->screen; @@ -20844,274 +15150,655 @@ index b87e264..3cadd13 100644 + y0 = out->y; + } + - vi = glXChooseVisual(m_dpy, m_nScreen, att); - cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); - -@@ -842,7 +853,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const CStd - unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; - - m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), -- out->x, out->y, width, height, 0, vi->depth, ++ vi = glXChooseVisual(m_dpy, m_nScreen, att); ++ cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); ++ ++ bool hasWM = HasWindowManager(); ++ ++ int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); ++ swa.override_redirect = hasWM ? False : True; ++ swa.border_pixel = fullscreen ? 0 : 5; ++ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; ++ swa.colormap = cmap; ++ swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; ++ swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ++ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ++ PropertyChangeMask | StructureNotifyMask | KeymapStateMask | ++ EnterWindowMask | LeaveWindowMask | ExposureMask; ++ unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; ++ ++ m_glWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), + x0, y0, width, height, 0, vi->depth, - InputOutput, vi->visual, - mask, &swa); - --- -1.7.10 - - -From 11696cc729a3a94d8aa5434b1e7948ae5e7b249d Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 25 Feb 2013 08:47:10 +0100 -Subject: [PATCH 85/88] vdpau: release more resources on pre-cleanup - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 72 ++++++++++++++++++++++-- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 2 + - 2 files changed, 68 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 524efae..38ef375 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1142,6 +1142,11 @@ void CMixer::Dispose() - m_dataPort.Purge(); - } - -+bool CMixer::IsActive() -+{ -+ return IsRunning(); ++ InputOutput, vi->visual, ++ mask, &swa); ++ ++ if (fullscreen && hasWM) ++ { ++ Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); ++ XChangeProperty(m_dpy, m_glWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); ++ } ++ ++ // define invisible cursor ++ Pixmap bitmapNoData; ++ XColor black; ++ static char noData[] = { 0,0,0,0,0,0,0,0 }; ++ black.red = black.green = black.blue = 0; ++ ++ bitmapNoData = XCreateBitmapFromData(m_dpy, m_glWindow, noData, 8, 8); ++ m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, ++ &black, &black, 0, 0); ++ XFreePixmap(m_dpy, bitmapNoData); ++ XDefineCursor(m_dpy,m_glWindow, m_invisibleCursor); ++ ++ //init X11 events ++ CWinEvents::Init(m_dpy, m_glWindow); ++ ++ changeWindow = true; ++ changeSize = true; ++ } ++ ++ if (!CWinEvents::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) ++ { ++ changeSize = true; ++ } ++ ++ if (changeSize || changeWindow) ++ { ++ XResizeWindow(m_dpy, m_glWindow, width, height); ++ } ++ ++ if (changeWindow) ++ { ++ m_icon = None; ++ if (!fullscreen) ++ { ++ CreateIconPixmap(); ++ XWMHints *wm_hints; ++ XTextProperty windowName, iconName; ++ std::string titleString = "XBMC Media Center"; ++ char *title = (char*)titleString.c_str(); ++ ++ XStringListToTextProperty(&title, 1, &windowName); ++ XStringListToTextProperty(&title, 1, &iconName); ++ ++ wm_hints = XAllocWMHints(); ++ wm_hints->initial_state = NormalState; ++ wm_hints->icon_pixmap = m_icon; ++ wm_hints->flags = StateHint | IconPixmapHint; ++ ++ XSync(m_dpy,False); ++ XSetWMProperties(m_dpy, m_glWindow, &windowName, &iconName, ++ NULL, 0, NULL, wm_hints, ++ NULL); ++ XFree(wm_hints); ++ ++ // register interest in the delete window message ++ Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); ++ XSetWMProtocols(m_dpy, m_glWindow, &wmDeleteMessage, 1); ++ } ++ XMapRaised(m_dpy, m_glWindow); ++ XSync(m_dpy,TRUE); ++ ++ if (changeWindow && mouseActive) ++ { ++ XWarpPointer(m_dpy, None, m_glWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); ++ } ++ ++ if (fullscreen) ++ { ++ int result = -1; ++ while (result != GrabSuccess && result != AlreadyGrabbed) ++ { ++ result = XGrabPointer(m_dpy, m_glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); ++ XbmcThreads::ThreadSleep(100); ++ } ++ XGrabKeyboard(m_dpy, m_glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ } ++ ++ CDirtyRegionList dr; ++ RefreshGlxContext(!m_currentOutput.Equals(output)); ++ XSync(m_dpy, FALSE); ++ g_graphicsContext.Clear(0); ++ g_graphicsContext.Flip(dr); ++ g_Windowing.ResetVSync(); ++ m_windowDirty = false; ++ ++ CSingleLock lock(m_resourceSection); ++ // tell any shared resources ++ for (vector::iterator i = m_resources.begin(); i != m_resources.end(); i++) ++ (*i)->OnResetDevice(); ++ } ++ ++ return true; +} + - void CMixer::OnStartup() - { - CLog::Log(LOGNOTICE, "CMixer::OnStartup: Output Thread created"); -@@ -2455,6 +2460,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - return; - case COutputControlProtocol::PRECLEANUP: - Flush(); -+ PreCleanup(); - msg->Reply(COutputControlProtocol::ACC); - return; - default: -@@ -2661,15 +2667,18 @@ bool COutput::Uninit() - - void COutput::Flush() - { -- Message *reply; -- if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, -+ if (m_mixer.IsActive()) ++bool CWinSystemX11::CreateIconPixmap() ++{ ++ int depth; ++ XImage *img = NULL; ++ Visual *vis; ++ XWindowAttributes wndattribs; ++ XVisualInfo visInfo; ++ double rRatio; ++ double gRatio; ++ double bRatio; ++ int outIndex = 0; ++ int i,j; ++ int numBufBytes; ++ unsigned char *buf; ++ uint32_t *newBuf = 0; ++ size_t numNewBufBytes; ++ ++ // Get visual Info ++ XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs); ++ visInfo.visualid = wndattribs.visual->visualid; ++ int nvisuals = 0; ++ XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals); ++ if (nvisuals != 1) + { -+ Message *reply; -+ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, - &reply, - 2000)) -- { -- reply->Release(); ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual"); ++ return false; ++ } ++ visInfo = visuals[0]; ++ XFree(visuals); ++ ++ depth = visInfo.depth; ++ vis = visInfo.visual; ++ ++ if (depth < 15) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth"); ++ return false; ++ } ++ ++ rRatio = vis->red_mask / 255.0; ++ gRatio = vis->green_mask / 255.0; ++ bRatio = vis->blue_mask / 255.0; ++ ++ CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon.png"); ++ ++ if (!iconTexture) ++ return false; ++ ++ buf = iconTexture->GetPixels(); ++ ++ numBufBytes = iconTexture->GetWidth() * iconTexture->GetHeight() * 4; ++ int wid = iconTexture->GetWidth(); ++ int hi = iconTexture->GetHeight(); ++ ++ if (depth>=24) ++ numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight())); ++ else ++ numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight())); ++ ++ newBuf = (uint32_t*)malloc(numNewBufBytes); ++ if (!newBuf) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed"); ++ return false; ++ } ++ ++ for (i=0; iGetHeight();++i) ++ { ++ for (j=0; jGetWidth();++j) + { -+ reply->Release(); ++ unsigned int pos = i*iconTexture->GetPitch()+j*4; ++ unsigned int r, g, b; ++ r = (buf[pos+2] * rRatio); ++ g = (buf[pos+1] * gRatio); ++ b = (buf[pos+0] * bRatio); ++ r &= vis->red_mask; ++ g &= vis->green_mask; ++ b &= vis->blue_mask; ++ newBuf[outIndex] = r | g | b; ++ ++outIndex; ++ } ++ } ++ img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, ++ iconTexture->GetWidth(), iconTexture->GetHeight(), ++ (depth>=24)?32:16, 0); ++ if (!img) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image"); ++ free(newBuf); ++ return false; ++ } ++ if (!XInitImage(img)) ++ { ++ CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed"); ++ XDestroyImage(img); ++ return false; ++ } ++ ++ // set byte order ++ union ++ { ++ char c[sizeof(short)]; ++ short s; ++ } order; ++ order.s = 1; ++ if ((1 == order.c[0])) ++ { ++ img->byte_order = LSBFirst; ++ } ++ else ++ { ++ img->byte_order = MSBFirst; ++ } ++ ++ // create icon pixmap from image ++ m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth); ++ GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL); ++ XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height); ++ XFreeGC(m_dpy, gc); ++ XDestroyImage(img); // this also frees newBuf ++ ++ delete iconTexture; ++ ++ return true; ++} ++ ++bool CWinSystemX11::HasWindowManager() ++{ ++ Window wm_check; ++ unsigned char *data; ++ int status, real_format; ++ Atom real_type, prop; ++ unsigned long items_read, items_left, i; ++ char req = 0; ++ ++ prop = XInternAtom(m_dpy, "_NET_SUPPORTING_WM_CHECK", True); ++ if (prop == None) ++ return false; ++ status = XGetWindowProperty(m_dpy, DefaultRootWindow(m_dpy), prop, ++ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ if(status != Success || ! items_read) ++ { ++ if(status == Success) ++ XFree(data); ++ return false; ++ } ++ ++ wm_check = ((Window*)data)[0]; ++ XFree(data); ++ ++ status = XGetWindowProperty(m_dpy, wm_check, prop, ++ 0L, 1L, False, XA_WINDOW, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ ++ if(status != Success || !items_read) ++ { ++ if(status == Success) ++ XFree(data); ++ return false; ++ } ++ ++ if(wm_check != ((Window*)data)[0]) ++ { ++ XFree(data); ++ return false; ++ } ++ ++ XFree(data); ++ ++ prop = XInternAtom(m_dpy, "_NET_WM_NAME", True); ++ if (prop == None) ++ { ++ CLog::Log(LOGDEBUG,"Window Manager Name: "); ++ return true; ++ } ++ ++ status = XGetWindowProperty(m_dpy, wm_check, prop, ++ 0L, (~0L), False, AnyPropertyType, &real_type, &real_format, ++ &items_read, &items_left, &data); ++ ++ if(status == Success && items_read) ++ { ++ CLog::Log(LOGDEBUG,"Window Manager Name: %s", data); ++ } ++ else ++ CLog::Log(LOGDEBUG,"Window Manager Name: "); ++ ++ if(status == Success) ++ XFree(data); ++ ++ return true; ++} ++ + #endif +diff -Naur xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11GL.cpp xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11GL.cpp +--- xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11GL.cpp 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11GL.cpp 2013-03-10 13:00:12.314988227 +0100 +@@ -23,6 +23,7 @@ + + #include "WinSystemX11GL.h" + #include "utils/log.h" ++#include "Application.h" + + CWinSystemX11GL::CWinSystemX11GL() + { +@@ -203,7 +204,7 @@ + return false; + + m_glxext = " "; +- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy)); ++ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_nScreen); + m_glxext += " "; + + CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str()); +@@ -245,17 +246,25 @@ + + bool CWinSystemX11GL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) + { ++ m_newGlContext = false; + CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop); + CRenderSystemGL::ResetRenderSystem(newWidth, newHeight, false, 0); + ++ if (m_newGlContext) ++ g_application.ReloadSkin(); ++ + return true; + } + + bool CWinSystemX11GL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) + { ++ m_newGlContext = false; + CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays); + CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate); + ++ if (m_newGlContext) ++ g_application.ReloadSkin(); ++ + return true; + } + +diff -Naur xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11.h xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11.h +--- xbmc-12.0.4/xbmc/windowing/X11/WinSystemX11.h 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/X11/WinSystemX11.h 2013-03-10 13:00:12.330988113 +0100 +@@ -47,11 +47,14 @@ + virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays); + virtual void UpdateResolutions(); + virtual int GetNumScreens() { return 1; } ++ virtual int GetCurrentScreen() { return m_nScreen; } + virtual void ShowOSMouse(bool show); + virtual void ResetOSScreensaver(); + virtual bool EnableFrameLimiter(); ++ virtual void EnableSystemScreenSaver(bool bEnable); + + virtual void NotifyAppActiveChange(bool bActivated); ++ virtual void NotifyAppFocusChange(bool bGaining); + + virtual bool Minimize(); + virtual bool Restore() ; +@@ -59,31 +62,46 @@ + virtual bool Show(bool raise = true); + virtual void Register(IDispResource *resource); + virtual void Unregister(IDispResource *resource); ++ virtual bool HasCalibration(const RESOLUTION_INFO &resInfo); + + // Local to WinSystemX11 only + Display* GetDisplay() { return m_dpy; } + GLXWindow GetWindow() { return m_glWindow; } ++ GLXContext GetGlxContext() { return m_glContext; } ++ void NotifyXRREvent(); ++ void GetConnectedOutputs(std::vector *outputs); ++ bool IsCurrentOutput(CStdString output); ++ void NotifyMouseCoverage(bool covered); + + protected: +- bool RefreshGlxContext(); ++ bool RefreshGlxContext(bool force); + void CheckDisplayEvents(); + void OnLostDevice(); ++ bool SetWindow(int width, int height, bool fullscreen, const CStdString &output); + +- SDL_Surface* m_SDLSurface; ++ Window m_glWindow; + GLXContext m_glContext; +- GLXWindow m_glWindow; +- Window m_wmWindow; + Display* m_dpy; ++ Cursor m_invisibleCursor; ++ Pixmap m_icon; ++ bool m_bIsRotated; + bool m_bWasFullScreenBeforeMinimize; + bool m_minimized; ++ bool m_bIgnoreNextFocusMessage; + int m_RREventBase; + CCriticalSection m_resourceSection; + std::vector m_resources; + uint64_t m_dpyLostTime; ++ CStdString m_currentOutput; ++ bool m_windowDirty; ++ bool m_bIsInternalXrr; ++ bool m_newGlContext; + + private: + bool IsSuitableVisual(XVisualInfo *vInfo); + static int XErrorHandler(Display* dpy, XErrorEvent* error); ++ bool CreateIconPixmap(); ++ bool HasWindowManager(); + + CStopWatch m_screensaverReset; + }; +diff -Naur xbmc-12.0.4/xbmc/windowing/X11/XRandR.cpp xbmc-12.0.4.patch/xbmc/windowing/X11/XRandR.cpp +--- xbmc-12.0.4/xbmc/windowing/X11/XRandR.cpp 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/X11/XRandR.cpp 2013-03-10 13:00:12.330988113 +0100 +@@ -39,6 +39,7 @@ + CXRandR::CXRandR(bool query) + { + m_bInit = false; ++ m_numScreens = 1; + if (query) + Query(); + } +@@ -55,11 +56,23 @@ + return false; + + m_outputs.clear(); +- m_current.clear(); ++ // query all screens ++ // we are happy if at least one screen returns results ++ bool success = false; ++ for(unsigned int screennum=0; screennumValue(), "screen") != 0) ++ if (atoi(pRootElement->Attribute("id")) != screennum) + { + // TODO ERROR + return false; +@@ -92,12 +105,20 @@ + xoutput.name.TrimLeft(" \n\r\t"); + xoutput.name.TrimRight(" \n\r\t"); + xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0); ++ xoutput.screen = screennum; + xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0); + xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0); + xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0); + xoutput.y = (output->Attribute("y") != NULL ? atoi(output->Attribute("y")) : 0); + xoutput.wmm = (output->Attribute("wmm") != NULL ? atoi(output->Attribute("wmm")) : 0); + xoutput.hmm = (output->Attribute("hmm") != NULL ? atoi(output->Attribute("hmm")) : 0); ++ if (output->Attribute("rotation") != NULL ++ && (strcasecmp(output->Attribute("rotation"), "left") == 0 || strcasecmp(output->Attribute("rotation"), "right") == 0)) ++ { ++ xoutput.isRotated = true; + } + else -+ CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); - } -- else -- CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); ++ xoutput.isRotated = false; - Message *msg; - while (m_mixer.m_dataPort.ReceiveInMessage(&msg)) -@@ -3008,6 +3017,57 @@ void COutput::ReleaseBufferPool() + if (!xoutput.isConnected) + continue; +@@ -116,7 +137,6 @@ + xoutput.modes.push_back(xmode); + if (xmode.isCurrent) + { +- m_current.push_back(xoutput); + hascurrent = true; + } + } +@@ -139,25 +159,6 @@ + Query(true); + } + +-void CXRandR::RestoreState() +-{ +- vector::iterator outiter; +- for (outiter=m_current.begin() ; outiter!=m_current.end() ; outiter++) +- { +- vector modes = (*outiter).modes; +- vector::iterator modeiter; +- for (modeiter=modes.begin() ; modeiter!=modes.end() ; modeiter++) +- { +- XMode mode = *modeiter; +- if (mode.isCurrent) +- { +- SetMode(*outiter, mode); +- return; +- } +- } +- } +-} +- + bool CXRandR::SetMode(XOutput output, XMode mode) + { + if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == "")) +@@ -245,7 +246,7 @@ + m_currentMode = modeFound.id; + char cmd[255]; + if (getenv("XBMC_BIN_HOME")) +- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str()); ++ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str()); + else + return false; + CLog::Log(LOGINFO, "XRANDR: %s", cmd); +@@ -259,17 +260,6 @@ + return true; + } + +-XOutput CXRandR::GetCurrentOutput() +-{ +- Query(); +- for (unsigned int j = 0; j < m_outputs.size(); j++) +- { +- if(m_outputs[j].isConnected) +- return m_outputs[j]; +- } +- XOutput empty; +- return empty; +-} + XMode CXRandR::GetCurrentMode(CStdString outputName) + { + Query(); +@@ -343,6 +333,43 @@ } } -+void COutput::PreCleanup() ++void CXRandR::SetNumScreens(unsigned int num) +{ -+ -+ VdpStatus vdp_st; -+ -+ m_mixer.Dispose(); -+ -+ CSingleLock lock(m_bufferPool.renderPicSec); -+ for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) -+ { -+ if (m_bufferPool.outputSurfaces[i] == VDP_INVALID_HANDLE) -+ continue; -+ -+ // check if output surface is in use -+ bool used = false; -+ std::deque::iterator it; -+ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) -+ { -+ if (((*it)->sourceIdx == m_bufferPool.outputSurfaces[i]) && (*it)->valid) -+ { -+ used = true; -+ break; -+ } -+ } -+ if (used) -+ continue; -+ -+#ifdef GL_NV_vdpau_interop -+ // unmap surface -+ std::map::iterator it_map; -+ it_map = m_bufferPool.glOutputSurfaceMap.find(m_bufferPool.outputSurfaces[i]); -+ if (it_map == m_bufferPool.glOutputSurfaceMap.end()) -+ { -+ CLog::Log(LOGERROR, "%s - could not find gl surface", __FUNCTION__); -+ continue; -+ } -+ glVDPAUUnregisterSurfaceNV(it_map->second.glVdpauSurface); -+ glDeleteTextures(1, it_map->second.texture); -+ m_bufferPool.glOutputSurfaceMap.erase(it_map); -+#endif -+ -+ vdp_st = m_config.vdpProcs.vdp_output_surface_destroy(m_bufferPool.outputSurfaces[i]); -+ CheckStatus(vdp_st, __LINE__); -+ -+ m_bufferPool.outputSurfaces[i] = VDP_INVALID_HANDLE; -+ -+ CLog::Log(LOGDEBUG, "VDPAU::PreCleanup - released output surface"); -+ } -+ ++ m_numScreens = num; ++ m_bInit = false; +} + - void COutput::InitMixer() - { - for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index 471ad68..e33b6f5 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -286,6 +286,7 @@ class CMixer : private CThread - virtual ~CMixer(); - void Start(); - void Dispose(); -+ bool IsActive(); - CMixerControlProtocol m_controlPort; - CMixerDataProtocol m_dataPort; - protected: -@@ -454,6 +455,7 @@ class COutput : private CThread - bool DestroyGlxContext(); - bool EnsureBufferPool(); - void ReleaseBufferPool(); -+ void PreCleanup(); - void InitMixer(); - bool GLInit(); - void GLMapSurfaces(); --- -1.7.10 - - -From 046ece78a7cb25c9d9feca0d907c4547943843c5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 5 Mar 2013 17:01:53 +0100 -Subject: [PATCH 86/88] LinuxRendererGL: do not upscale if source equals dest - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 0bb924b..b5b0838 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -860,6 +860,14 @@ void CLinuxRendererGL::UpdateVideoFilter() - m_scalingMethod = VS_SCALINGMETHOD_LINEAR; - } - -+ // no need to scale if source equals dest -+ bool scale = ((float)m_sourceHeight != m_destRect.Height()) || -+ ((float)m_sourceWidth != m_destRect.Width()); -+ if(!scale) ++bool CXRandR::IsOutputConnected(CStdString name) ++{ ++ bool result = false; ++ Query(); ++ ++ for (unsigned int i = 0; i < m_outputs.size(); ++i) + { -+ m_scalingMethod = VS_SCALINGMETHOD_LINEAR; ++ if (m_outputs[i].name == name) ++ { ++ result = true; ++ break; ++ } + } ++ return result; ++} + - if (m_pVideoFilterShader) - { - m_pVideoFilterShader->Free(); --- -1.7.10 - - -From 1ac2908aa3fd49bdbfd7e271ddd3a8f6c552929c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 6 Mar 2013 07:35:10 +0100 -Subject: [PATCH 87/88] vdpau: set deinterlacing method to auto, if default - method not supported - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 38ef375..b69ae8c 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2091,13 +2091,15 @@ void CMixer::InitCycle() - } - else - { -- CLog::Log(LOGERROR, "CMixer::%s - interlace method not supported", __FUNCTION__); -+ CLog::Log(LOGERROR, "CMixer::%s - interlace method: %d not supported, setting to AUTO", __FUNCTION__, method); - m_mixersteps = 1; - m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; - m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU; - m_mixerInput[1].DVDPic.iFlags &= ~(DVP_FLAG_TOP_FIELD_FIRST | - DVP_FLAG_REPEAT_TOP_FIELD | - DVP_FLAG_INTERLACED); ++XOutput* CXRandR::GetOutput(CStdString outputName) ++{ ++ XOutput *result = 0; ++ Query(); ++ for (unsigned int i = 0; i < m_outputs.size(); ++i) ++ { ++ if (m_outputs[i].name == outputName) ++ { ++ result = &m_outputs[i]; ++ break; ++ } ++ } ++ return result; ++} + -+ g_settings.m_currentVideoSettings.m_InterlaceMethod = VS_INTERLACEMETHOD_AUTO; + CXRandR g_xrandr; + + #endif // HAS_XRANDR +diff -Naur xbmc-12.0.4/xbmc/windowing/X11/XRandR.h xbmc-12.0.4.patch/xbmc/windowing/X11/XRandR.h +--- xbmc-12.0.4/xbmc/windowing/X11/XRandR.h 2013-03-08 13:01:29.000000000 +0100 ++++ xbmc-12.0.4.patch/xbmc/windowing/X11/XRandR.h 2013-03-10 13:00:12.311988249 +0100 +@@ -79,6 +79,7 @@ } - } - else --- -1.7.10 - - -From 1f1e576daead67677f3cacbb592f47129ad6f5f5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Mar 2013 14:04:15 +0100 -Subject: [PATCH 88/88] buffering: do not drop in RenderManager - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index c99a555..bc764da 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1067,18 +1067,18 @@ void CXBMCRenderManager::PrepareNextRender() + CStdString name; + bool isConnected; ++ int screen; + int w; + int h; + int x; +@@ -86,6 +87,7 @@ + int wmm; + int hmm; + std::vector modes; ++ bool isRotated; + }; - // look ahead in the queue - // if the next frame is already late, skip the one we are about to render -- while (idx != m_iOutputRenderBuffer) -- { -- int idx_next = (idx + 1) % m_iNumRenderBuffers; -- if (m_renderBuffers[idx_next].timestamp <= clocktime) -- { -- FlipRenderBuffer(); -- idx = GetNextRenderBufferIndex(); -- CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); -- } -- else -- break; -- } -+// while (idx != m_iOutputRenderBuffer) -+// { -+// int idx_next = (idx + 1) % m_iNumRenderBuffers; -+// if (m_renderBuffers[idx_next].timestamp <= clocktime) -+// { -+// FlipRenderBuffer(); -+// idx = GetNextRenderBufferIndex(); -+// CLog::Log(LOGDEBUG,"%s - skip frame at render buffer index: %d", __FUNCTION__, idx); -+// } -+// else -+// break; -+// } + class CXRandR +@@ -93,13 +95,15 @@ + public: + CXRandR(bool query=false); + bool Query(bool force=false); ++ bool Query(bool force, int screennum); + std::vector GetModes(void); +- XOutput GetCurrentOutput(); + XMode GetCurrentMode(CStdString outputName); ++ XOutput *GetOutput(CStdString outputName); + bool SetMode(XOutput output, XMode mode); + void LoadCustomModeLinesToAllOutputs(void); + void SaveState(); +- void RestoreState(); ++ void SetNumScreens(unsigned int num); ++ bool IsOutputConnected(CStdString name); + //bool Has1080i(); + //bool Has1080p(); + //bool Has720p(); +@@ -107,10 +111,10 @@ - double presenttime = m_renderBuffers[idx].timestamp; + private: + bool m_bInit; +- std::vector m_current; + std::vector m_outputs; + CStdString m_currentOutput; + CStdString m_currentMode; ++ unsigned int m_numScreens; + }; --- -1.7.10 - + extern CXRandR g_xrandr;