From fe22f229a3df1a0cf0d8ec7fb2a479cc5de464cd Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 13:25:39 +0100 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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; From bf4f1626e991148b38a8c5b7b3e4c8ba54aea231 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 10 Mar 2013 20:32:22 +0100 Subject: [PATCH 08/14] xbmc: add PR2387 Signed-off-by: Stephan Raue --- .../xbmc/patches/xbmc-990.29-PR2387.patch | 1517 +++++++++++++++++ 1 file changed, 1517 insertions(+) create mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch b/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch new file mode 100644 index 0000000000..2e85748d70 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch @@ -0,0 +1,1517 @@ +From 9d0695f2ae5f2a4d98c4ec6882fecd8209a425bc Mon Sep 17 00:00:00 2001 +From: Lars Op den Kamp +Date: Thu, 28 Feb 2013 20:41:38 +0100 +Subject: [PATCH] [cec] rebased PR1794 + fixes for Frodo + +--- + XBMC.xcodeproj/project.pbxproj | 13 +++ + configure.in | 40 +------ + project/BuildDependencies/scripts/libcec_d.txt | 2 +- + project/VS2010Express/XBMC.vcxproj | 2 + + project/VS2010Express/XBMC.vcxproj.filters | 6 + + system/peripherals.xml | 31 ++---- + tools/android/depends/libcec/Makefile | 4 +- + tools/darwin/depends/libcec/Makefile | 2 +- + xbmc/peripherals/PeripheralTypes.h | 76 ++++++++++++- + xbmc/peripherals/Peripherals.cpp | 62 +++++------ + xbmc/peripherals/Peripherals.h | 7 +- + xbmc/peripherals/bus/Makefile.in | 4 +- + xbmc/peripherals/bus/PeripheralBus.cpp | 81 +++----------- + xbmc/peripherals/bus/PeripheralBus.h | 23 +--- + xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp | 69 ------------ + xbmc/peripherals/bus/linux/PeripheralBusRPi.h | 40 ------- + .../bus/linux/PeripheralBusUSBLibUSB.cpp | 3 +- + .../bus/linux/PeripheralBusUSBLibUdev.cpp | 4 +- + xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp | 1 + + xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp | 116 ++++++++++++++++++++ + xbmc/peripherals/bus/virtual/PeripheralBusCEC.h | 57 ++++++++++ + xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp | 5 +- + xbmc/peripherals/devices/Peripheral.cpp | 50 ++++----- + xbmc/peripherals/devices/Peripheral.h | 6 +- + xbmc/peripherals/devices/PeripheralBluetooth.cpp | 4 +- + xbmc/peripherals/devices/PeripheralBluetooth.h | 2 +- + xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 52 ++------- + xbmc/peripherals/devices/PeripheralCecAdapter.h | 4 +- + xbmc/peripherals/devices/PeripheralDisk.cpp | 5 +- + xbmc/peripherals/devices/PeripheralDisk.h | 2 +- + xbmc/peripherals/devices/PeripheralHID.cpp | 5 +- + xbmc/peripherals/devices/PeripheralHID.h | 2 +- + xbmc/peripherals/devices/PeripheralImon.cpp | 4 +- + xbmc/peripherals/devices/PeripheralImon.h | 2 +- + xbmc/peripherals/devices/PeripheralNIC.cpp | 5 +- + xbmc/peripherals/devices/PeripheralNIC.h | 2 +- + xbmc/peripherals/devices/PeripheralNyxboard.cpp | 4 +- + xbmc/peripherals/devices/PeripheralNyxboard.h | 2 +- + xbmc/peripherals/devices/PeripheralTuner.cpp | 4 +- + xbmc/peripherals/devices/PeripheralTuner.h | 2 +- + 40 files changed, 404 insertions(+), 401 deletions(-) + delete mode 100644 xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp + delete mode 100644 xbmc/peripherals/bus/linux/PeripheralBusRPi.h + create mode 100644 xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp + create mode 100644 xbmc/peripherals/bus/virtual/PeripheralBusCEC.h + +diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj +index bf4a009..fbcd662 100644 +diff --git a/configure.in b/configure.in +index 4769315..4472e3e 100644 +--- a/configure.in ++++ b/configure.in +@@ -157,8 +157,6 @@ libusb_disabled="== libusb disabled. Plug and play USB device support will not b + libusb_disabled_udev_found="== libusb disabled. ==" + libcec_enabled="== libcec enabled. ==" + libcec_disabled="== libcec disabled. CEC adapter support will not be available. ==" +-libcec_disabled_missing_libs="== libcec disabled because it either needs libudev, or libusb a compatible version of the RPi API. CEC adapter support will not be available. ==" +-cec_rpi_api_missing="== no compatible RPi API found ==" + + # External library message strings + external_libraries_enabled="== Use of all supported external libraries enabled. ==" +@@ -1455,46 +1453,18 @@ fi + + # libcec + USE_LIBCEC=0 +-USE_CEC_RPI_API=0 +-use_rpi_cec_api="auto" + if test "x$use_libcec" != "xno"; then +- case "${host_cpu}" in +- arm*) +- echo "will check for RPi support" +- AC_CHECK_HEADER(interface/vmcs_host/vc_cec.h,,use_rpi_cec_api="no") +- ;; +- *) +- echo "will not check for RPi support (unsupported cpu: ${host_cpu})" +- use_rpi_cec_api="no" +- ;; +- esac +- +- # libcec needs libudev, libusb or the RPi API under linux, or the device will never be detected. +- if test "$host_vendor" != "apple" && test "$use_libusb" = "no" && test "$use_libudev" = "no" && test "$use_rpi_cec_api" = "no"; then +- if test "x$use_libcec" != "xauto"; then +- AC_MSG_ERROR($libcec_disabled_missing_libs) +- else +- use_libcec="no" +- AC_MSG_NOTICE($libcec_disabled_missing_libs) +- fi +- fi +- + # libcec is dyloaded, so we need to check for its headers and link any depends. + if test "x$use_libcec" != "xno"; then + if test "x$use_libcec" != "xauto"; then +- PKG_CHECK_MODULES([CEC],[libcec >= 2.0.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)]) ++ PKG_CHECK_MODULES([CEC],[libcec >= 2.1.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)]) + else +- PKG_CHECK_MODULES([CEC],[libcec >= 2.0.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) ++ PKG_CHECK_MODULES([CEC],[libcec >= 2.1.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) + fi + + if test "x$use_libcec" != "xno"; then + INCLUDES="$INCLUDES $CEC_CFLAGS" + USE_LIBCEC=1;AC_DEFINE([HAVE_LIBCEC],[1],["Define to 1 if libcec is installed"]) +- if test "x$use_rpi_cec_api" != "xno"; then +- LIBS+=" -lvcos -lvchiq_arm" +- AC_DEFINE([HAVE_CEC_RPI_API],[1],["Define to 1 if the CEC RPi API is installed"]) +- USE_CEC_RPI_API=1 +- fi + XB_FIND_SONAME([LIBCEC],[cec],[use_libcec]) + AC_MSG_NOTICE($libcec_enabled) + else +@@ -2255,11 +2225,6 @@ fi + + if test "x$use_libcec" != "xno"; then + final_message="$final_message\n libcec support:\tYes" +- if test "x$use_rpi_cec_api" != "xno"; then +- final_message="$final_message\n libcec RPi support:\tYes" +- else +- final_message="$final_message\n libcec RPi support:\tNo" +- fi + else + final_message="$final_message\n libcec support:\tNo" + fi +@@ -2451,7 +2416,6 @@ AC_SUBST(USE_AIRTUNES) + AC_SUBST(USE_LIBUDEV) + AC_SUBST(USE_LIBUSB) + AC_SUBST(USE_LIBCEC) +-AC_SUBST(USE_CEC_RPI_API) + AC_SUBST(USE_MYSQL) + AC_SUBST(USE_WEB_SERVER) + AC_SUBST(USE_UPNP) +diff --git a/project/BuildDependencies/scripts/libcec_d.txt b/project/BuildDependencies/scripts/libcec_d.txt +index c1419b5..2c7d495 100644 +diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj +index fb0947e..7e32ccc 100644 +diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters +index 53a6c97..52a5373 100644 +diff --git a/system/peripherals.xml b/system/peripherals.xml +index 967b96c..68205df 100644 +--- a/system/peripherals.xml ++++ b/system/peripherals.xml +@@ -7,30 +7,7 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ + + + +@@ -54,6 +31,12 @@ + + + ++ ++ ++ ++ + + + +diff --git a/tools/android/depends/libcec/Makefile b/tools/android/depends/libcec/Makefile +index 7d9b6b8..0147147 100644 +--- a/tools/android/depends/libcec/Makefile ++++ b/tools/android/depends/libcec/Makefile +@@ -3,7 +3,7 @@ DEPS= ../Makefile.include Makefile + + # lib name, version + LIBNAME=libcec +-VERSION=2.0.5-3 ++VERSION=2.1.0 + SOURCE=$(LIBNAME)-$(VERSION) + ARCHIVE=$(SOURCE).tar.gz + +@@ -11,7 +11,7 @@ ARCHIVE=$(SOURCE).tar.gz + CONFIGURE=./configure --prefix=$(PREFIX) --host=$(HOST) \ + ac_cv_search_dlopen=yes + +-LIBDYLIB=$(PLATFORM)/src/lib/.libs/libcec.so.2.0.0 ++LIBDYLIB=$(PLATFORM)/src/lib/.libs/libcec.so.2.0.1 + + all: .installed-$(PLATFORM) + +diff --git a/tools/darwin/depends/libcec/Makefile b/tools/darwin/depends/libcec/Makefile +index 3e84bff..b7970dd 100644 +--- a/tools/darwin/depends/libcec/Makefile ++++ b/tools/darwin/depends/libcec/Makefile +@@ -3,7 +3,7 @@ include ../config.site.mk + + # lib name, version + LIBNAME=libcec +-VERSION=2.0.5-3 ++VERSION=2.1.0 + SOURCE=$(LIBNAME)-$(VERSION) + ARCHIVE=$(SOURCE).tar.gz + +diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h +index 3cd7691..03030d4 100644 +--- a/xbmc/peripherals/PeripheralTypes.h ++++ b/xbmc/peripherals/PeripheralTypes.h +@@ -35,7 +35,8 @@ + PERIPHERAL_BUS_UNKNOWN = 0, + PERIPHERAL_BUS_USB, + PERIPHERAL_BUS_PCI, +- PERIPHERAL_BUS_RPI ++ PERIPHERAL_BUS_RPI, ++ PERIPHERAL_BUS_CEC + }; + + enum PeripheralFeature +@@ -143,6 +144,8 @@ + return "pci"; + case PERIPHERAL_BUS_RPI: + return "rpi"; ++ case PERIPHERAL_BUS_CEC: ++ return "cec"; + default: + return "unknown"; + } +@@ -159,6 +162,8 @@ + return PERIPHERAL_BUS_PCI; + else if (strTypeLowerCase.Equals("rpi")) + return PERIPHERAL_BUS_RPI; ++ else if (strTypeLowerCase.Equals("cec")) ++ return PERIPHERAL_BUS_CEC; + + return PERIPHERAL_BUS_UNKNOWN; + }; +@@ -180,4 +185,73 @@ + strHexString.Format("%04X", iVal); + }; + }; ++ ++ class PeripheralScanResult ++ { ++ public: ++ PeripheralScanResult(const PeripheralBusType busType) : ++ m_type(PERIPHERAL_UNKNOWN), ++ m_iVendorId(0), ++ m_iProductId(0), ++ m_mappedType(PERIPHERAL_UNKNOWN), ++ m_busType(busType), ++ m_mappedBusType(busType), ++ m_iSequence(0) {} ++ ++ PeripheralScanResult(void) : ++ m_type(PERIPHERAL_UNKNOWN), ++ m_iVendorId(0), ++ m_iProductId(0), ++ m_mappedType(PERIPHERAL_UNKNOWN), ++ m_busType(PERIPHERAL_BUS_UNKNOWN), ++ m_mappedBusType(PERIPHERAL_BUS_UNKNOWN), ++ m_iSequence(0) {} ++ ++ bool operator ==(const PeripheralScanResult& right) const ++ { ++ return m_iVendorId == right.m_iVendorId && ++ m_iProductId == right.m_iProductId && ++ m_type == right.m_type && ++ m_busType == right.m_busType && ++ m_strLocation.Equals(right.m_strLocation); ++ } ++ ++ bool operator !=(const PeripheralScanResult& right) const ++ { ++ return !(*this == right); ++ } ++ ++ PeripheralType m_type; ++ CStdString m_strLocation; ++ int m_iVendorId; ++ int m_iProductId; ++ PeripheralType m_mappedType; ++ CStdString m_strDeviceName; ++ PeripheralBusType m_busType; ++ PeripheralBusType m_mappedBusType; ++ unsigned int m_iSequence; // when more than one adapter of the same type is found ++ }; ++ ++ struct PeripheralScanResults ++ { ++ bool GetDeviceOnLocation(const CStdString& strLocation, PeripheralScanResult* result) const ++ { ++ for (std::vector::const_iterator it = m_results.begin(); it != m_results.end(); it++) ++ { ++ if ((*it).m_strLocation == strLocation) ++ { ++ *result = *it; ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ bool ContainsResult(const PeripheralScanResult& result) const ++ { ++ return std::find(m_results.begin(), m_results.end(), result) != m_results.end(); ++ } ++ ++ std::vector m_results; ++ }; + } +diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp +index 3ce8c07..c5fadd9 100644 +--- a/xbmc/peripherals/Peripherals.cpp ++++ b/xbmc/peripherals/Peripherals.cpp +@@ -31,8 +31,8 @@ + #include "bus/PeripheralBusUSB.h" + #include "dialogs/GUIDialogPeripheralManager.h" + +-#ifdef HAVE_CEC_RPI_API +-#include "bus/linux/PeripheralBusRPi.h" ++#if defined(HAVE_LIBCEC) ++#include "bus/virtual/PeripheralBusCEC.h" + #endif + + #include "threads/SingleLock.h" +@@ -84,8 +84,8 @@ void CPeripherals::Initialise(void) + #if defined(HAVE_PERIPHERAL_BUS_USB) + m_busses.push_back(new CPeripheralBusUSB(this)); + #endif +-#ifdef HAVE_CEC_RPI_API +- m_busses.push_back(new CPeripheralBusRPi(this)); ++#if defined(HAVE_LIBCEC) ++ m_busses.push_back(new CPeripheralBusCEC(this)); + #endif + + /* initialise all known busses */ +@@ -229,54 +229,50 @@ bool CPeripherals::HasPeripheralWithFeature(const PeripheralFeature feature, Per + return (GetPeripheralsWithFeature(dummy, feature, busType) > 0); + } + +-CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId /* = 0 */, int iProductId /* = 0 */) ++CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralScanResult& result) + { + CPeripheral *peripheral = NULL; ++ PeripheralScanResult mappedResult = result; ++ if (mappedResult.m_busType == PERIPHERAL_BUS_UNKNOWN) ++ mappedResult.m_busType = bus.Type(); ++ + /* check whether there's something mapped in peripherals.xml */ +- PeripheralType mappedType = type; +- CStdString strDeviceName; +- int iMappingPtr = GetMappingForDevice(bus, type, iVendorId, iProductId); +- bool bHasMapping(iMappingPtr >= 0); +- if (bHasMapping) +- { +- mappedType = m_mappings[iMappingPtr].m_mappedTo; +- strDeviceName = m_mappings[iMappingPtr].m_strDeviceName; +- } +- else ++ if (!GetMappingForDevice(bus, mappedResult)) + { + /* don't create instances for devices that aren't mapped in peripherals.xml */ + return NULL; + } + +- switch(mappedType) ++ switch(mappedResult.m_mappedType) + { + case PERIPHERAL_HID: +- peripheral = new CPeripheralHID(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralHID(mappedResult); + break; + + case PERIPHERAL_NIC: +- peripheral = new CPeripheralNIC(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralNIC(mappedResult); + break; + + case PERIPHERAL_DISK: +- peripheral = new CPeripheralDisk(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralDisk(mappedResult); + break; + + case PERIPHERAL_NYXBOARD: +- peripheral = new CPeripheralNyxboard(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralNyxboard(mappedResult); + break; + + case PERIPHERAL_TUNER: +- peripheral = new CPeripheralTuner(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralTuner(mappedResult); + break; + + case PERIPHERAL_BLUETOOTH: +- peripheral = new CPeripheralBluetooth(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralBluetooth(mappedResult); + break; + + case PERIPHERAL_CEC: + #if defined(HAVE_LIBCEC) +- peripheral = new CPeripheralCecAdapter(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ if (bus.Type() == PERIPHERAL_BUS_CEC) ++ peripheral = new CPeripheralCecAdapter(mappedResult); + #else + if (!m_bMissingLibCecWarningDisplayed) + { +@@ -288,7 +284,7 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera + break; + + case PERIPHERAL_IMON: +- peripheral = new CPeripheralImon(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); ++ peripheral = new CPeripheralImon(mappedResult); + break; + + default: +@@ -305,7 +301,7 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera + } + else + { +- CLog::Log(LOGDEBUG, "%s - failed to initialise peripheral on '%s'", __FUNCTION__, strLocation.c_str()); ++ CLog::Log(LOGDEBUG, "%s - failed to initialise peripheral on '%s'", __FUNCTION__, mappedResult.m_strLocation.c_str()); + delete peripheral; + peripheral = NULL; + } +@@ -340,7 +336,7 @@ void CPeripherals::OnDeviceDeleted(const CPeripheralBus &bus, const CPeripheral + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(35006), peripheral.DeviceName()); + } + +-int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const ++bool CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, PeripheralScanResult& result) const + { + /* check all mappings in the order in which they are defined in peripherals.xml */ + for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++) +@@ -355,24 +351,26 @@ int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const Periphera + else + { + for (unsigned int i = 0; i < mapping.m_PeripheralID.size(); i++) +- if (mapping.m_PeripheralID[i].m_iVendorId == iVendorId && mapping.m_PeripheralID[i].m_iProductId == iProductId) ++ if (mapping.m_PeripheralID[i].m_iVendorId == result.m_iVendorId && mapping.m_PeripheralID[i].m_iProductId == result.m_iProductId) + bProductMatch = true; + } + + bool bBusMatch = (mapping.m_busType == PERIPHERAL_BUS_UNKNOWN || mapping.m_busType == bus.Type()); +- bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == classType); ++ bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == result.m_type); + + if (bProductMatch && bBusMatch && bClassMatch) + { + CStdString strVendorId, strProductId; +- PeripheralTypeTranslator::FormatHexString(iVendorId, strVendorId); +- PeripheralTypeTranslator::FormatHexString(iProductId, strProductId); ++ PeripheralTypeTranslator::FormatHexString(result.m_iVendorId, strVendorId); ++ PeripheralTypeTranslator::FormatHexString(result.m_iProductId, strProductId); + CLog::Log(LOGDEBUG, "%s - device (%s:%s) mapped to %s (type = %s)", __FUNCTION__, strVendorId.c_str(), strProductId.c_str(), mapping.m_strDeviceName.c_str(), PeripheralTypeTranslator::TypeToString(mapping.m_mappedTo)); +- return iMappingPtr; ++ result.m_mappedType = m_mappings[iMappingPtr].m_mappedTo; ++ result.m_strDeviceName = m_mappings[iMappingPtr].m_strDeviceName; ++ return true; + } + } + +- return -1; ++ return false; + } + + void CPeripherals::GetSettingsFromMapping(CPeripheral &peripheral) const +diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h +index ac94699..9594ff8 100644 +--- a/xbmc/peripherals/Peripherals.h ++++ b/xbmc/peripherals/Peripherals.h +@@ -111,11 +111,10 @@ + /*! + * @brief Creates a new instance of a peripheral. + * @param bus The bus on which this peripheral is present. +- * @param type The type of the new peripheral. +- * @param strLocation The location on the bus. ++ * @param result The scan result from the device scanning code. + * @return The new peripheral or NULL if it could not be created. + */ +- CPeripheral *CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId = 0, int iProductId = 0); ++ CPeripheral *CreatePeripheral(CPeripheralBus &bus, const PeripheralScanResult& result); + + /*! + * @brief Add the settings that are defined in the mappings file to the peripheral (if there is anything defined). +@@ -200,7 +199,7 @@ + private: + CPeripherals(void); + bool LoadMappings(void); +- int GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const; ++ bool GetMappingForDevice(const CPeripheralBus &bus, PeripheralScanResult& result) const; + static void GetSettingsFromMappingsFile(TiXmlElement *xmlNode, std::map &m_settings); + + bool m_bInitialised; +diff --git a/xbmc/peripherals/bus/Makefile.in b/xbmc/peripherals/bus/Makefile.in +index 01fa4e2..2262e4a 100644 +--- a/xbmc/peripherals/bus/Makefile.in ++++ b/xbmc/peripherals/bus/Makefile.in +@@ -12,8 +12,8 @@ ifeq ($(findstring osx,@ARCH@),osx) + SRCS += osx/PeripheralBusUSB.cpp + endif + +-ifeq (@USE_CEC_RPI_API@,1) +-SRCS += linux/PeripheralBusRPi.cpp ++ifeq (@USE_LIBCEC@,1) ++SRCS += virtual/PeripheralBusCEC.cpp + endif + + LIB = peripheral-bus.a +diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp +index 727f7c9..b17a9f1 100644 +--- a/xbmc/peripherals/bus/PeripheralBus.cpp ++++ b/xbmc/peripherals/bus/PeripheralBus.cpp +@@ -29,65 +29,6 @@ + + #define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000 + +-bool PeripheralScanResult::operator ==(const PeripheralScanResult &right) const +-{ +- return m_iVendorId == right.m_iVendorId && +- m_iProductId == right.m_iProductId && +- m_type == right.m_type && +- m_strLocation.Equals(right.m_strLocation); +-} +- +-bool PeripheralScanResult::operator !=(const PeripheralScanResult &right) const +-{ +- return !(*this == right); +-} +- +-bool PeripheralScanResult::operator ==(const CPeripheral &right) const +-{ +- return m_iVendorId == right.VendorId() && +- m_iProductId == right.ProductId() && +- m_type == right.Type() && +- m_strLocation.Equals(right.Location()); +-} +- +-bool PeripheralScanResult::operator !=(const CPeripheral &right) const +-{ +- return !(*this == right); +-} +- +-bool PeripheralScanResults::GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const +-{ +- bool bReturn(false); +- +- for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) +- { +- if (m_results.at(iDevicePtr).m_strLocation == strLocation) +- { +- *result = m_results.at(iDevicePtr); +- bReturn = true; +- break; +- } +- } +- +- return bReturn; +-} +- +-bool PeripheralScanResults::ContainsResult(const PeripheralScanResult &result) const +-{ +- bool bReturn(false); +- +- for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) +- { +- if (m_results.at(iDevicePtr) == result) +- { +- bReturn = true; +- break; +- } +- } +- +- return bReturn; +-} +- + CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) : + CThread("XBMC Peripherals"), + m_iRescanTime(PERIPHERAL_DEFAULT_RESCAN_INTERVAL), +@@ -137,9 +78,9 @@ void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &resul + for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--) + { + CPeripheral *peripheral = m_peripherals.at(iDevicePtr); +- PeripheralScanResult updatedDevice; ++ PeripheralScanResult updatedDevice(m_type); + if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) || +- updatedDevice != *peripheral) ++ *peripheral != updatedDevice) + { + /* device removed */ + removedPeripherals.push_back(peripheral); +@@ -170,9 +111,9 @@ void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results) + CSingleLock lock(m_critSection); + for (unsigned int iResultPtr = 0; iResultPtr < results.m_results.size(); iResultPtr++) + { +- PeripheralScanResult result = results.m_results.at(iResultPtr); ++ const PeripheralScanResult& result = results.m_results.at(iResultPtr); + if (!HasPeripheral(result.m_strLocation)) +- g_peripherals.CreatePeripheral(*this, result.m_type, result.m_strLocation, result.m_iVendorId, result.m_iProductId); ++ g_peripherals.CreatePeripheral(*this, result); + } + } + +@@ -246,6 +187,20 @@ int CPeripheralBus::GetPeripheralsWithFeature(vector &results, co + return iReturn; + } + ++size_t CPeripheralBus::GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const ++{ ++ int iReturn(0); ++ CSingleLock lock(m_critSection); ++ for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) ++ { ++ if (m_peripherals.at(iPeripheralPtr)->VendorId() == iVendorId && ++ m_peripherals.at(iPeripheralPtr)->ProductId() == iProductId) ++ iReturn++; ++ } ++ ++ return iReturn; ++} ++ + void CPeripheralBus::Process(void) + { + while (!m_bStop) +diff --git a/xbmc/peripherals/bus/PeripheralBus.h b/xbmc/peripherals/bus/PeripheralBus.h +index 96426a9..29ff7d7 100644 +--- a/xbmc/peripherals/bus/PeripheralBus.h ++++ b/xbmc/peripherals/bus/PeripheralBus.h +@@ -31,28 +31,6 @@ + { + class CPeripherals; + +- struct PeripheralScanResult +- { +- bool operator ==(const PeripheralScanResult &right) const; +- bool operator !=(const PeripheralScanResult &right) const; +- +- bool operator ==(const CPeripheral &right) const; +- bool operator !=(const CPeripheral &right) const; +- +- PeripheralType m_type; +- CStdString m_strLocation; +- int m_iVendorId; +- int m_iProductId; +- }; +- +- struct PeripheralScanResults +- { +- bool GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const; +- bool ContainsResult(const PeripheralScanResult &result) const; +- +- std::vector m_results; +- }; +- + /*! + * @class CPeripheralBus + * This represents a bus on the system. By default, this bus instance will scan for changes every second. +@@ -100,6 +78,7 @@ + virtual int GetPeripheralsWithFeature(std::vector &results, const PeripheralFeature feature) const; + + virtual size_t GetNumberOfPeripherals() const; ++ virtual size_t GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const; + + /*! + * @brief Get all features that are supported by devices on this bus. +diff --git a/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp b/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp +deleted file mode 100644 +index 8a436e4..0000000 +--- a/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp ++++ /dev/null +@@ -1,69 +0,0 @@ +-/* +- * Copyright (C) 2005-2012 Team XBMC +- * http://xbmc.org +- * +- * This Program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This Program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#include "PeripheralBusRPi.h" +-#include +- +-extern "C" { +-#include +-#include +-} +- +-using namespace PERIPHERALS; +- +-#define RPI_PERIPHERAL_BUS_VID 0x2708 +-#define RPI_PERIPHERAL_CEC_PID 0x1001 +- +-CPeripheralBusRPi::CPeripheralBusRPi(CPeripherals *manager) : +- CPeripheralBus(manager, PERIPHERAL_BUS_RPI) +-{ +- m_bNeedsPolling = false; +-} +- +-bool CPeripheralBusRPi::PerformDeviceScan(PeripheralScanResults &results) +-{ +- if (FindAdapter()) +- { +- PeripheralScanResult result; +- result.m_iVendorId = RPI_PERIPHERAL_BUS_VID; +- result.m_iProductId = RPI_PERIPHERAL_CEC_PID; +- result.m_type = PERIPHERAL_CEC; +- result.m_strLocation = CEC_RPI_VIRTUAL_COM; +- +- if (!results.ContainsResult(result)) +- results.m_results.push_back(result); +- } +- +- return true; +-} +- +-bool CPeripheralBusRPi::FindAdapter(void) +-{ +- uint8_t iResult; +- +- VCHI_INSTANCE_T vchiq_instance; +- if ((iResult = vchi_initialise(&vchiq_instance)) != VCHIQ_SUCCESS) +- return false; +- +- if ((iResult = vchi_connect(NULL, 0, vchiq_instance)) != VCHIQ_SUCCESS) +- return false; +- +- return true; +-} +diff --git a/xbmc/peripherals/bus/linux/PeripheralBusRPi.h b/xbmc/peripherals/bus/linux/PeripheralBusRPi.h +deleted file mode 100644 +index e660401..0000000 +--- a/xbmc/peripherals/bus/linux/PeripheralBusRPi.h ++++ /dev/null +@@ -1,40 +0,0 @@ +-#pragma once +-/* +- * Copyright (C) 2005-2012 Team XBMC +- * http://xbmc.org +- * +- * This Program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This Program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with XBMC; see the file COPYING. If not, see +- * . +- * +- */ +- +-#include "peripherals/bus/PeripheralBus.h" +-#include "peripherals/devices/Peripheral.h" +- +-namespace PERIPHERALS +-{ +- class CPeripherals; +- +- class CPeripheralBusRPi : public CPeripheralBus +- { +- public: +- CPeripheralBusRPi(CPeripherals *manager); +- virtual ~CPeripheralBusRPi(void) {}; +- +- bool PerformDeviceScan(PeripheralScanResults &results); +- +- private: +- bool FindAdapter(void); +- }; +-} +diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp +index 659ebf0..563c96e 100644 +--- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp ++++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp +@@ -43,7 +43,7 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) + struct usb_device *dev; + for (dev = bus->devices; dev; dev = dev->next) + { +- PeripheralScanResult result; ++ PeripheralScanResult result(m_type); + result.m_iVendorId = dev->descriptor.idVendor; + result.m_iProductId = dev->descriptor.idProduct; + result.m_type = (dev->descriptor.bDeviceClass == USB_CLASS_PER_INTERFACE && dev->descriptor.bNumConfigurations > 0 && +@@ -55,6 +55,7 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) + #else + result.m_strLocation.Format("/bus%s/dev%s", bus->dirname, dev->filename); + #endif ++ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); + if (!results.ContainsResult(result)) + results.m_results.push_back(result); + } +diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp +index b7a0061..ca21e06 100644 +--- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp ++++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp +@@ -152,12 +152,12 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) + iClass = USB_CLASS_HID; + } + +- PeripheralScanResult result; ++ PeripheralScanResult result(m_type); + result.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(udev_device_get_sysattr_value(dev, "idVendor")); + result.m_iProductId = PeripheralTypeTranslator::HexStringToInt(udev_device_get_sysattr_value(dev, "idProduct")); + result.m_type = GetType(iClass); + result.m_strLocation = udev_device_get_syspath(dev); +- ++ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); + if (!results.ContainsResult(result)) + results.m_results.push_back(result); + } +diff --git a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp +index b0e3617..78bd224 100644 +--- a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp ++++ b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp +@@ -266,6 +266,7 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera + else + privateDataRef->result.m_type = refCon->GetType(bDeviceClass); + ++ privateDataRef->result.m_iSequence = refCon->GetNumberOfPeripheralsWithId(privateDataRef->result.m_iVendorId, privateDataRef->result.m_iProductId); + if (!refCon->m_scan_results.ContainsResult(privateDataRef->result)) + { + // register this usb device for an interest notification callback. +diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp +new file mode 100644 +index 0000000..da169c1 +--- /dev/null ++++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp +@@ -0,0 +1,116 @@ ++/* ++ * Copyright (C) 2005-2012 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++#if defined(HAVE_LIBCEC) ++#include "PeripheralBusCEC.h" ++#include "peripherals/Peripherals.h" ++#include "utils/log.h" ++#include "DynamicDll.h" ++ ++#include ++ ++using namespace PERIPHERALS; ++using namespace CEC; ++using namespace std; ++ ++class DllLibCECInterface ++{ ++public: ++ virtual ~DllLibCECInterface() {} ++ virtual ICECAdapter* CECInitialise(libcec_configuration *configuration)=0; ++ virtual void* CECDestroy(ICECAdapter *adapter)=0; ++}; ++ ++class PERIPHERALS::DllLibCEC : public DllDynamic, DllLibCECInterface ++{ ++ DECLARE_DLL_WRAPPER(DllLibCEC, DLL_PATH_LIBCEC) ++ ++ DEFINE_METHOD1(ICECAdapter*, CECInitialise, (libcec_configuration *p1)) ++ DEFINE_METHOD1(void* , CECDestroy, (ICECAdapter *p1)) ++ ++ BEGIN_METHOD_RESOLVE() ++ RESOLVE_METHOD_RENAME(CECInitialise, CECInitialise) ++ RESOLVE_METHOD_RENAME(CECDestroy, CECDestroy) ++ END_METHOD_RESOLVE() ++}; ++ ++CPeripheralBusCEC::CPeripheralBusCEC(CPeripherals *manager) : ++ CPeripheralBus(manager, PERIPHERAL_BUS_CEC), ++ m_dll(new DllLibCEC), ++ m_cecAdapter(NULL) ++{ ++ m_iRescanTime = 1000; ++ if (!m_dll->Load() || !m_dll->IsLoaded()) ++ { ++ delete m_dll; ++ m_dll = NULL; ++ } ++ else ++ { ++ m_cecAdapter = m_dll->CECInitialise(&m_configuration); ++ } ++} ++ ++CPeripheralBusCEC::~CPeripheralBusCEC(void) ++{ ++ if (m_dll && m_cecAdapter) ++ m_dll->CECDestroy(m_cecAdapter); ++ delete m_dll; ++} ++ ++bool CPeripheralBusCEC::PerformDeviceScan(PeripheralScanResults &results) ++{ ++ if (!m_dll || !m_cecAdapter) ++ return false; ++ ++ cec_adapter_descriptor deviceList[10]; ++ int8_t iFound = m_cecAdapter->DetectAdapters(deviceList, 10, NULL, true); ++ ++ for (uint8_t iDevicePtr = 0; iDevicePtr < iFound; iDevicePtr++) ++ { ++ PeripheralScanResult result(m_type); ++ result.m_iVendorId = deviceList[iDevicePtr].iVendorId; ++ result.m_iProductId = deviceList[iDevicePtr].iProductId; ++ result.m_strLocation = deviceList[iDevicePtr].strComName; ++ result.m_type = PERIPHERAL_CEC; ++ ++ // override the bus type, so users don't have to reconfigure their adapters ++ switch(deviceList[iDevicePtr].adapterType) ++ { ++ case ADAPTERTYPE_P8_EXTERNAL: ++ case ADAPTERTYPE_P8_DAUGHTERBOARD: ++ result.m_mappedBusType = PERIPHERAL_BUS_USB; ++ break; ++ case ADAPTERTYPE_RPI: ++ result.m_mappedBusType = PERIPHERAL_BUS_RPI; ++ break; ++ default: ++ break; ++ } ++ ++ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); ++ if (!results.ContainsResult(result)) ++ results.m_results.push_back(result); ++ } ++ return true; ++} ++ ++#endif +diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h +new file mode 100644 +index 0000000..acba01a +--- /dev/null ++++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h +@@ -0,0 +1,57 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "peripherals/bus/PeripheralBus.h" ++#include "peripherals/devices/Peripheral.h" ++ ++// undefine macro isset, it collides with function in cectypes.h ++#ifdef isset ++#undef isset ++#endif ++#include ++ ++namespace CEC ++{ ++ class ICECAdapter; ++} ++ ++namespace PERIPHERALS ++{ ++ class CPeripherals; ++ class DllLibCEC; ++ ++ class CPeripheralBusCEC : public CPeripheralBus ++ { ++ public: ++ CPeripheralBusCEC(CPeripherals *manager); ++ virtual ~CPeripheralBusCEC(void); ++ ++ /*! ++ * @see PeripheralBus::PerformDeviceScan() ++ */ ++ bool PerformDeviceScan(PeripheralScanResults &results); ++ ++ private: ++ DllLibCEC* m_dll; ++ CEC::ICECAdapter* m_cecAdapter; ++ CEC::libcec_configuration m_configuration; ++ }; ++} +diff --git a/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp +index 811e0d1..fb55561 100644 +--- a/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp ++++ b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp +@@ -104,14 +104,15 @@ bool CPeripheralBusUSB::PerformDeviceScan(const GUID *guid, const PeripheralType + + if ((strTmp.Find("&mi_") < 0) || (strTmp.Find("&mi_00") >= 0)) + { +- PeripheralScanResult prevDevice; ++ PeripheralScanResult prevDevice(m_type); + if (!results.GetDeviceOnLocation(devicedetailData->DevicePath, &prevDevice)) + { +- PeripheralScanResult result; ++ PeripheralScanResult result(m_type); + result.m_strLocation = devicedetailData->DevicePath; + result.m_type = type; + result.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(strVendorId.c_str()); + result.m_iProductId = PeripheralTypeTranslator::HexStringToInt(strProductId.c_str()); ++ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); + + if (!results.ContainsResult(result)) + results.m_results.push_back(result); +diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp +index e9cde30..ad2227a 100644 +--- a/xbmc/peripherals/devices/Peripheral.cpp ++++ b/xbmc/peripherals/devices/Peripheral.cpp +@@ -38,39 +38,23 @@ struct SortBySettingsOrder + } + }; + +-CPeripheral::CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- m_type(type), +- m_busType(busType), +- m_strLocation(strLocation), +- m_strDeviceName(strDeviceName), ++CPeripheral::CPeripheral(const PeripheralScanResult& scanResult) : ++ m_type(scanResult.m_mappedType), ++ m_busType(scanResult.m_busType), ++ m_mappedBusType(scanResult.m_mappedBusType), ++ m_strLocation(scanResult.m_strLocation), ++ m_strDeviceName(scanResult.m_strDeviceName), + m_strFileLocation(StringUtils::EmptyString), +- m_iVendorId(iVendorId), +- m_iProductId(iProductId), +- m_strVersionInfo(g_localizeStrings.Get(13205)), // "unknown" +- m_bInitialised(false), +- m_bHidden(false), +- m_bError(false) +-{ +- PeripheralTypeTranslator::FormatHexString(iVendorId, m_strVendorId); +- PeripheralTypeTranslator::FormatHexString(iProductId, m_strProductId); +- m_strFileLocation.Format("peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(busType), strLocation.c_str()); +-} +- +-CPeripheral::CPeripheral(void) : +- m_type(PERIPHERAL_UNKNOWN), +- m_busType(PERIPHERAL_BUS_UNKNOWN), +- m_strLocation(StringUtils::EmptyString), +- m_strDeviceName(StringUtils::EmptyString), +- m_strFileLocation(StringUtils::EmptyString), +- m_iVendorId(0), +- m_strVendorId("0000"), +- m_iProductId(0), +- m_strProductId("0000"), ++ m_iVendorId(scanResult.m_iVendorId), ++ m_iProductId(scanResult.m_iProductId), + m_strVersionInfo(g_localizeStrings.Get(13205)), // "unknown" + m_bInitialised(false), + m_bHidden(false), + m_bError(false) + { ++ PeripheralTypeTranslator::FormatHexString(scanResult.m_iVendorId, m_strVendorId); ++ PeripheralTypeTranslator::FormatHexString(scanResult.m_iProductId, m_strProductId); ++ m_strFileLocation.Format(scanResult.m_iSequence > 0 ? "peripherals://%s/%s_%d.dev" : "peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(scanResult.m_busType), scanResult.m_strLocation.c_str(), scanResult.m_iSequence); + } + + CPeripheral::~CPeripheral(void) +@@ -146,7 +130,7 @@ bool CPeripheral::Initialise(void) + return bReturn; + + g_peripherals.GetSettingsFromMapping(*this); +- m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_busType), m_strVendorId.c_str(), m_strProductId.c_str()); ++ m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_mappedBusType), m_strVendorId.c_str(), m_strProductId.c_str()); + LoadPersistedSettings(); + + for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++) +@@ -535,3 +519,13 @@ void CPeripheral::ClearSettings(void) + } + m_settings.clear(); + } ++ ++bool CPeripheral::operator ==(const PeripheralScanResult& right) const ++{ ++ return m_strLocation.Equals(right.m_strLocation); ++} ++ ++bool CPeripheral::operator !=(const PeripheralScanResult& right) const ++{ ++ return !(*this == right); ++} +diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h +index d42e83e..64cf64e 100644 +--- a/xbmc/peripherals/devices/Peripheral.h ++++ b/xbmc/peripherals/devices/Peripheral.h +@@ -34,12 +34,13 @@ + friend class CGUIDialogPeripheralSettings; + + public: +- CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); +- CPeripheral(void); ++ CPeripheral(const PeripheralScanResult& scanResult); + virtual ~CPeripheral(void); + + bool operator ==(const CPeripheral &right) const; + bool operator !=(const CPeripheral &right) const; ++ bool operator ==(const PeripheralScanResult& right) const; ++ bool operator !=(const PeripheralScanResult& right) const; + + const CStdString &FileLocation(void) const { return m_strFileLocation; } + const CStdString &Location(void) const { return m_strLocation; } +@@ -158,6 +159,7 @@ + + PeripheralType m_type; + PeripheralBusType m_busType; ++ PeripheralBusType m_mappedBusType; + CStdString m_strLocation; + CStdString m_strDeviceName; + CStdString m_strSettingsFile; +diff --git a/xbmc/peripherals/devices/PeripheralBluetooth.cpp b/xbmc/peripherals/devices/PeripheralBluetooth.cpp +index a2f4e06..4785f7b 100644 +--- a/xbmc/peripherals/devices/PeripheralBluetooth.cpp ++++ b/xbmc/peripherals/devices/PeripheralBluetooth.cpp +@@ -23,8 +23,8 @@ + + using namespace PERIPHERALS; + +-CPeripheralBluetooth::CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) ++CPeripheralBluetooth::CPeripheralBluetooth(const PeripheralScanResult& scanResult) : ++ CPeripheral(scanResult) + { + m_features.push_back(FEATURE_BLUETOOTH); + } +diff --git a/xbmc/peripherals/devices/PeripheralBluetooth.h b/xbmc/peripherals/devices/PeripheralBluetooth.h +index 6b79be9..a1be1ff 100644 +--- a/xbmc/peripherals/devices/PeripheralBluetooth.h ++++ b/xbmc/peripherals/devices/PeripheralBluetooth.h +@@ -26,7 +26,7 @@ + class CPeripheralBluetooth : public CPeripheral + { + public: +- CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralBluetooth(const PeripheralScanResult& scanResult); + virtual ~CPeripheralBluetooth(void) {}; + }; + } +diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +index e578dc3..983e1a7 100644 +--- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp ++++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +@@ -80,14 +80,15 @@ class DllLibCEC : public DllDynamic, DllLibCECInterface + END_METHOD_RESOLVE() + }; + +-CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheralHID(type, busType, strLocation, strDeviceName, iVendorId, iProductId), ++CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralScanResult& scanResult) : ++ CPeripheralHID(scanResult), + CThread("CEC Adapter"), + m_dll(NULL), + m_cecAdapter(NULL) + { + ResetMembers(); + m_features.push_back(FEATURE_CEC); ++ m_strComPort = scanResult.m_strLocation; + } + + CPeripheralCecAdapter::~CPeripheralCecAdapter(void) +@@ -98,6 +99,7 @@ class DllLibCEC : public DllDynamic, DllLibCECInterface + m_bStop = true; + } + ++ SAFE_DELETE(m_queryThread); + StopThread(true); + + if (m_dll && m_cecAdapter) +@@ -302,38 +304,6 @@ void CPeripheralCecAdapter::SetVersionInfo(const libcec_configuration &configura + } + } + +-CStdString CPeripheralCecAdapter::GetComPort(void) +-{ +- CStdString strPort = GetSettingString("port"); +- if (strPort.IsEmpty()) +- { +- strPort = m_strFileLocation; +- cec_adapter deviceList[10]; +- TranslateComPort(strPort); +- uint8_t iFound = m_cecAdapter->FindAdapters(deviceList, 10, strPort.c_str()); +- +- if (iFound <= 0) +- { +- CLog::Log(LOGWARNING, "%s - no CEC adapters found on %s", __FUNCTION__, strPort.c_str()); +- // display warning: couldn't set up com port +- CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36011)); +- strPort = ""; +- } +- else +- { +- cec_adapter *dev = &deviceList[0]; +- if (iFound > 1) +- CLog::Log(LOGDEBUG, "%s - multiple com ports found for device. taking the first one", __FUNCTION__); +- else +- CLog::Log(LOGDEBUG, "%s - autodetect com port '%s'", __FUNCTION__, dev->comm); +- +- strPort = dev->comm; +- } +- } +- +- return strPort; +-} +- + bool CPeripheralCecAdapter::OpenConnection(void) + { + bool bIsOpen(false); +@@ -345,12 +315,8 @@ bool CPeripheralCecAdapter::OpenConnection(void) + return bIsOpen; + } + +- CStdString strPort = GetComPort(); +- if (strPort.empty()) +- return bIsOpen; +- + // open the CEC adapter +- CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, strPort.c_str()); ++ CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, m_strComPort.c_str()); + + // scanning the CEC bus takes about 5 seconds, so display a notification to inform users that we're busy + CStdString strMessage; +@@ -361,7 +327,7 @@ bool CPeripheralCecAdapter::OpenConnection(void) + + while (!m_bStop && !bIsOpen) + { +- if ((bIsOpen = m_cecAdapter->Open(strPort.c_str(), 10000)) == false) ++ if ((bIsOpen = m_cecAdapter->Open(m_strComPort.c_str(), 10000)) == false) + { + // display warning: couldn't initialise libCEC + CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__); +@@ -430,8 +396,7 @@ void CPeripheralCecAdapter::Process(void) + Sleep(5); + } + +- delete m_queryThread; +- m_queryThread = NULL; ++ SAFE_DELETE(m_queryThread); + + bool bSendStandbyCommands(false); + { +@@ -1255,8 +1220,7 @@ int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message me + + bool CPeripheralCecAdapter::TranslateComPort(CStdString &strLocation) + { +- if ((strLocation.Left(18).Equals("peripherals://usb/") || +- strLocation.Left(18).Equals("peripherals://rpi/")) && ++ if ((strLocation.Left(18).Equals("peripherals://cec/")) && + strLocation.Right(4).Equals(".dev")) + { + strLocation = strLocation.Right(strLocation.length() - 18); +diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h +index 23cd99e..c681e60 100644 +--- a/xbmc/peripherals/devices/PeripheralCecAdapter.h ++++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h +@@ -86,7 +86,7 @@ + friend class CPeripheralCecAdapterUpdateThread; + + public: +- CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralCecAdapter(const PeripheralScanResult& scanResult); + virtual ~CPeripheralCecAdapter(void); + + void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); +@@ -106,7 +106,6 @@ + int GetButton(void); + unsigned int GetHoldTime(void); + void ResetButton(void); +- CStdString GetComPort(void); + + void PushCecKeypress(const CEC::cec_keypress &key); + +@@ -171,6 +170,7 @@ + bool m_bActiveSourceBeforeStandby; + bool m_bOnPlayReceived; + bool m_bPlaybackPaused; ++ CStdString m_strComPort; + }; + + class CPeripheralCecAdapterUpdateThread : public CThread +diff --git a/xbmc/peripherals/devices/PeripheralDisk.cpp b/xbmc/peripherals/devices/PeripheralDisk.cpp +index 96d7fcf..b5507fc 100644 +--- a/xbmc/peripherals/devices/PeripheralDisk.cpp ++++ b/xbmc/peripherals/devices/PeripheralDisk.cpp +@@ -23,8 +23,9 @@ + + using namespace PERIPHERALS; + +-CPeripheralDisk::CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35003) : strDeviceName, iVendorId, iProductId) ++CPeripheralDisk::CPeripheralDisk(const PeripheralScanResult& scanResult) : ++ CPeripheral(scanResult) + { ++ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35003) : scanResult.m_strDeviceName; + m_features.push_back(FEATURE_DISK); + } +diff --git a/xbmc/peripherals/devices/PeripheralDisk.h b/xbmc/peripherals/devices/PeripheralDisk.h +index 4fab920..fc44ff6 100644 +--- a/xbmc/peripherals/devices/PeripheralDisk.h ++++ b/xbmc/peripherals/devices/PeripheralDisk.h +@@ -26,7 +26,7 @@ + class CPeripheralDisk : public CPeripheral + { + public: +- CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralDisk(const PeripheralScanResult& scanResult); + virtual ~CPeripheralDisk(void) {}; + }; + } +diff --git a/xbmc/peripherals/devices/PeripheralHID.cpp b/xbmc/peripherals/devices/PeripheralHID.cpp +index fe1f355..27152f1 100644 +--- a/xbmc/peripherals/devices/PeripheralHID.cpp ++++ b/xbmc/peripherals/devices/PeripheralHID.cpp +@@ -27,10 +27,11 @@ + using namespace PERIPHERALS; + using namespace std; + +-CPeripheralHID::CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId), ++CPeripheralHID::CPeripheralHID(const PeripheralScanResult& scanResult) : ++ CPeripheral(scanResult), + m_bInitialised(false) + { ++ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : scanResult.m_strDeviceName; + m_features.push_back(FEATURE_HID); + } + +diff --git a/xbmc/peripherals/devices/PeripheralHID.h b/xbmc/peripherals/devices/PeripheralHID.h +index ac60dcf..fb8bf44 100644 +--- a/xbmc/peripherals/devices/PeripheralHID.h ++++ b/xbmc/peripherals/devices/PeripheralHID.h +@@ -27,7 +27,7 @@ + class CPeripheralHID : public CPeripheral + { + public: +- CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralHID(const PeripheralScanResult& scanResult); + virtual ~CPeripheralHID(void); + virtual bool InitialiseFeature(const PeripheralFeature feature); + virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode) { return false; } +diff --git a/xbmc/peripherals/devices/PeripheralImon.cpp b/xbmc/peripherals/devices/PeripheralImon.cpp +index 6fbbb33..b0474a1 100644 +--- a/xbmc/peripherals/devices/PeripheralImon.cpp ++++ b/xbmc/peripherals/devices/PeripheralImon.cpp +@@ -37,8 +37,8 @@ + volatile long CPeripheralImon::m_lCountOfImonsConflictWithDInput = 0; + + +-CPeripheralImon::CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheralHID(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId) ++CPeripheralImon::CPeripheralImon(const PeripheralScanResult& scanResult) : ++ CPeripheralHID(scanResult) + { + m_features.push_back(FEATURE_IMON); + m_bImonConflictsWithDInput = false; +diff --git a/xbmc/peripherals/devices/PeripheralImon.h b/xbmc/peripherals/devices/PeripheralImon.h +index 8444906..87905b4 100644 +--- a/xbmc/peripherals/devices/PeripheralImon.h ++++ b/xbmc/peripherals/devices/PeripheralImon.h +@@ -26,7 +26,7 @@ + class CPeripheralImon : public CPeripheralHID + { + public: +- CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralImon(const PeripheralScanResult& scanResult); + virtual ~CPeripheralImon(void) {} + virtual bool InitialiseFeature(const PeripheralFeature feature); + virtual void OnSettingChanged(const CStdString &strChangedSetting); +diff --git a/xbmc/peripherals/devices/PeripheralNIC.cpp b/xbmc/peripherals/devices/PeripheralNIC.cpp +index 747c2f7..ee950e8 100644 +--- a/xbmc/peripherals/devices/PeripheralNIC.cpp ++++ b/xbmc/peripherals/devices/PeripheralNIC.cpp +@@ -25,8 +25,9 @@ + using namespace PERIPHERALS; + using namespace std; + +-CPeripheralNIC::CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35002) : strDeviceName, iVendorId, iProductId) ++CPeripheralNIC::CPeripheralNIC(const PeripheralScanResult& scanResult) : ++ CPeripheral(scanResult) + { ++ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35002) : scanResult.m_strDeviceName; + m_features.push_back(FEATURE_NIC); + } +diff --git a/xbmc/peripherals/devices/PeripheralNIC.h b/xbmc/peripherals/devices/PeripheralNIC.h +index 49abc2b..fc12302 100644 +--- a/xbmc/peripherals/devices/PeripheralNIC.h ++++ b/xbmc/peripherals/devices/PeripheralNIC.h +@@ -26,7 +26,7 @@ + class CPeripheralNIC : public CPeripheral + { + public: +- CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralNIC(const PeripheralScanResult& scanResult); + virtual ~CPeripheralNIC(void) {}; + }; + } +diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.cpp b/xbmc/peripherals/devices/PeripheralNyxboard.cpp +index 5e3f649..df9c290 100644 +--- a/xbmc/peripherals/devices/PeripheralNyxboard.cpp ++++ b/xbmc/peripherals/devices/PeripheralNyxboard.cpp +@@ -27,8 +27,8 @@ + using namespace PERIPHERALS; + using namespace std; + +-CPeripheralNyxboard::CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheralHID(type, busType, strLocation, strDeviceName, iVendorId, iProductId) ++CPeripheralNyxboard::CPeripheralNyxboard(const PeripheralScanResult& scanResult) : ++ CPeripheralHID(scanResult) + { + m_features.push_back(FEATURE_NYXBOARD); + } +diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.h b/xbmc/peripherals/devices/PeripheralNyxboard.h +index 346d555..254c6c6 100644 +--- a/xbmc/peripherals/devices/PeripheralNyxboard.h ++++ b/xbmc/peripherals/devices/PeripheralNyxboard.h +@@ -26,7 +26,7 @@ + class CPeripheralNyxboard : public CPeripheralHID + { + public: +- CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralNyxboard(const PeripheralScanResult& scanResult); + virtual ~CPeripheralNyxboard(void) {}; + virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode); + }; +diff --git a/xbmc/peripherals/devices/PeripheralTuner.cpp b/xbmc/peripherals/devices/PeripheralTuner.cpp +index ef5630c..8937598 100644 +--- a/xbmc/peripherals/devices/PeripheralTuner.cpp ++++ b/xbmc/peripherals/devices/PeripheralTuner.cpp +@@ -23,8 +23,8 @@ + + using namespace PERIPHERALS; + +-CPeripheralTuner::CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : +- CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) ++CPeripheralTuner::CPeripheralTuner(const PeripheralScanResult& scanResult) : ++ CPeripheral(scanResult) + { + m_features.push_back(FEATURE_TUNER); + } +diff --git a/xbmc/peripherals/devices/PeripheralTuner.h b/xbmc/peripherals/devices/PeripheralTuner.h +index b4b15f8..7130130 100644 +--- a/xbmc/peripherals/devices/PeripheralTuner.h ++++ b/xbmc/peripherals/devices/PeripheralTuner.h +@@ -26,7 +26,7 @@ + class CPeripheralTuner : public CPeripheral + { + public: +- CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); ++ CPeripheralTuner(const PeripheralScanResult& scanResult); + virtual ~CPeripheralTuner(void) {}; + }; + } +-- +1.7.10 + From 69258d33bfc7004aa9a76a8c7bafc89f06ccb1ba Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Sun, 10 Mar 2013 23:12:36 +0200 Subject: [PATCH 09/14] iperf: move to debug tools --- .../networking/testing/iperf/changelog.txt | 5 ---- .../networking/testing/iperf/icon/icon.png | Bin 2360 -> 0 bytes .../testing/iperf/source/default.py | 23 ------------------ .../networking/testing => debug}/iperf/build | 0 .../iperf/addon => debug/iperf/install} | 4 +-- .../networking/testing => debug}/iperf/meta | 5 ++-- packages/debug/meta | 2 +- 7 files changed, 5 insertions(+), 34 deletions(-) delete mode 100644 packages/addons/networking/testing/iperf/changelog.txt delete mode 100644 packages/addons/networking/testing/iperf/icon/icon.png delete mode 100644 packages/addons/networking/testing/iperf/source/default.py rename packages/{addons/networking/testing => debug}/iperf/build (100%) rename packages/{addons/networking/testing/iperf/addon => debug/iperf/install} (91%) rename packages/{addons/networking/testing => debug}/iperf/meta (95%) diff --git a/packages/addons/networking/testing/iperf/changelog.txt b/packages/addons/networking/testing/iperf/changelog.txt deleted file mode 100644 index 353ab309e7..0000000000 --- a/packages/addons/networking/testing/iperf/changelog.txt +++ /dev/null @@ -1,5 +0,0 @@ -3.0.1 -- bump addon version - -2.1.1 -- initial addon based on iperf-2.0.5 diff --git a/packages/addons/networking/testing/iperf/icon/icon.png b/packages/addons/networking/testing/iperf/icon/icon.png deleted file mode 100644 index 9f8063f8858e71cd245625a9067be902588d51cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2360 zcmeHH{WsHl9RGZ6v#dPatcaslN+S6Vj9*{LW> zrCj78?hp5e-sil|>vdk|ykF;iUO&7K(}KvRC>s<2 zz?2f;w-o@$AR#adW*|;wXt06cdwc?Y0H{7O`&%Re02rWc4)!tS+}z5_%GTD_ z&d$!>-rmvC(Z$6DkH@>ayL)AFTX6EGN6crVTM53~?vhwosii(Pwnwt9h`i6#v z#>U2`rlyvb7O`0T@ZrN}&z`+{^=e>XKq8UIWU|4*LAhM6P$-m2<>=_BN~Ibb8&j** z6B83Uoo;%1TCdj|j{h~k8u*z8#O~=j!@fyk!1g2nX3zZr==qz2-wY;_PYLu#N{wNr z&Q_wKNDqVM!}ky6leqEm>;yg_@z{}k_HImSEI$Sl9K*(tDSB9fDK2+QG`GH=t z0Fjold0U8l5fdSxW}$oC{$UIC+nY~+`TeU#-|9VrRlIkypGQLquW_zrs17>KY5Ooe zG|V9gmr|y)owD-4$+A>yZFL9AT01tvW_SGoE$uo(x;;GqQSROSE0^G4psSe5NP8hM~UB!jDf^>_8~ zEv6+e|LHV@%cXxp$M$EjTmmHkk!cuI%zMk*6-xuKHv$ zl6k>ceIfjH&yl`+`HMeG$2(gsC(((lB^%NhZ%D~vkg&Gri2Un`b_-#*i)DzycXuf; z&iASvB8zha;z6ozaaH`&zqh#Sps1bCbD=4nB1U@VV%cy!QIPHR=G;5e+c&xP6|Ic) zwzIBfS5Nae$HkcQsa<>Vz0e38*N%4omP~-k2AvdL0Wi0NchTQCk;v2h%3#9kA>gRJG0c; zE2^wdLD=3?V#f+L{jC^Xz;v@s|5}y%513R8)pkZuce(91QlvnBihHEpDWfexa1hmo!7me;QB|flP zW^e9Wr-rW}pG`z#VFgU7+rrbAiMB$XedSDf_7(EGl+Y5MLwz3os&J^gxT9bF!MH?R z$LS_ Date: Mon, 11 Mar 2013 00:29:37 +0100 Subject: [PATCH 10/14] slang: only build libslang, this fixes some crosscompiling issues with building the unneeded 'slsh' tool. thanks to 'unforgiven512' Signed-off-by: Stephan Raue --- packages/devel/slang/build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devel/slang/build b/packages/devel/slang/build index f79f129022..c2844e153d 100755 --- a/packages/devel/slang/build +++ b/packages/devel/slang/build @@ -38,5 +38,5 @@ cd $PKG_BUILD --without-z \ --without-x \ -make -$MAKEINSTALL +make -C src +$MAKEINSTALL -C src From f94e159ff50f219f852c3a4d48911723f7203e74 Mon Sep 17 00:00:00 2001 From: Gerad Munsch Date: Mon, 11 Mar 2013 00:05:28 -0400 Subject: [PATCH 11/14] Fix the build: PR2387 attempted to patch some files that do not exist in the OpenELEC XBMC tarballs. The lines were removed from the patch. --- .../mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch b/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch index 2e85748d70..7a0301aaee 100644 --- a/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch +++ b/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch @@ -6,9 +6,6 @@ Subject: [PATCH] [cec] rebased PR1794 + fixes for Frodo --- XBMC.xcodeproj/project.pbxproj | 13 +++ configure.in | 40 +------ - project/BuildDependencies/scripts/libcec_d.txt | 2 +- - project/VS2010Express/XBMC.vcxproj | 2 + - project/VS2010Express/XBMC.vcxproj.filters | 6 + system/peripherals.xml | 31 ++---- tools/android/depends/libcec/Makefile | 4 +- tools/darwin/depends/libcec/Makefile | 2 +- @@ -134,12 +131,6 @@ index 4769315..4472e3e 100644 AC_SUBST(USE_MYSQL) AC_SUBST(USE_WEB_SERVER) AC_SUBST(USE_UPNP) -diff --git a/project/BuildDependencies/scripts/libcec_d.txt b/project/BuildDependencies/scripts/libcec_d.txt -index c1419b5..2c7d495 100644 -diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj -index fb0947e..7e32ccc 100644 -diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters -index 53a6c97..52a5373 100644 diff --git a/system/peripherals.xml b/system/peripherals.xml index 967b96c..68205df 100644 --- a/system/peripherals.xml From 07b8b99b94c858c1e7222e4e1f4f51ae2ed6847a Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Mon, 11 Mar 2013 14:08:22 +0100 Subject: [PATCH 12/14] xbmc: add PR2252 Signed-off-by: Stephan Raue --- .../xbmc/patches/xbmc-990.30-PR2252.patch | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch b/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch new file mode 100644 index 0000000000..b757a9fb23 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch @@ -0,0 +1,51 @@ +From 80a8ad68567f89b3f6810c07daaf42d2edddee87 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 18 Feb 2013 23:49:43 +0000 +Subject: [PATCH] [rbp] Fix for audiotoggledigital on Pi. + +Pi only has two audio output modes so the three way toggle gets stuck. This fix corresponds to Pi specific settings code: +https://github.com/xbmc/xbmc/blob/master/xbmc/settings/GUISettings.cpp#L458 +--- + xbmc/Application.cpp | 12 ++++++++---- + xbmc/settings/GUISettings.h | 1 + + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index d6e663b..5e9d979 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -2863,11 +2863,15 @@ bool CApplication::OnAction(const CAction &action) + + if (action.GetID() == ACTION_TOGGLE_DIGITAL_ANALOG) + { +- switch(g_guiSettings.GetInt("audiooutput.mode")) ++ // we are only allowed to SetInt to a value supported in GUISettings, so we keep trying until it sticks ++ int mode = g_guiSettings.GetInt("audiooutput.mode"); ++ for (int i = 0; i < AUDIO_COUNT; i++) + { +- case AUDIO_ANALOG: g_guiSettings.SetInt("audiooutput.mode", AUDIO_IEC958); break; +- case AUDIO_IEC958: g_guiSettings.SetInt("audiooutput.mode", AUDIO_HDMI ); break; +- case AUDIO_HDMI : g_guiSettings.SetInt("audiooutput.mode", AUDIO_ANALOG); break; ++ if (++mode == AUDIO_COUNT) ++ mode = 0; ++ g_guiSettings.SetInt("audiooutput.mode", mode); ++ if (g_guiSettings.GetInt("audiooutput.mode") == mode) ++ break; + } + + g_application.Restart(); +diff --git a/xbmc/settings/GUISettings.h b/xbmc/settings/GUISettings.h +index b48ba35..98f9836 100644 +--- a/xbmc/settings/GUISettings.h ++++ b/xbmc/settings/GUISettings.h +@@ -84,6 +84,7 @@ + #define AUDIO_ANALOG 0 + #define AUDIO_IEC958 1 + #define AUDIO_HDMI 2 ++#define AUDIO_COUNT 3 + #define AUDIO_IS_BITSTREAM(x) ((x) == AUDIO_IEC958 || (x) == AUDIO_HDMI) + + #define VIDEO_NORMAL 0 +-- +1.7.10 + From 74283a83e647677e54418c5cee9d22d5d4cddf22 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Mon, 11 Mar 2013 14:09:34 +0100 Subject: [PATCH 13/14] xbmc: remove broken PRs Signed-off-by: Stephan Raue --- .../xbmc/patches/xbmc-990.17-PR2320.patch | 144 ------------------ .../xbmc/patches/xbmc-990.19-PR2382.patch | 46 ------ 2 files changed, 190 deletions(-) delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.17-PR2320.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.19-PR2382.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.17-PR2320.patch b/packages/mediacenter/xbmc/patches/xbmc-990.17-PR2320.patch deleted file mode 100644 index c800347443..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.17-PR2320.patch +++ /dev/null @@ -1,144 +0,0 @@ -From f2faaa846e03cbcc1ba11f09baad690c792035c5 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Thu, 28 Feb 2013 00:17:03 +0100 -Subject: [PATCH] AE: Revisit Device Opening. Try to set periodSize of 100 ms - and BufferSize of 800 ms - ---- - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 98 ++++++++++++++++----------- - 1 file changed, 59 insertions(+), 39 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index fe40d17..821bd2e 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -38,7 +38,6 @@ - #endif - - #define ALSA_OPTIONS (SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_FORMAT | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_RESAMPLE) --#define ALSA_PERIODS 16 - - #define ALSA_MAX_CHANNELS 16 - static enum AEChannel ALSAChannelMap[ALSA_MAX_CHANNELS + 1] = { -@@ -328,59 +327,80 @@ bool CAESinkALSA::InitializeHW(AEAudioFormat &format) - } - } - -- unsigned int periods; -- - snd_pcm_uframes_t periodSize, bufferSize; - snd_pcm_hw_params_get_buffer_size_max(hw_params, &bufferSize); -+ snd_pcm_hw_params_get_period_size_max(hw_params, &periodSize, NULL); -+ -+ /* -+ We want to make sure, that we have approx 500 to 800 ms Buffer with -+ a periodSize of approx 100 ms. -+ It is calced: -+ periodSize = sampleRate / 10 -+ buffersize = periodSize * 1 frame * 8. -+ */ -+ periodSize = std::min(periodSize, (snd_pcm_uframes_t) sampleRate / 10); -+ bufferSize = std::min(bufferSize, (snd_pcm_uframes_t) periodSize * 8); -+ -+ /* -+ According to upstream we should set buffer size first - so make sure it is always at least -+ double of period size to not get underruns -+ */ -+ periodSize = std::min(periodSize, bufferSize / 2); - -- bufferSize = std::min(bufferSize, (snd_pcm_uframes_t)8192); -- periodSize = bufferSize / ALSA_PERIODS; -- periods = ALSA_PERIODS; -- -- CLog::Log(LOGDEBUG, "CAESinkALSA::InitializeHW - Request: periodSize %lu, periods %u, bufferSize %lu", periodSize, periods, bufferSize); -+ CLog::Log(LOGDEBUG, "CAESinkALSA::InitializeHW - Request: periodSize %lu, bufferSize %lu", periodSize, bufferSize); - -- /* work on a copy of the hw params */ - snd_pcm_hw_params_t *hw_params_copy; - snd_pcm_hw_params_alloca(&hw_params_copy); -- -- /* try to set the buffer size then the period size */ -- snd_pcm_hw_params_copy(hw_params_copy, hw_params); -- snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize); -- snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL); -- snd_pcm_hw_params_set_periods_near (m_pcm, hw_params_copy, &periods , NULL); -- if (snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) -+ snd_pcm_hw_params_copy(hw_params_copy, hw_params); // copy what we have and is already working -+ -+ // first trying bufferSize, PeriodSize -+ // for more info see here: -+ // http://mailman.alsa-project.org/pipermail/alsa-devel/2009-September/021069.html -+ // the last three tries are done as within pulseaudio -+ -+ // backup periodSize and bufferSize first. Restore them after every failed try -+ snd_pcm_uframes_t periodSizeTemp, bufferSizeTemp; -+ periodSizeTemp = periodSize; -+ bufferSizeTemp = bufferSize; -+ if (snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize) != 0 -+ || snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL) != 0 -+ || snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) - { -- /* try to set the period size then the buffer size */ -- snd_pcm_hw_params_copy(hw_params_copy, hw_params); -- snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL); -- snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize); -- snd_pcm_hw_params_set_periods_near (m_pcm, hw_params_copy, &periods , NULL); -- if (snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) -+ bufferSize = bufferSizeTemp; -+ periodSize = periodSizeTemp; -+ // retry with PeriodSize, bufferSize -+ snd_pcm_hw_params_copy(hw_params_copy, hw_params); // restore working copy -+ if (snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL) != 0 -+ || snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize) != 0 -+ || snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) - { -- /* try to just set the buffer size */ -- snd_pcm_hw_params_copy(hw_params_copy, hw_params); -- snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize); -- snd_pcm_hw_params_set_periods_near (m_pcm, hw_params_copy, &periods , NULL); -- if (snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) -+ // try only periodSize -+ periodSize = periodSizeTemp; -+ snd_pcm_hw_params_copy(hw_params_copy, hw_params); // restore working copy -+ if(snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL) != 0 -+ || snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) - { -- /* try to just set the period size */ -- snd_pcm_hw_params_copy(hw_params_copy, hw_params); -- snd_pcm_hw_params_set_period_size_near(m_pcm, hw_params_copy, &periodSize, NULL); -- snd_pcm_hw_params_set_periods_near (m_pcm, hw_params_copy, &periods , NULL); -- if (snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) -+ // try only BufferSize -+ bufferSize = bufferSizeTemp; -+ snd_pcm_hw_params_copy(hw_params_copy, hw_params); // restory working copy -+ if (snd_pcm_hw_params_set_buffer_size_near(m_pcm, hw_params_copy, &bufferSize) != 0 -+ || snd_pcm_hw_params(m_pcm, hw_params_copy) != 0) - { -- CLog::Log(LOGERROR, "CAESinkALSA::InitializeHW - Failed to set the parameters"); -- return false; -+ // set default that Alsa would choose -+ CLog::Log(LOGWARNING, "CAESinkAlsa::IntializeHW - Using default alsa values - set failed"); -+ if (snd_pcm_hw_params(m_pcm, hw_params) != 0) -+ { -+ CLog::Log(LOGDEBUG, "CAESinkALSA::InitializeHW - Could not init a valid sink"); -+ return false; -+ } - } - } -+ // reread values when alsa default was kept -+ snd_pcm_get_params(m_pcm, &bufferSize, &periodSize); - } - } -- -- snd_pcm_hw_params_get_period_size(hw_params_copy, &periodSize, NULL); -- snd_pcm_hw_params_get_buffer_size(hw_params_copy, &bufferSize); - -- -- CLog::Log(LOGDEBUG, "CAESinkALSA::InitializeHW - Got: periodSize %lu, periods %u, bufferSize %lu", periodSize, periods, bufferSize); -+ CLog::Log(LOGDEBUG, "CAESinkALSA::InitializeHW - Got: periodSize %lu, bufferSize %lu", periodSize, bufferSize); - - /* set the format parameters */ - format.m_sampleRate = sampleRate; --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.19-PR2382.patch b/packages/mediacenter/xbmc/patches/xbmc-990.19-PR2382.patch deleted file mode 100644 index 988377325b..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.19-PR2382.patch +++ /dev/null @@ -1,46 +0,0 @@ -From eb4ae32119a83716d7fb930381d2848c02383cea Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Wed, 6 Mar 2013 07:52:59 +0100 -Subject: [PATCH] AE: Fix menu sounds by decreasing buffer(max 200 ms) and - periodSize(50 ms) - ---- - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 19 ++++++++++--------- - 1 file changed, 10 insertions(+), 9 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index 821bd2e..21891a5 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -332,18 +332,19 @@ bool CAESinkALSA::InitializeHW(AEAudioFormat &format) - snd_pcm_hw_params_get_period_size_max(hw_params, &periodSize, NULL); - - /* -- We want to make sure, that we have approx 500 to 800 ms Buffer with -- a periodSize of approx 100 ms. -- It is calced: -- periodSize = sampleRate / 10 -- buffersize = periodSize * 1 frame * 8. -+ We want to make sure, that we have max 200 ms Buffer with -+ a periodSize of approx 50 ms. Choosing a higher bufferSize -+ will cause problems with menu sounds. Buffer will be increased -+ after those are fixed. -+ periodSize = sampleRate / 20 -+ bufferSize = periodSize * 1 frame * 4. - */ -- periodSize = std::min(periodSize, (snd_pcm_uframes_t) sampleRate / 10); -- bufferSize = std::min(bufferSize, (snd_pcm_uframes_t) periodSize * 8); -+ periodSize = std::min(periodSize, (snd_pcm_uframes_t) sampleRate / 20); -+ bufferSize = std::min(bufferSize, (snd_pcm_uframes_t) periodSize * 4); - - /* -- According to upstream we should set buffer size first - so make sure it is always at least -- double of period size to not get underruns -+ According to upstream we should set buffer size first - so make sure it is always at least -+ double of period size to not get underruns - */ - periodSize = std::min(periodSize, bufferSize / 2); - --- -1.7.10 - From 14f40f50fed720050d1ae0ab47b9bc841c67327f Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Mon, 11 Mar 2013 15:43:38 +0100 Subject: [PATCH 14/14] xbmc: update to xbmc-12.0.5 Signed-off-by: Stephan Raue --- .../mediacenter/xbmc-theme-Confluence/meta | 2 +- packages/mediacenter/xbmc/meta | 2 +- .../xbmc/patches/xbmc-990.18-PR2368.patch | 156 -- .../xbmc/patches/xbmc-990.20-PR2286.patch | 520 ------ .../xbmc/patches/xbmc-990.23-PR2363.patch | 202 --- .../xbmc/patches/xbmc-990.24-PR2375.patch | 31 - .../xbmc/patches/xbmc-990.27-PR2388.patch | 25 - .../xbmc/patches/xbmc-990.27-fix-build.patch | 34 + .../xbmc/patches/xbmc-990.28-PR2395.patch | 31 - .../xbmc/patches/xbmc-990.29-PR2387.patch | 1508 ----------------- .../xbmc/patches/xbmc-990.30-PR2252.patch | 51 - tools/mkpkg/mkpkg_xbmc-frodo | 2 +- 12 files changed, 37 insertions(+), 2527 deletions(-) delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.18-PR2368.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch create mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.27-fix-build.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch delete mode 100644 packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch diff --git a/packages/mediacenter/xbmc-theme-Confluence/meta b/packages/mediacenter/xbmc-theme-Confluence/meta index e9d4da29c1..8601e6b110 100644 --- a/packages/mediacenter/xbmc-theme-Confluence/meta +++ b/packages/mediacenter/xbmc-theme-Confluence/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc-theme-Confluence" -PKG_VERSION="12.0.4" +PKG_VERSION="12.0.5" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/meta b/packages/mediacenter/xbmc/meta index 9c0a4a8655..03ae526c9d 100644 --- a/packages/mediacenter/xbmc/meta +++ b/packages/mediacenter/xbmc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="12.0.4" +PKG_VERSION="12.0.5" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.18-PR2368.patch b/packages/mediacenter/xbmc/patches/xbmc-990.18-PR2368.patch deleted file mode 100644 index d9c9c1f634..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.18-PR2368.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 632825b71a2bc248eb5705666debc5f7653d6878 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sun, 24 Feb 2013 15:25:49 +0000 -Subject: [PATCH] [rbp] Fix for stuttery video when seeking before zero - -There are a few issues with seeking I found. -We weren't correctly setting OMX_BUFFERFLAG_TIME_UNKNOWN on the first frame after a seek which could make the GPU think video was at 0 and audio at a much larger offset. -A full video fifo (to GPU) stops any higher priority messages from being received which can stall a seek and the flush message doesn't get through. Use m_flush to discard the video packet that doesn't fit. -We get an audio frame through with unknown pts/dts after the flush, but before the GENERAL_RESYNC when seeking. This was given to GPU and was perhaps 30 seconds out from the following packets and that throws off the timing between audio and video streams. Keeping m_flush true until the GENERAL_RESYNC discards this frame. Hopefully that is safe. ---- - xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 13 ++----------- - xbmc/cores/omxplayer/OMXPlayerAudio.h | 1 - - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 7 +++++++ - xbmc/cores/omxplayer/OMXPlayerVideo.h | 1 + - xbmc/cores/omxplayer/OMXVideo.cpp | 11 +++-------- - 5 files changed, 13 insertions(+), 20 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -index 58c3a4f..16ea6c3 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -@@ -369,13 +369,9 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) - - while(!m_bStop) - { -+ // discard if flushing as clocks may be stopped and we'll never submit it - if(m_flush) -- { -- CSingleLock lock(m_flushLock); -- m_flush = false; -- lock.Leave(); - break; -- } - - if(m_omxAudio.GetSpace() < (unsigned int)pkt->iSize) - { -@@ -420,12 +416,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) - while(!m_bStop) - { - if(m_flush) -- { -- CSingleLock lock(m_flushLock); -- m_flush = false; -- lock.Leave(); - break; -- } - - if(m_omxAudio.GetSpace() < (unsigned int)pkt->iSize) - { -@@ -544,6 +535,7 @@ void OMXPlayerAudio::Process() - } - else - CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, 0)", m_audioClock); -+ m_flush = false; - } - else if (pMsg->IsType(CDVDMsg::GENERAL_RESET)) - { -@@ -627,7 +619,6 @@ void OMXPlayerAudio::Process() - - void OMXPlayerAudio::Flush() - { -- CSingleLock lock(m_flushLock); - m_flush = true; - m_messageQueue.Flush(); - m_messageQueue.Put( new CDVDMsg(CDVDMsg::GENERAL_FLUSH), 1); -diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.h b/xbmc/cores/omxplayer/OMXPlayerAudio.h -index d10133e..d6083e9 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerAudio.h -+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.h -@@ -42,7 +42,6 @@ - class OMXPlayerAudio : public CThread - { - protected: -- CCriticalSection m_flushLock; - CDVDMessageQueue m_messageQueue; - CDVDMessageQueue &m_messageParent; - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 5a6e31e..5dd908b 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -122,6 +122,7 @@ bool OMXPlayerVideo::OpenStream(CDVDStreamInfo &hints) - m_Deinterlace = ( g_settings.m_currentVideoSettings.m_DeinterlaceMode == VS_DEINTERLACEMODE_OFF ) ? false : true; - m_hdmi_clock_sync = (g_guiSettings.GetInt("videoplayer.adjustrefreshrate") != ADJUST_REFRESHRATE_OFF); - m_started = false; -+ m_flush = false; - m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; - m_autosync = 1; - m_iSleepEndTime = DVD_NOPTS_VALUE; -@@ -593,6 +594,7 @@ void OMXPlayerVideo::Process() - m_omxVideo.Reset(); - m_av_clock->OMXReset(false); - m_av_clock->UnLock(); -+ m_flush = false; - } - else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) - { -@@ -633,6 +635,10 @@ void OMXPlayerVideo::Process() - - while (!m_bStop) - { -+ // discard if flushing as clocks may be stopped and we'll never submit it -+ if (m_flush) -+ break; -+ - if((int)m_omxVideo.GetFreeSpace() < pPacket->iSize) - { - Sleep(10); -@@ -697,6 +703,7 @@ void OMXPlayerVideo::Process() - - void OMXPlayerVideo::Flush() - { -+ m_flush = true; - m_messageQueue.Flush(); - m_messageQueue.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH), 1); - } -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.h b/xbmc/cores/omxplayer/OMXPlayerVideo.h -index cf05c1f..7df1b0b 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.h -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.h -@@ -61,6 +61,7 @@ class OMXPlayerVideo : public CThread - int m_audio_count; - bool m_stalled; - bool m_started; -+ bool m_flush; - std::string m_codecname; - double m_droptime; - double m_dropbase; -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index 3417286..4f11ff8 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -809,17 +809,12 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) - // only send dts on first frame to get nearly correct starttime - if(pts == DVD_NOPTS_VALUE) - pts = dts; -- if(pts == DVD_NOPTS_VALUE) -- omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; -- omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME; -+ omx_buffer->nFlags |= OMX_BUFFERFLAG_STARTTIME; - CLog::Log(LOGDEBUG, "OMXVideo::Decode VDec : setStartTime %f\n", (pts == DVD_NOPTS_VALUE ? 0.0 : pts) / DVD_TIME_BASE); - m_av_clock->VideoStart(false); - } -- else -- { -- if(pts == DVD_NOPTS_VALUE) -- omx_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; -- } -+ if(pts == DVD_NOPTS_VALUE) -+ omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; - - omx_buffer->nTimeStamp = ToOMXTime((uint64_t)(pts == DVD_NOPTS_VALUE) ? 0 : pts); - omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes; --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch b/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch deleted file mode 100644 index 373c7963de..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch +++ /dev/null @@ -1,520 +0,0 @@ -From dac7871e3440b9d4235fcd91af1c2d41a931d69d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 Feb 2013 23:04:28 +0000 -Subject: [PATCH] [rbp] Handle resolution changes during video stream. - -When the resolution changes, GPU sends a port settings changed message. Host has to acknowledge it by disabling and enabling the affected ports. ---- - xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 229 ++++++++++++------------------- - xbmc/cores/omxplayer/OMXPlayerVideo.h | 7 +- - xbmc/cores/omxplayer/OMXVideo.cpp | 95 ++++++++----- - xbmc/cores/omxplayer/OMXVideo.h | 7 +- - 4 files changed, 151 insertions(+), 187 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -index 5a6e31e..a033c78 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -83,9 +83,6 @@ class COMXMsgVideoCodecChange : public CDVDMsg - m_iSubtitleDelay = 0; - m_FlipTimeStamp = 0.0; - m_bRenderSubs = false; -- m_width = 0; -- m_height = 0; -- m_fps = 0.0f; - m_flags = 0; - m_bAllowFullscreen = false; - m_iCurrentPts = DVD_NOPTS_VALUE; -@@ -98,12 +95,7 @@ class COMXMsgVideoCodecChange : public CDVDMsg - m_messageQueue.SetMaxDataSize(10 * 1024 * 1024); - m_messageQueue.SetMaxTimeSize(8.0); - -- RESOLUTION res = g_graphicsContext.GetVideoResolution(); -- m_video_width = g_settings.m_ResInfo[res].iScreenWidth; -- m_video_height = g_settings.m_ResInfo[res].iScreenHeight; -- - m_dst_rect.SetRect(0, 0, 0, 0); -- - } - - OMXPlayerVideo::~OMXPlayerVideo() -@@ -125,6 +117,8 @@ bool OMXPlayerVideo::OpenStream(CDVDStreamInfo &hints) - m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; - m_autosync = 1; - m_iSleepEndTime = DVD_NOPTS_VALUE; -+ // force SetVideoRect to be called initially -+ m_dst_rect.SetRect(0, 0, 0, 0); - - m_audio_count = m_av_clock->HasAudio(); - -@@ -220,154 +214,45 @@ void OMXPlayerVideo::ProcessOverlays(int iGroupId, double pts) - if (m_started) - m_pOverlayContainer->CleanUp(pts - m_iSubtitleDelay); - -- enum EOverlay -- { OVERLAY_AUTO // select mode auto -- , OVERLAY_GPU // render osd using gpu -- , OVERLAY_BUF // render osd on buffer -- } render = OVERLAY_AUTO; -- -- /* -- if(m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SPU) -- || m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_IMAGE) -- || m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SSA) ) -- render = OVERLAY_BUF; -- */ -- -- if(render == OVERLAY_BUF) -- { -- // rendering spu overlay types directly on video memory costs a lot of processing power. -- // thus we allocate a temp picture, copy the original to it (needed because the same picture can be used more than once). -- // then do all the rendering on that temp picture and finaly copy it to video memory. -- // In almost all cases this is 5 or more times faster!. -- -- if(m_pTempOverlayPicture && ( m_pTempOverlayPicture->iWidth != m_width -- || m_pTempOverlayPicture->iHeight != m_height)) -- { -- CDVDCodecUtils::FreePicture(m_pTempOverlayPicture); -- m_pTempOverlayPicture = NULL; -- } -- -- if(!m_pTempOverlayPicture) -- m_pTempOverlayPicture = CDVDCodecUtils::AllocatePicture(m_width, m_height); -- if(!m_pTempOverlayPicture) -- return; -- m_pTempOverlayPicture->format = RENDER_FMT_YUV420P; -- } -- -- if(render == OVERLAY_AUTO) -- render = OVERLAY_GPU; -- - VecOverlays overlays; - -- { -- CSingleLock lock(*m_pOverlayContainer); -+ CSingleLock lock(*m_pOverlayContainer); - -- VecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays(); -- VecOverlaysIter it = pVecOverlays->begin(); -- -- //Check all overlays and render those that should be rendered, based on time and forced -- //Both forced and subs should check timeing, pts == 0 in the stillframe case -- while (it != pVecOverlays->end()) -- { -- CDVDOverlay* pOverlay = *it++; -- if(!pOverlay->bForced && !m_bRenderSubs) -- continue; -- -- if(pOverlay->iGroupId != iGroupId) -- continue; -+ VecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays(); -+ VecOverlaysIter it = pVecOverlays->begin(); - -- double pts2 = pOverlay->bForced ? pts : pts - m_iSubtitleDelay; -+ //Check all overlays and render those that should be rendered, based on time and forced -+ //Both forced and subs should check timeing, pts == 0 in the stillframe case -+ while (it != pVecOverlays->end()) -+ { -+ CDVDOverlay* pOverlay = *it++; -+ if(!pOverlay->bForced && !m_bRenderSubs) -+ continue; - -- if((pOverlay->iPTSStartTime <= pts2 && (pOverlay->iPTSStopTime > pts2 || pOverlay->iPTSStopTime == 0LL)) || pts == 0) -- { -- if(pOverlay->IsOverlayType(DVDOVERLAY_TYPE_GROUP)) -- overlays.insert(overlays.end(), static_cast(pOverlay)->m_overlays.begin() -- , static_cast(pOverlay)->m_overlays.end()); -- else -- overlays.push_back(pOverlay); -+ if(pOverlay->iGroupId != iGroupId) -+ continue; - -- } -- } -+ double pts2 = pOverlay->bForced ? pts : pts - m_iSubtitleDelay; - -- for(it = overlays.begin(); it != overlays.end(); ++it) -+ if((pOverlay->iPTSStartTime <= pts2 && (pOverlay->iPTSStopTime > pts2 || pOverlay->iPTSStopTime == 0LL)) || pts == 0) - { -- double pts2 = (*it)->bForced ? pts : pts - m_iSubtitleDelay; -- -- if (render == OVERLAY_GPU) -- g_renderManager.AddOverlay(*it, pts2); -- -- /* -- printf("subtitle : DVDOVERLAY_TYPE_SPU %d DVDOVERLAY_TYPE_IMAGE %d DVDOVERLAY_TYPE_SSA %d\n", -- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SPU), -- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_IMAGE), -- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SSA) ); -- */ -- -- if (render == OVERLAY_BUF) -- CDVDOverlayRenderer::Render(m_pTempOverlayPicture, *it, pts2); -+ if(pOverlay->IsOverlayType(DVDOVERLAY_TYPE_GROUP)) -+ overlays.insert(overlays.end(), static_cast(pOverlay)->m_overlays.begin() -+ , static_cast(pOverlay)->m_overlays.end()); -+ else -+ overlays.push_back(pOverlay); - } - } --} -- --void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) --{ - -- if (!g_renderManager.IsConfigured() -- || m_video_width != m_width -- || m_video_height != m_height -- || m_fps != m_fFrameRate) -+ for(it = overlays.begin(); it != overlays.end(); ++it) - { -- m_width = m_video_width; -- m_height = m_video_height; -- m_fps = m_fFrameRate; -- -- unsigned flags = 0; -- ERenderFormat format = RENDER_FMT_BYPASS; -- -- if(m_bAllowFullscreen) -- { -- flags |= CONF_FLAGS_FULLSCREEN; -- m_bAllowFullscreen = false; // only allow on first configure -- } -- -- if(m_flags & CONF_FLAGS_FORMAT_SBS) -- { -- if(g_Windowing.Support3D(m_video_width, m_video_height, D3DPRESENTFLAG_MODE3DSBS)) -- { -- CLog::Log(LOGNOTICE, "3DSBS movie found"); -- flags |= CONF_FLAGS_FORMAT_SBS; -- } -- } -- else if(m_flags & CONF_FLAGS_FORMAT_TB) -- { -- if(g_Windowing.Support3D(m_video_width, m_video_height, D3DPRESENTFLAG_MODE3DTB)) -- { -- CLog::Log(LOGNOTICE, "3DTB movie found"); -- flags |= CONF_FLAGS_FORMAT_TB; -- } -- } -- -- unsigned int iDisplayWidth = m_hints.width; -- unsigned int iDisplayHeight = m_hints.height; -- -- /* use forced aspect if any */ -- if( m_fForcedAspectRatio != 0.0f ) -- iDisplayWidth = (int) (iDisplayHeight * m_fForcedAspectRatio); -- -- CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. %dx%x format: BYPASS", -- __FUNCTION__, m_width, m_height, m_fps, iDisplayWidth, iDisplayHeight); -- -- if(!g_renderManager.Configure(m_hints.width, m_hints.height, -- iDisplayWidth, iDisplayHeight, m_fps, flags, format, 0, -- m_hints.orientation)) -- { -- CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); -- return; -- } -- -- g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack); -+ double pts2 = (*it)->bForced ? pts : pts - m_iSubtitleDelay; -+ g_renderManager.AddOverlay(*it, pts2); - } -+} - -+void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) -+{ - if (!g_renderManager.IsStarted()) { - CLog::Log(LOGERROR, "%s - renderer not started", __FUNCTION__); - return; -@@ -724,6 +609,7 @@ bool OMXPlayerVideo::OpenDecoder() - m_av_clock->OMXStop(false); - - bool bVideoDecoderOpen = m_omxVideo.Open(m_hints, m_av_clock, m_Deinterlace, m_hdmi_clock_sync); -+ m_omxVideo.RegisterResolutionUpdateCallBack((void *)this, ResolutionUpdateCallBack); - - if(!bVideoDecoderOpen) - { -@@ -859,3 +745,62 @@ void OMXPlayerVideo::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, - player->SetVideoRect(SrcRect, DestRect); - } - -+void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height) -+{ -+ RESOLUTION res = g_graphicsContext.GetVideoResolution(); -+ uint32_t video_width = g_settings.m_ResInfo[res].iScreenWidth; -+ uint32_t video_height = g_settings.m_ResInfo[res].iScreenHeight; -+ -+ unsigned flags = 0; -+ ERenderFormat format = RENDER_FMT_BYPASS; -+ -+ if(m_bAllowFullscreen) -+ { -+ flags |= CONF_FLAGS_FULLSCREEN; -+ m_bAllowFullscreen = false; // only allow on first configure -+ } -+ -+ if(m_flags & CONF_FLAGS_FORMAT_SBS) -+ { -+ if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DSBS)) -+ { -+ CLog::Log(LOGNOTICE, "3DSBS movie found"); -+ flags |= CONF_FLAGS_FORMAT_SBS; -+ } -+ } -+ else if(m_flags & CONF_FLAGS_FORMAT_TB) -+ { -+ if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DTB)) -+ { -+ CLog::Log(LOGNOTICE, "3DTB movie found"); -+ flags |= CONF_FLAGS_FORMAT_TB; -+ } -+ } -+ -+ unsigned int iDisplayWidth = width; -+ unsigned int iDisplayHeight = height; -+ -+ /* use forced aspect if any */ -+ if( m_fForcedAspectRatio != 0.0f ) -+ iDisplayWidth = (int) (iDisplayHeight * m_fForcedAspectRatio); -+ -+ CLog::Log(LOGDEBUG,"%s - change configuration. video:%dx%d. framerate: %4.2f. %dx%d format: BYPASS", -+ __FUNCTION__, video_width, video_height, m_fFrameRate, iDisplayWidth, iDisplayHeight); -+ -+ if(!g_renderManager.Configure(width, height, -+ iDisplayWidth, iDisplayHeight, m_fFrameRate, flags, format, 0, -+ m_hints.orientation)) -+ { -+ CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); -+ return; -+ } -+ -+ g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack); -+} -+ -+void OMXPlayerVideo::ResolutionUpdateCallBack(void *ctx, uint32_t width, uint32_t height) -+{ -+ OMXPlayerVideo *player = static_cast(ctx); -+ player->ResolutionUpdateCallBack(width, height); -+} -+ -diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.h b/xbmc/cores/omxplayer/OMXPlayerVideo.h -index cf05c1f..95a691b 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.h -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.h -@@ -70,12 +70,7 @@ class OMXPlayerVideo : public CThread - bool m_bAllowFullscreen; - - float m_fForcedAspectRatio; -- unsigned int m_width; -- unsigned int m_height; -- unsigned int m_video_width; -- unsigned int m_video_height; - unsigned m_flags; -- float m_fps; - - CRect m_dst_rect; - int m_view_mode; -@@ -133,5 +128,7 @@ class OMXPlayerVideo : public CThread - int GetFreeSpace(); - void SetVideoRect(const CRect &SrcRect, const CRect &DestRect); - static void RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect); -+ void ResolutionUpdateCallBack(uint32_t width, uint32_t height); -+ static void ResolutionUpdateCallBack(void *ctx, uint32_t width, uint32_t height); - }; - #endif -diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp -index 3417286..b6b42e7 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXVideo.cpp -@@ -86,7 +86,6 @@ - m_video_codec_name = ""; - m_deinterlace = false; - m_hdmi_clock_sync = false; -- m_first_frame = true; - } - - COMXVideo::~COMXVideo() -@@ -154,6 +153,9 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b - OMX_ERRORTYPE omx_err = OMX_ErrorNone; - std::string decoder_name; - -+ m_res_ctx = NULL; -+ m_res_callback = NULL; -+ - m_video_codec_name = ""; - m_codingType = OMX_VIDEO_CodingUnused; - -@@ -697,7 +699,6 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b - CLASSNAME, __func__, m_omx_decoder.GetComponent(), m_omx_decoder.GetInputPort(), m_omx_decoder.GetOutputPort(), - m_deinterlace, m_hdmi_clock_sync); - -- m_first_frame = true; - // start from assuming all recent frames had valid pts - m_history_valid_pts = ~0; - -@@ -736,8 +737,10 @@ void COMXVideo::Close() - m_video_convert = false; - m_video_codec_name = ""; - m_deinterlace = false; -- m_first_frame = true; - m_av_clock = NULL; -+ -+ m_res_ctx = NULL; -+ m_res_callback = NULL; - } - - void COMXVideo::SetDropState(bool bDrop) -@@ -851,57 +854,74 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) - } - } - -- if(m_first_frame && m_deinterlace) -+ omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, 0); -+ if (omx_err == OMX_ErrorNone) - { - OMX_PARAM_PORTDEFINITIONTYPE port_image; - OMX_INIT_STRUCTURE(port_image); - port_image.nPortIndex = m_omx_decoder.GetOutputPort(); -- - omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_image); - if(omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 1 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ { -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ } -+ // let OMXPlayerVideo know about resolution so it can inform RenderManager -+ if (m_res_callback) -+ m_res_callback(m_res_ctx, port_image.format.video.nFrameWidth, port_image.format.video.nFrameHeight); -+ -+ m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true); -+ m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), true); - -- /* we assume when the sizes equal we have the first decoded frame */ -- if(port_image.format.video.nFrameWidth == m_decoded_width && port_image.format.video.nFrameHeight == m_decoded_height) -+ OMX_CONFIG_INTERLACETYPE interlace; -+ OMX_INIT_STRUCTURE(interlace); -+ interlace.nPortIndex = m_omx_decoder.GetOutputPort(); -+ omx_err = m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace, &interlace); -+ if(omx_err != OMX_ErrorNone) - { -- m_first_frame = false; -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ } - -- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); -- if(omx_err == OMX_ErrorStreamCorrupt) -+ if (m_deinterlace) -+ { -+ m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), true); -+ port_image.nPortIndex = m_omx_image_fx.GetInputPort(); -+ omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); -+ if(omx_err != OMX_ErrorNone) - { -- CLog::Log(LOGERROR, "%s::%s - image not unsupported\n", CLASSNAME, __func__); -- return false; -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); - } -- -- m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), false); -- m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), false); -- -- if(m_deinterlace) -+ omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); -+ if(omx_err != OMX_ErrorNone) - { -- m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), false); -- m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), false); -- -- port_image.nPortIndex = m_omx_image_fx.GetInputPort(); -- omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); -- if(omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 2 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -- -- port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); -- omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); -- if(omx_err != OMX_ErrorNone) -- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 3 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); - } -- -- m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), false); -- -- if(m_deinterlace) -+ port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); -+ omx_err = m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition, &port_image); -+ if(omx_err != OMX_ErrorNone) - { -- m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), false); -- m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), false); -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); - } -+ m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), true); - -- m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), false); -+ m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), true); -+ } -+ port_image.nPortIndex = m_omx_sched.GetInputPort(); -+ omx_err = m_omx_sched.SetParameter(OMX_IndexParamPortDefinition, &port_image); -+ if(omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ } -+ omx_err = m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged); -+ if(omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); -+ } -+ if (m_deinterlace) -+ { -+ m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), true); - } -+ m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true); -+ m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), true); - } - } - -@@ -932,7 +952,6 @@ void COMXVideo::Reset(void) - - SendDecoderConfig(); - -- m_first_frame = true; - */ - } - -diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h -index 0afa56d..037f155 100644 ---- a/xbmc/cores/omxplayer/OMXVideo.h -+++ b/xbmc/cores/omxplayer/OMXVideo.h -@@ -36,6 +36,8 @@ - - #define CLASSNAME "COMXVideo" - -+typedef void (*ResolutionUpdateCallBackFn)(void *ctx, uint32_t width, uint32_t height); -+ - class COMXVideo - { - public: -@@ -45,6 +47,7 @@ class COMXVideo - // Required overrides - bool SendDecoderConfig(); - bool Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace = false, bool hdmi_clock_sync = false); -+ void RegisterResolutionUpdateCallBack(void *ctx, ResolutionUpdateCallBackFn callback) { m_res_ctx = ctx; m_res_callback = callback; } - void Close(void); - unsigned int GetFreeSpace(); - unsigned int GetSize(); -@@ -89,9 +92,9 @@ class COMXVideo - - bool m_deinterlace; - bool m_hdmi_clock_sync; -- bool m_first_frame; - uint32_t m_history_valid_pts; -- -+ ResolutionUpdateCallBackFn m_res_callback; -+ void *m_res_ctx; - bool NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, int in_extrasize); - }; - --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch b/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch deleted file mode 100644 index 11ccd5224c..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 3d1005fdd34e72f81aff9034f8d30a0d33a780a8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 4 Mar 2013 08:30:47 +0100 -Subject: [PATCH] Always copy overlays from file parser - Fixes stuck hw - resources on render - ---- - .../cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h | 6 +++ - .../dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h | 6 +++ - .../dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h | 11 ++++++ - .../dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h | 41 ++++++++++++++++++++ - xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp | 1 + - .../dvdplayer/DVDSubtitles/DVDSubtitleParser.h | 8 +++- - 6 files changed, 72 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h -index 8c87bc4..da8de1f 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h -@@ -103,6 +103,12 @@ class CDVDOverlay - - bool IsOverlayType(DVDOverlayType type) { return (m_type == type); } - -+ /** -+ * return a copy to DVDPlayerSubtitle in order to have hw resources cleared -+ * after rendering -+ */ -+ virtual CDVDOverlay* Clone() { return Acquire(); } -+ - double iPTSStartTime; - double iPTSStopTime; - bool bForced; // display, no matter what -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h -index bc90d68..e1cdf59 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h -@@ -20,6 +20,7 @@ - * - */ - -+#include "PlatformDefs.h" - #include "DVDOverlay.h" - #include - #include -@@ -117,6 +118,11 @@ class CDVDOverlayImage : public CDVDOverlay - if(palette) free(palette); - } - -+ virtual CDVDOverlayImage* Clone() -+ { -+ return new CDVDOverlayImage(*this); -+ } -+ - BYTE* data_at(int sub_x, int sub_y) const - { - int bpp; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h -index 31deba1..f42c571 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h -@@ -37,10 +37,21 @@ class CDVDOverlaySSA : public CDVDOverlay - libass->Acquire(); - } - -+ CDVDOverlaySSA(CDVDOverlaySSA& src) -+ : CDVDOverlay(src) -+ , m_libass(src.m_libass) -+ { -+ m_libass->Acquire(); -+ } -+ - ~CDVDOverlaySSA() - { - if(m_libass) - SAFE_RELEASE(m_libass); - } - -+ virtual CDVDOverlaySSA* Clone() -+ { -+ return new CDVDOverlaySSA(*this); -+ } - }; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h -index 849a6e3..54e3bfa 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h -@@ -46,6 +46,12 @@ class CDVDOverlayText : public CDVDOverlay - m_type = type; - } - -+ CElement(CElement& src) -+ { -+ pNext = NULL; -+ m_type = src.m_type; -+ } -+ - virtual ~CElement() - { - } -@@ -71,6 +77,12 @@ class CDVDOverlayText : public CDVDOverlay - } - } - -+ CElementText(CElementText& src) -+ : CElement(src) -+ { -+ m_text = strdup(src.m_text); -+ } -+ - virtual ~CElementText() - { - if (m_text) free(m_text); -@@ -81,12 +93,20 @@ class CDVDOverlayText : public CDVDOverlay - - class CElementProperty : public CElement - { -+ public: - CElementProperty() : CElement(ELEMENT_TYPE_PROPERTY) - { - bItalic = false; - bBold = false; - } - -+ CElementProperty(CElementProperty& src) -+ : CElement(src) -+ { -+ bItalic = src.bItalic; -+ bBold = src.bBold; -+ } -+ - public: - bool bItalic; - bool bBold; -@@ -99,6 +119,22 @@ class CDVDOverlayText : public CDVDOverlay - m_pEnd = NULL; - } - -+ CDVDOverlayText(CDVDOverlayText& src) -+ : CDVDOverlay(src) -+ { -+ m_pHead = NULL; -+ m_pEnd = NULL; -+ for(CElement* e = src.m_pHead; e; e = e->pNext) -+ { -+ if(e->IsElementType(ELEMENT_TYPE_TEXT)) -+ AddElement(new CElementText(*static_cast(e))); -+ else if(e->IsElementType(ELEMENT_TYPE_PROPERTY)) -+ AddElement(new CElementProperty(*static_cast(e))); -+ else -+ AddElement(new CElement(*static_cast(e))); -+ } -+ } -+ - virtual ~CDVDOverlayText() - { - CElement* pTemp; -@@ -110,6 +146,11 @@ class CDVDOverlayText : public CDVDOverlay - } - } - -+ virtual CDVDOverlayText* Clone() -+ { -+ return new CDVDOverlayText(*this); -+ } -+ - void AddElement(CDVDOverlayText::CElement* pElement) - { - pElement->pNext = NULL; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp -index 29c8d57..540d890 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp -@@ -222,6 +222,7 @@ void CDVDPlayerSubtitle::Process(double pts) - while(pOverlay) - { - m_pOverlayContainer->Add(pOverlay); -+ pOverlay->Release(); - pOverlay = m_pSubtitleFileParser->Parse(pts); - } - -diff --git a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h -index 944bf06..3cd1e95 100644 ---- a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h -+++ b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h -@@ -47,7 +47,13 @@ class CDVDSubtitleParserCollection - m_filename = strFile; - } - virtual ~CDVDSubtitleParserCollection() { } -- virtual CDVDOverlay* Parse(double iPts) { return m_collection.Get(iPts); } -+ virtual CDVDOverlay* Parse(double iPts) -+ { -+ CDVDOverlay* o = m_collection.Get(iPts); -+ if(o == NULL) -+ return o; -+ return o->Clone(); -+ } - virtual void Reset() { m_collection.Reset(); } - virtual void Dispose() { m_collection.Clear(); } - --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch b/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch deleted file mode 100644 index ddf3dd7e81..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8717c162b8c5092d77672351ce3bfa2d4e7e32d8 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Tue, 5 Mar 2013 22:17:15 +0100 -Subject: [PATCH] AE: Fix resample of e.g. 192 khz to 48 khz audio by scaling - the usual suspects with the src sampleRate - ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -index 258dcac..a64beb1 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -@@ -196,6 +196,13 @@ void CSoftAEStream::Initialize() - m_ssrcData.data_out = (float*)_aligned_malloc(m_format.m_frameSamples * (int)std::ceil(m_ssrcData.src_ratio) * sizeof(float), 16); - m_ssrcData.output_frames = m_format.m_frames * (long)std::ceil(m_ssrcData.src_ratio); - m_ssrcData.end_of_input = 0; -+ // we must buffer the same amount as before but taking the source sample rate into account -+ // there is no reason to decrease the buffer for upsampling -+ if (m_internalRatio < 1) -+ { -+ m_waterLevel *= (1.0 / m_internalRatio); -+ m_refillBuffer = m_waterLevel; -+ } - } - - m_limiter.SetSamplerate(AE.GetSampleRate()); --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch b/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch deleted file mode 100644 index 2b158d1f20..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 249cccc2da097917995571b123ac22e30ed3f686 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 7 Mar 2013 12:50:57 +0000 -Subject: [PATCH] [rbp] Enable Vsync as a default - ---- - xbmc/settings/Settings.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h -index fd44a0f..5ba1d36 100644 ---- a/xbmc/settings/Settings.h -+++ b/xbmc/settings/Settings.h -@@ -36,7 +36,7 @@ - #ifdef MID - #define DEFAULT_VSYNC VSYNC_DISABLED - #else // MID --#if defined(TARGET_DARWIN) || defined(_WIN32) -+#if defined(TARGET_DARWIN) || defined(_WIN32) || defined(TARGET_RASPBERRY_PI) - #define DEFAULT_VSYNC VSYNC_ALWAYS - #else - #define DEFAULT_VSYNC VSYNC_DRIVER --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.27-fix-build.patch b/packages/mediacenter/xbmc/patches/xbmc-990.27-fix-build.patch new file mode 100644 index 0000000000..b17ea63d81 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.27-fix-build.patch @@ -0,0 +1,34 @@ +From 88e250d43dcb13ec2a05f64994c57a3d96b024b4 Mon Sep 17 00:00:00 2001 +From: Jim Carroll +Date: Mon, 11 Mar 2013 03:19:46 -0400 +Subject: [PATCH] [fix] build issue with std::min on some platforms. + +--- + xbmc/interfaces/legacy/File.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/xbmc/interfaces/legacy/File.h b/xbmc/interfaces/legacy/File.h +index d8b5d26..d3c17b3 100644 +--- a/xbmc/interfaces/legacy/File.h ++++ b/xbmc/interfaces/legacy/File.h +@@ -27,6 +27,8 @@ + #include "LanguageHook.h" + #include "commons/Buffer.h" + ++#include ++ + namespace XBMCAddon + { + +@@ -70,7 +72,7 @@ + inline String read(unsigned long numBytes = 0) + { + XbmcCommons::Buffer b = readBytes(numBytes); +- return b.getString(numBytes == 0 ? b.remaining() : std::min(b.remaining(),numBytes)); ++ return b.getString(numBytes == 0 ? b.remaining() : std::min((unsigned long)b.remaining(),numBytes)); + } + + /** +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch b/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch deleted file mode 100644 index e5cc23d133..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.28-PR2395.patch +++ /dev/null @@ -1,31 +0,0 @@ -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 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch b/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch deleted file mode 100644 index 7a0301aaee..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.29-PR2387.patch +++ /dev/null @@ -1,1508 +0,0 @@ -From 9d0695f2ae5f2a4d98c4ec6882fecd8209a425bc Mon Sep 17 00:00:00 2001 -From: Lars Op den Kamp -Date: Thu, 28 Feb 2013 20:41:38 +0100 -Subject: [PATCH] [cec] rebased PR1794 + fixes for Frodo - ---- - XBMC.xcodeproj/project.pbxproj | 13 +++ - configure.in | 40 +------ - system/peripherals.xml | 31 ++---- - tools/android/depends/libcec/Makefile | 4 +- - tools/darwin/depends/libcec/Makefile | 2 +- - xbmc/peripherals/PeripheralTypes.h | 76 ++++++++++++- - xbmc/peripherals/Peripherals.cpp | 62 +++++------ - xbmc/peripherals/Peripherals.h | 7 +- - xbmc/peripherals/bus/Makefile.in | 4 +- - xbmc/peripherals/bus/PeripheralBus.cpp | 81 +++----------- - xbmc/peripherals/bus/PeripheralBus.h | 23 +--- - xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp | 69 ------------ - xbmc/peripherals/bus/linux/PeripheralBusRPi.h | 40 ------- - .../bus/linux/PeripheralBusUSBLibUSB.cpp | 3 +- - .../bus/linux/PeripheralBusUSBLibUdev.cpp | 4 +- - xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp | 1 + - xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp | 116 ++++++++++++++++++++ - xbmc/peripherals/bus/virtual/PeripheralBusCEC.h | 57 ++++++++++ - xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp | 5 +- - xbmc/peripherals/devices/Peripheral.cpp | 50 ++++----- - xbmc/peripherals/devices/Peripheral.h | 6 +- - xbmc/peripherals/devices/PeripheralBluetooth.cpp | 4 +- - xbmc/peripherals/devices/PeripheralBluetooth.h | 2 +- - xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 52 ++------- - xbmc/peripherals/devices/PeripheralCecAdapter.h | 4 +- - xbmc/peripherals/devices/PeripheralDisk.cpp | 5 +- - xbmc/peripherals/devices/PeripheralDisk.h | 2 +- - xbmc/peripherals/devices/PeripheralHID.cpp | 5 +- - xbmc/peripherals/devices/PeripheralHID.h | 2 +- - xbmc/peripherals/devices/PeripheralImon.cpp | 4 +- - xbmc/peripherals/devices/PeripheralImon.h | 2 +- - xbmc/peripherals/devices/PeripheralNIC.cpp | 5 +- - xbmc/peripherals/devices/PeripheralNIC.h | 2 +- - xbmc/peripherals/devices/PeripheralNyxboard.cpp | 4 +- - xbmc/peripherals/devices/PeripheralNyxboard.h | 2 +- - xbmc/peripherals/devices/PeripheralTuner.cpp | 4 +- - xbmc/peripherals/devices/PeripheralTuner.h | 2 +- - 40 files changed, 404 insertions(+), 401 deletions(-) - delete mode 100644 xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp - delete mode 100644 xbmc/peripherals/bus/linux/PeripheralBusRPi.h - create mode 100644 xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp - create mode 100644 xbmc/peripherals/bus/virtual/PeripheralBusCEC.h - -diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj -index bf4a009..fbcd662 100644 -diff --git a/configure.in b/configure.in -index 4769315..4472e3e 100644 ---- a/configure.in -+++ b/configure.in -@@ -157,8 +157,6 @@ libusb_disabled="== libusb disabled. Plug and play USB device support will not b - libusb_disabled_udev_found="== libusb disabled. ==" - libcec_enabled="== libcec enabled. ==" - libcec_disabled="== libcec disabled. CEC adapter support will not be available. ==" --libcec_disabled_missing_libs="== libcec disabled because it either needs libudev, or libusb a compatible version of the RPi API. CEC adapter support will not be available. ==" --cec_rpi_api_missing="== no compatible RPi API found ==" - - # External library message strings - external_libraries_enabled="== Use of all supported external libraries enabled. ==" -@@ -1455,46 +1453,18 @@ fi - - # libcec - USE_LIBCEC=0 --USE_CEC_RPI_API=0 --use_rpi_cec_api="auto" - if test "x$use_libcec" != "xno"; then -- case "${host_cpu}" in -- arm*) -- echo "will check for RPi support" -- AC_CHECK_HEADER(interface/vmcs_host/vc_cec.h,,use_rpi_cec_api="no") -- ;; -- *) -- echo "will not check for RPi support (unsupported cpu: ${host_cpu})" -- use_rpi_cec_api="no" -- ;; -- esac -- -- # libcec needs libudev, libusb or the RPi API under linux, or the device will never be detected. -- if test "$host_vendor" != "apple" && test "$use_libusb" = "no" && test "$use_libudev" = "no" && test "$use_rpi_cec_api" = "no"; then -- if test "x$use_libcec" != "xauto"; then -- AC_MSG_ERROR($libcec_disabled_missing_libs) -- else -- use_libcec="no" -- AC_MSG_NOTICE($libcec_disabled_missing_libs) -- fi -- fi -- - # libcec is dyloaded, so we need to check for its headers and link any depends. - if test "x$use_libcec" != "xno"; then - if test "x$use_libcec" != "xauto"; then -- PKG_CHECK_MODULES([CEC],[libcec >= 2.0.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)]) -+ PKG_CHECK_MODULES([CEC],[libcec >= 2.1.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)]) - else -- PKG_CHECK_MODULES([CEC],[libcec >= 2.0.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) -+ PKG_CHECK_MODULES([CEC],[libcec >= 2.1.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) - fi - - if test "x$use_libcec" != "xno"; then - INCLUDES="$INCLUDES $CEC_CFLAGS" - USE_LIBCEC=1;AC_DEFINE([HAVE_LIBCEC],[1],["Define to 1 if libcec is installed"]) -- if test "x$use_rpi_cec_api" != "xno"; then -- LIBS+=" -lvcos -lvchiq_arm" -- AC_DEFINE([HAVE_CEC_RPI_API],[1],["Define to 1 if the CEC RPi API is installed"]) -- USE_CEC_RPI_API=1 -- fi - XB_FIND_SONAME([LIBCEC],[cec],[use_libcec]) - AC_MSG_NOTICE($libcec_enabled) - else -@@ -2255,11 +2225,6 @@ fi - - if test "x$use_libcec" != "xno"; then - final_message="$final_message\n libcec support:\tYes" -- if test "x$use_rpi_cec_api" != "xno"; then -- final_message="$final_message\n libcec RPi support:\tYes" -- else -- final_message="$final_message\n libcec RPi support:\tNo" -- fi - else - final_message="$final_message\n libcec support:\tNo" - fi -@@ -2451,7 +2416,6 @@ AC_SUBST(USE_AIRTUNES) - AC_SUBST(USE_LIBUDEV) - AC_SUBST(USE_LIBUSB) - AC_SUBST(USE_LIBCEC) --AC_SUBST(USE_CEC_RPI_API) - AC_SUBST(USE_MYSQL) - AC_SUBST(USE_WEB_SERVER) - AC_SUBST(USE_UPNP) -diff --git a/system/peripherals.xml b/system/peripherals.xml -index 967b96c..68205df 100644 ---- a/system/peripherals.xml -+++ b/system/peripherals.xml -@@ -7,30 +7,7 @@ - - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -+ - - - -@@ -54,6 +31,12 @@ - - - -+ -+ -+ -+ - - - -diff --git a/tools/android/depends/libcec/Makefile b/tools/android/depends/libcec/Makefile -index 7d9b6b8..0147147 100644 ---- a/tools/android/depends/libcec/Makefile -+++ b/tools/android/depends/libcec/Makefile -@@ -3,7 +3,7 @@ DEPS= ../Makefile.include Makefile - - # lib name, version - LIBNAME=libcec --VERSION=2.0.5-3 -+VERSION=2.1.0 - SOURCE=$(LIBNAME)-$(VERSION) - ARCHIVE=$(SOURCE).tar.gz - -@@ -11,7 +11,7 @@ ARCHIVE=$(SOURCE).tar.gz - CONFIGURE=./configure --prefix=$(PREFIX) --host=$(HOST) \ - ac_cv_search_dlopen=yes - --LIBDYLIB=$(PLATFORM)/src/lib/.libs/libcec.so.2.0.0 -+LIBDYLIB=$(PLATFORM)/src/lib/.libs/libcec.so.2.0.1 - - all: .installed-$(PLATFORM) - -diff --git a/tools/darwin/depends/libcec/Makefile b/tools/darwin/depends/libcec/Makefile -index 3e84bff..b7970dd 100644 ---- a/tools/darwin/depends/libcec/Makefile -+++ b/tools/darwin/depends/libcec/Makefile -@@ -3,7 +3,7 @@ include ../config.site.mk - - # lib name, version - LIBNAME=libcec --VERSION=2.0.5-3 -+VERSION=2.1.0 - SOURCE=$(LIBNAME)-$(VERSION) - ARCHIVE=$(SOURCE).tar.gz - -diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h -index 3cd7691..03030d4 100644 ---- a/xbmc/peripherals/PeripheralTypes.h -+++ b/xbmc/peripherals/PeripheralTypes.h -@@ -35,7 +35,8 @@ - PERIPHERAL_BUS_UNKNOWN = 0, - PERIPHERAL_BUS_USB, - PERIPHERAL_BUS_PCI, -- PERIPHERAL_BUS_RPI -+ PERIPHERAL_BUS_RPI, -+ PERIPHERAL_BUS_CEC - }; - - enum PeripheralFeature -@@ -143,6 +144,8 @@ - return "pci"; - case PERIPHERAL_BUS_RPI: - return "rpi"; -+ case PERIPHERAL_BUS_CEC: -+ return "cec"; - default: - return "unknown"; - } -@@ -159,6 +162,8 @@ - return PERIPHERAL_BUS_PCI; - else if (strTypeLowerCase.Equals("rpi")) - return PERIPHERAL_BUS_RPI; -+ else if (strTypeLowerCase.Equals("cec")) -+ return PERIPHERAL_BUS_CEC; - - return PERIPHERAL_BUS_UNKNOWN; - }; -@@ -180,4 +185,73 @@ - strHexString.Format("%04X", iVal); - }; - }; -+ -+ class PeripheralScanResult -+ { -+ public: -+ PeripheralScanResult(const PeripheralBusType busType) : -+ m_type(PERIPHERAL_UNKNOWN), -+ m_iVendorId(0), -+ m_iProductId(0), -+ m_mappedType(PERIPHERAL_UNKNOWN), -+ m_busType(busType), -+ m_mappedBusType(busType), -+ m_iSequence(0) {} -+ -+ PeripheralScanResult(void) : -+ m_type(PERIPHERAL_UNKNOWN), -+ m_iVendorId(0), -+ m_iProductId(0), -+ m_mappedType(PERIPHERAL_UNKNOWN), -+ m_busType(PERIPHERAL_BUS_UNKNOWN), -+ m_mappedBusType(PERIPHERAL_BUS_UNKNOWN), -+ m_iSequence(0) {} -+ -+ bool operator ==(const PeripheralScanResult& right) const -+ { -+ return m_iVendorId == right.m_iVendorId && -+ m_iProductId == right.m_iProductId && -+ m_type == right.m_type && -+ m_busType == right.m_busType && -+ m_strLocation.Equals(right.m_strLocation); -+ } -+ -+ bool operator !=(const PeripheralScanResult& right) const -+ { -+ return !(*this == right); -+ } -+ -+ PeripheralType m_type; -+ CStdString m_strLocation; -+ int m_iVendorId; -+ int m_iProductId; -+ PeripheralType m_mappedType; -+ CStdString m_strDeviceName; -+ PeripheralBusType m_busType; -+ PeripheralBusType m_mappedBusType; -+ unsigned int m_iSequence; // when more than one adapter of the same type is found -+ }; -+ -+ struct PeripheralScanResults -+ { -+ bool GetDeviceOnLocation(const CStdString& strLocation, PeripheralScanResult* result) const -+ { -+ for (std::vector::const_iterator it = m_results.begin(); it != m_results.end(); it++) -+ { -+ if ((*it).m_strLocation == strLocation) -+ { -+ *result = *it; -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ bool ContainsResult(const PeripheralScanResult& result) const -+ { -+ return std::find(m_results.begin(), m_results.end(), result) != m_results.end(); -+ } -+ -+ std::vector m_results; -+ }; - } -diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp -index 3ce8c07..c5fadd9 100644 ---- a/xbmc/peripherals/Peripherals.cpp -+++ b/xbmc/peripherals/Peripherals.cpp -@@ -31,8 +31,8 @@ - #include "bus/PeripheralBusUSB.h" - #include "dialogs/GUIDialogPeripheralManager.h" - --#ifdef HAVE_CEC_RPI_API --#include "bus/linux/PeripheralBusRPi.h" -+#if defined(HAVE_LIBCEC) -+#include "bus/virtual/PeripheralBusCEC.h" - #endif - - #include "threads/SingleLock.h" -@@ -84,8 +84,8 @@ void CPeripherals::Initialise(void) - #if defined(HAVE_PERIPHERAL_BUS_USB) - m_busses.push_back(new CPeripheralBusUSB(this)); - #endif --#ifdef HAVE_CEC_RPI_API -- m_busses.push_back(new CPeripheralBusRPi(this)); -+#if defined(HAVE_LIBCEC) -+ m_busses.push_back(new CPeripheralBusCEC(this)); - #endif - - /* initialise all known busses */ -@@ -229,54 +229,50 @@ bool CPeripherals::HasPeripheralWithFeature(const PeripheralFeature feature, Per - return (GetPeripheralsWithFeature(dummy, feature, busType) > 0); - } - --CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId /* = 0 */, int iProductId /* = 0 */) -+CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralScanResult& result) - { - CPeripheral *peripheral = NULL; -+ PeripheralScanResult mappedResult = result; -+ if (mappedResult.m_busType == PERIPHERAL_BUS_UNKNOWN) -+ mappedResult.m_busType = bus.Type(); -+ - /* check whether there's something mapped in peripherals.xml */ -- PeripheralType mappedType = type; -- CStdString strDeviceName; -- int iMappingPtr = GetMappingForDevice(bus, type, iVendorId, iProductId); -- bool bHasMapping(iMappingPtr >= 0); -- if (bHasMapping) -- { -- mappedType = m_mappings[iMappingPtr].m_mappedTo; -- strDeviceName = m_mappings[iMappingPtr].m_strDeviceName; -- } -- else -+ if (!GetMappingForDevice(bus, mappedResult)) - { - /* don't create instances for devices that aren't mapped in peripherals.xml */ - return NULL; - } - -- switch(mappedType) -+ switch(mappedResult.m_mappedType) - { - case PERIPHERAL_HID: -- peripheral = new CPeripheralHID(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralHID(mappedResult); - break; - - case PERIPHERAL_NIC: -- peripheral = new CPeripheralNIC(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralNIC(mappedResult); - break; - - case PERIPHERAL_DISK: -- peripheral = new CPeripheralDisk(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralDisk(mappedResult); - break; - - case PERIPHERAL_NYXBOARD: -- peripheral = new CPeripheralNyxboard(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralNyxboard(mappedResult); - break; - - case PERIPHERAL_TUNER: -- peripheral = new CPeripheralTuner(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralTuner(mappedResult); - break; - - case PERIPHERAL_BLUETOOTH: -- peripheral = new CPeripheralBluetooth(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralBluetooth(mappedResult); - break; - - case PERIPHERAL_CEC: - #if defined(HAVE_LIBCEC) -- peripheral = new CPeripheralCecAdapter(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ if (bus.Type() == PERIPHERAL_BUS_CEC) -+ peripheral = new CPeripheralCecAdapter(mappedResult); - #else - if (!m_bMissingLibCecWarningDisplayed) - { -@@ -288,7 +284,7 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera - break; - - case PERIPHERAL_IMON: -- peripheral = new CPeripheralImon(type, bus.Type(), strLocation, strDeviceName, iVendorId, iProductId); -+ peripheral = new CPeripheralImon(mappedResult); - break; - - default: -@@ -305,7 +301,7 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera - } - else - { -- CLog::Log(LOGDEBUG, "%s - failed to initialise peripheral on '%s'", __FUNCTION__, strLocation.c_str()); -+ CLog::Log(LOGDEBUG, "%s - failed to initialise peripheral on '%s'", __FUNCTION__, mappedResult.m_strLocation.c_str()); - delete peripheral; - peripheral = NULL; - } -@@ -340,7 +336,7 @@ void CPeripherals::OnDeviceDeleted(const CPeripheralBus &bus, const CPeripheral - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(35006), peripheral.DeviceName()); - } - --int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const -+bool CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, PeripheralScanResult& result) const - { - /* check all mappings in the order in which they are defined in peripherals.xml */ - for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++) -@@ -355,24 +351,26 @@ int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const Periphera - else - { - for (unsigned int i = 0; i < mapping.m_PeripheralID.size(); i++) -- if (mapping.m_PeripheralID[i].m_iVendorId == iVendorId && mapping.m_PeripheralID[i].m_iProductId == iProductId) -+ if (mapping.m_PeripheralID[i].m_iVendorId == result.m_iVendorId && mapping.m_PeripheralID[i].m_iProductId == result.m_iProductId) - bProductMatch = true; - } - - bool bBusMatch = (mapping.m_busType == PERIPHERAL_BUS_UNKNOWN || mapping.m_busType == bus.Type()); -- bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == classType); -+ bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == result.m_type); - - if (bProductMatch && bBusMatch && bClassMatch) - { - CStdString strVendorId, strProductId; -- PeripheralTypeTranslator::FormatHexString(iVendorId, strVendorId); -- PeripheralTypeTranslator::FormatHexString(iProductId, strProductId); -+ PeripheralTypeTranslator::FormatHexString(result.m_iVendorId, strVendorId); -+ PeripheralTypeTranslator::FormatHexString(result.m_iProductId, strProductId); - CLog::Log(LOGDEBUG, "%s - device (%s:%s) mapped to %s (type = %s)", __FUNCTION__, strVendorId.c_str(), strProductId.c_str(), mapping.m_strDeviceName.c_str(), PeripheralTypeTranslator::TypeToString(mapping.m_mappedTo)); -- return iMappingPtr; -+ result.m_mappedType = m_mappings[iMappingPtr].m_mappedTo; -+ result.m_strDeviceName = m_mappings[iMappingPtr].m_strDeviceName; -+ return true; - } - } - -- return -1; -+ return false; - } - - void CPeripherals::GetSettingsFromMapping(CPeripheral &peripheral) const -diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h -index ac94699..9594ff8 100644 ---- a/xbmc/peripherals/Peripherals.h -+++ b/xbmc/peripherals/Peripherals.h -@@ -111,11 +111,10 @@ - /*! - * @brief Creates a new instance of a peripheral. - * @param bus The bus on which this peripheral is present. -- * @param type The type of the new peripheral. -- * @param strLocation The location on the bus. -+ * @param result The scan result from the device scanning code. - * @return The new peripheral or NULL if it could not be created. - */ -- CPeripheral *CreatePeripheral(CPeripheralBus &bus, const PeripheralType type, const CStdString &strLocation, int iVendorId = 0, int iProductId = 0); -+ CPeripheral *CreatePeripheral(CPeripheralBus &bus, const PeripheralScanResult& result); - - /*! - * @brief Add the settings that are defined in the mappings file to the peripheral (if there is anything defined). -@@ -200,7 +199,7 @@ - private: - CPeripherals(void); - bool LoadMappings(void); -- int GetMappingForDevice(const CPeripheralBus &bus, const PeripheralType classType, int iVendorId, int iProductId) const; -+ bool GetMappingForDevice(const CPeripheralBus &bus, PeripheralScanResult& result) const; - static void GetSettingsFromMappingsFile(TiXmlElement *xmlNode, std::map &m_settings); - - bool m_bInitialised; -diff --git a/xbmc/peripherals/bus/Makefile.in b/xbmc/peripherals/bus/Makefile.in -index 01fa4e2..2262e4a 100644 ---- a/xbmc/peripherals/bus/Makefile.in -+++ b/xbmc/peripherals/bus/Makefile.in -@@ -12,8 +12,8 @@ ifeq ($(findstring osx,@ARCH@),osx) - SRCS += osx/PeripheralBusUSB.cpp - endif - --ifeq (@USE_CEC_RPI_API@,1) --SRCS += linux/PeripheralBusRPi.cpp -+ifeq (@USE_LIBCEC@,1) -+SRCS += virtual/PeripheralBusCEC.cpp - endif - - LIB = peripheral-bus.a -diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp -index 727f7c9..b17a9f1 100644 ---- a/xbmc/peripherals/bus/PeripheralBus.cpp -+++ b/xbmc/peripherals/bus/PeripheralBus.cpp -@@ -29,65 +29,6 @@ - - #define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000 - --bool PeripheralScanResult::operator ==(const PeripheralScanResult &right) const --{ -- return m_iVendorId == right.m_iVendorId && -- m_iProductId == right.m_iProductId && -- m_type == right.m_type && -- m_strLocation.Equals(right.m_strLocation); --} -- --bool PeripheralScanResult::operator !=(const PeripheralScanResult &right) const --{ -- return !(*this == right); --} -- --bool PeripheralScanResult::operator ==(const CPeripheral &right) const --{ -- return m_iVendorId == right.VendorId() && -- m_iProductId == right.ProductId() && -- m_type == right.Type() && -- m_strLocation.Equals(right.Location()); --} -- --bool PeripheralScanResult::operator !=(const CPeripheral &right) const --{ -- return !(*this == right); --} -- --bool PeripheralScanResults::GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const --{ -- bool bReturn(false); -- -- for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) -- { -- if (m_results.at(iDevicePtr).m_strLocation == strLocation) -- { -- *result = m_results.at(iDevicePtr); -- bReturn = true; -- break; -- } -- } -- -- return bReturn; --} -- --bool PeripheralScanResults::ContainsResult(const PeripheralScanResult &result) const --{ -- bool bReturn(false); -- -- for (unsigned int iDevicePtr = 0; iDevicePtr < m_results.size(); iDevicePtr++) -- { -- if (m_results.at(iDevicePtr) == result) -- { -- bReturn = true; -- break; -- } -- } -- -- return bReturn; --} -- - CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) : - CThread("XBMC Peripherals"), - m_iRescanTime(PERIPHERAL_DEFAULT_RESCAN_INTERVAL), -@@ -137,9 +78,9 @@ void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &resul - for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--) - { - CPeripheral *peripheral = m_peripherals.at(iDevicePtr); -- PeripheralScanResult updatedDevice; -+ PeripheralScanResult updatedDevice(m_type); - if (!results.GetDeviceOnLocation(peripheral->Location(), &updatedDevice) || -- updatedDevice != *peripheral) -+ *peripheral != updatedDevice) - { - /* device removed */ - removedPeripherals.push_back(peripheral); -@@ -170,9 +111,9 @@ void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results) - CSingleLock lock(m_critSection); - for (unsigned int iResultPtr = 0; iResultPtr < results.m_results.size(); iResultPtr++) - { -- PeripheralScanResult result = results.m_results.at(iResultPtr); -+ const PeripheralScanResult& result = results.m_results.at(iResultPtr); - if (!HasPeripheral(result.m_strLocation)) -- g_peripherals.CreatePeripheral(*this, result.m_type, result.m_strLocation, result.m_iVendorId, result.m_iProductId); -+ g_peripherals.CreatePeripheral(*this, result); - } - } - -@@ -246,6 +187,20 @@ int CPeripheralBus::GetPeripheralsWithFeature(vector &results, co - return iReturn; - } - -+size_t CPeripheralBus::GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const -+{ -+ int iReturn(0); -+ CSingleLock lock(m_critSection); -+ for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < m_peripherals.size(); iPeripheralPtr++) -+ { -+ if (m_peripherals.at(iPeripheralPtr)->VendorId() == iVendorId && -+ m_peripherals.at(iPeripheralPtr)->ProductId() == iProductId) -+ iReturn++; -+ } -+ -+ return iReturn; -+} -+ - void CPeripheralBus::Process(void) - { - while (!m_bStop) -diff --git a/xbmc/peripherals/bus/PeripheralBus.h b/xbmc/peripherals/bus/PeripheralBus.h -index 96426a9..29ff7d7 100644 ---- a/xbmc/peripherals/bus/PeripheralBus.h -+++ b/xbmc/peripherals/bus/PeripheralBus.h -@@ -31,28 +31,6 @@ - { - class CPeripherals; - -- struct PeripheralScanResult -- { -- bool operator ==(const PeripheralScanResult &right) const; -- bool operator !=(const PeripheralScanResult &right) const; -- -- bool operator ==(const CPeripheral &right) const; -- bool operator !=(const CPeripheral &right) const; -- -- PeripheralType m_type; -- CStdString m_strLocation; -- int m_iVendorId; -- int m_iProductId; -- }; -- -- struct PeripheralScanResults -- { -- bool GetDeviceOnLocation(const CStdString &strLocation, PeripheralScanResult *result) const; -- bool ContainsResult(const PeripheralScanResult &result) const; -- -- std::vector m_results; -- }; -- - /*! - * @class CPeripheralBus - * This represents a bus on the system. By default, this bus instance will scan for changes every second. -@@ -100,6 +78,7 @@ - virtual int GetPeripheralsWithFeature(std::vector &results, const PeripheralFeature feature) const; - - virtual size_t GetNumberOfPeripherals() const; -+ virtual size_t GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const; - - /*! - * @brief Get all features that are supported by devices on this bus. -diff --git a/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp b/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp -deleted file mode 100644 -index 8a436e4..0000000 ---- a/xbmc/peripherals/bus/linux/PeripheralBusRPi.cpp -+++ /dev/null -@@ -1,69 +0,0 @@ --/* -- * Copyright (C) 2005-2012 Team XBMC -- * http://xbmc.org -- * -- * This Program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This Program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with XBMC; see the file COPYING. If not, see -- * . -- * -- */ -- --#include "PeripheralBusRPi.h" --#include -- --extern "C" { --#include --#include --} -- --using namespace PERIPHERALS; -- --#define RPI_PERIPHERAL_BUS_VID 0x2708 --#define RPI_PERIPHERAL_CEC_PID 0x1001 -- --CPeripheralBusRPi::CPeripheralBusRPi(CPeripherals *manager) : -- CPeripheralBus(manager, PERIPHERAL_BUS_RPI) --{ -- m_bNeedsPolling = false; --} -- --bool CPeripheralBusRPi::PerformDeviceScan(PeripheralScanResults &results) --{ -- if (FindAdapter()) -- { -- PeripheralScanResult result; -- result.m_iVendorId = RPI_PERIPHERAL_BUS_VID; -- result.m_iProductId = RPI_PERIPHERAL_CEC_PID; -- result.m_type = PERIPHERAL_CEC; -- result.m_strLocation = CEC_RPI_VIRTUAL_COM; -- -- if (!results.ContainsResult(result)) -- results.m_results.push_back(result); -- } -- -- return true; --} -- --bool CPeripheralBusRPi::FindAdapter(void) --{ -- uint8_t iResult; -- -- VCHI_INSTANCE_T vchiq_instance; -- if ((iResult = vchi_initialise(&vchiq_instance)) != VCHIQ_SUCCESS) -- return false; -- -- if ((iResult = vchi_connect(NULL, 0, vchiq_instance)) != VCHIQ_SUCCESS) -- return false; -- -- return true; --} -diff --git a/xbmc/peripherals/bus/linux/PeripheralBusRPi.h b/xbmc/peripherals/bus/linux/PeripheralBusRPi.h -deleted file mode 100644 -index e660401..0000000 ---- a/xbmc/peripherals/bus/linux/PeripheralBusRPi.h -+++ /dev/null -@@ -1,40 +0,0 @@ --#pragma once --/* -- * Copyright (C) 2005-2012 Team XBMC -- * http://xbmc.org -- * -- * This Program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This Program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with XBMC; see the file COPYING. If not, see -- * . -- * -- */ -- --#include "peripherals/bus/PeripheralBus.h" --#include "peripherals/devices/Peripheral.h" -- --namespace PERIPHERALS --{ -- class CPeripherals; -- -- class CPeripheralBusRPi : public CPeripheralBus -- { -- public: -- CPeripheralBusRPi(CPeripherals *manager); -- virtual ~CPeripheralBusRPi(void) {}; -- -- bool PerformDeviceScan(PeripheralScanResults &results); -- -- private: -- bool FindAdapter(void); -- }; --} -diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp -index 659ebf0..563c96e 100644 ---- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp -+++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUSB.cpp -@@ -43,7 +43,7 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) - struct usb_device *dev; - for (dev = bus->devices; dev; dev = dev->next) - { -- PeripheralScanResult result; -+ PeripheralScanResult result(m_type); - result.m_iVendorId = dev->descriptor.idVendor; - result.m_iProductId = dev->descriptor.idProduct; - result.m_type = (dev->descriptor.bDeviceClass == USB_CLASS_PER_INTERFACE && dev->descriptor.bNumConfigurations > 0 && -@@ -55,6 +55,7 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) - #else - result.m_strLocation.Format("/bus%s/dev%s", bus->dirname, dev->filename); - #endif -+ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); - if (!results.ContainsResult(result)) - results.m_results.push_back(result); - } -diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp -index b7a0061..ca21e06 100644 ---- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp -+++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp -@@ -152,12 +152,12 @@ bool CPeripheralBusUSB::PerformDeviceScan(PeripheralScanResults &results) - iClass = USB_CLASS_HID; - } - -- PeripheralScanResult result; -+ PeripheralScanResult result(m_type); - result.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(udev_device_get_sysattr_value(dev, "idVendor")); - result.m_iProductId = PeripheralTypeTranslator::HexStringToInt(udev_device_get_sysattr_value(dev, "idProduct")); - result.m_type = GetType(iClass); - result.m_strLocation = udev_device_get_syspath(dev); -- -+ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); - if (!results.ContainsResult(result)) - results.m_results.push_back(result); - } -diff --git a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp -index b0e3617..78bd224 100644 ---- a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp -+++ b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp -@@ -266,6 +266,7 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera - else - privateDataRef->result.m_type = refCon->GetType(bDeviceClass); - -+ privateDataRef->result.m_iSequence = refCon->GetNumberOfPeripheralsWithId(privateDataRef->result.m_iVendorId, privateDataRef->result.m_iProductId); - if (!refCon->m_scan_results.ContainsResult(privateDataRef->result)) - { - // register this usb device for an interest notification callback. -diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp -new file mode 100644 -index 0000000..da169c1 ---- /dev/null -+++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp -@@ -0,0 +1,116 @@ -+/* -+ * Copyright (C) 2005-2012 Team XBMC -+ * http://xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "system.h" -+#if defined(HAVE_LIBCEC) -+#include "PeripheralBusCEC.h" -+#include "peripherals/Peripherals.h" -+#include "utils/log.h" -+#include "DynamicDll.h" -+ -+#include -+ -+using namespace PERIPHERALS; -+using namespace CEC; -+using namespace std; -+ -+class DllLibCECInterface -+{ -+public: -+ virtual ~DllLibCECInterface() {} -+ virtual ICECAdapter* CECInitialise(libcec_configuration *configuration)=0; -+ virtual void* CECDestroy(ICECAdapter *adapter)=0; -+}; -+ -+class PERIPHERALS::DllLibCEC : public DllDynamic, DllLibCECInterface -+{ -+ DECLARE_DLL_WRAPPER(DllLibCEC, DLL_PATH_LIBCEC) -+ -+ DEFINE_METHOD1(ICECAdapter*, CECInitialise, (libcec_configuration *p1)) -+ DEFINE_METHOD1(void* , CECDestroy, (ICECAdapter *p1)) -+ -+ BEGIN_METHOD_RESOLVE() -+ RESOLVE_METHOD_RENAME(CECInitialise, CECInitialise) -+ RESOLVE_METHOD_RENAME(CECDestroy, CECDestroy) -+ END_METHOD_RESOLVE() -+}; -+ -+CPeripheralBusCEC::CPeripheralBusCEC(CPeripherals *manager) : -+ CPeripheralBus(manager, PERIPHERAL_BUS_CEC), -+ m_dll(new DllLibCEC), -+ m_cecAdapter(NULL) -+{ -+ m_iRescanTime = 1000; -+ if (!m_dll->Load() || !m_dll->IsLoaded()) -+ { -+ delete m_dll; -+ m_dll = NULL; -+ } -+ else -+ { -+ m_cecAdapter = m_dll->CECInitialise(&m_configuration); -+ } -+} -+ -+CPeripheralBusCEC::~CPeripheralBusCEC(void) -+{ -+ if (m_dll && m_cecAdapter) -+ m_dll->CECDestroy(m_cecAdapter); -+ delete m_dll; -+} -+ -+bool CPeripheralBusCEC::PerformDeviceScan(PeripheralScanResults &results) -+{ -+ if (!m_dll || !m_cecAdapter) -+ return false; -+ -+ cec_adapter_descriptor deviceList[10]; -+ int8_t iFound = m_cecAdapter->DetectAdapters(deviceList, 10, NULL, true); -+ -+ for (uint8_t iDevicePtr = 0; iDevicePtr < iFound; iDevicePtr++) -+ { -+ PeripheralScanResult result(m_type); -+ result.m_iVendorId = deviceList[iDevicePtr].iVendorId; -+ result.m_iProductId = deviceList[iDevicePtr].iProductId; -+ result.m_strLocation = deviceList[iDevicePtr].strComName; -+ result.m_type = PERIPHERAL_CEC; -+ -+ // override the bus type, so users don't have to reconfigure their adapters -+ switch(deviceList[iDevicePtr].adapterType) -+ { -+ case ADAPTERTYPE_P8_EXTERNAL: -+ case ADAPTERTYPE_P8_DAUGHTERBOARD: -+ result.m_mappedBusType = PERIPHERAL_BUS_USB; -+ break; -+ case ADAPTERTYPE_RPI: -+ result.m_mappedBusType = PERIPHERAL_BUS_RPI; -+ break; -+ default: -+ break; -+ } -+ -+ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); -+ if (!results.ContainsResult(result)) -+ results.m_results.push_back(result); -+ } -+ return true; -+} -+ -+#endif -diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h -new file mode 100644 -index 0000000..acba01a ---- /dev/null -+++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.h -@@ -0,0 +1,57 @@ -+#pragma once -+/* -+ * Copyright (C) 2005-2013 Team XBMC -+ * http://xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "peripherals/bus/PeripheralBus.h" -+#include "peripherals/devices/Peripheral.h" -+ -+// undefine macro isset, it collides with function in cectypes.h -+#ifdef isset -+#undef isset -+#endif -+#include -+ -+namespace CEC -+{ -+ class ICECAdapter; -+} -+ -+namespace PERIPHERALS -+{ -+ class CPeripherals; -+ class DllLibCEC; -+ -+ class CPeripheralBusCEC : public CPeripheralBus -+ { -+ public: -+ CPeripheralBusCEC(CPeripherals *manager); -+ virtual ~CPeripheralBusCEC(void); -+ -+ /*! -+ * @see PeripheralBus::PerformDeviceScan() -+ */ -+ bool PerformDeviceScan(PeripheralScanResults &results); -+ -+ private: -+ DllLibCEC* m_dll; -+ CEC::ICECAdapter* m_cecAdapter; -+ CEC::libcec_configuration m_configuration; -+ }; -+} -diff --git a/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp -index 811e0d1..fb55561 100644 ---- a/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp -+++ b/xbmc/peripherals/bus/win32/PeripheralBusUSB.cpp -@@ -104,14 +104,15 @@ bool CPeripheralBusUSB::PerformDeviceScan(const GUID *guid, const PeripheralType - - if ((strTmp.Find("&mi_") < 0) || (strTmp.Find("&mi_00") >= 0)) - { -- PeripheralScanResult prevDevice; -+ PeripheralScanResult prevDevice(m_type); - if (!results.GetDeviceOnLocation(devicedetailData->DevicePath, &prevDevice)) - { -- PeripheralScanResult result; -+ PeripheralScanResult result(m_type); - result.m_strLocation = devicedetailData->DevicePath; - result.m_type = type; - result.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(strVendorId.c_str()); - result.m_iProductId = PeripheralTypeTranslator::HexStringToInt(strProductId.c_str()); -+ result.m_iSequence = GetNumberOfPeripheralsWithId(result.m_iVendorId, result.m_iProductId); - - if (!results.ContainsResult(result)) - results.m_results.push_back(result); -diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp -index e9cde30..ad2227a 100644 ---- a/xbmc/peripherals/devices/Peripheral.cpp -+++ b/xbmc/peripherals/devices/Peripheral.cpp -@@ -38,39 +38,23 @@ struct SortBySettingsOrder - } - }; - --CPeripheral::CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- m_type(type), -- m_busType(busType), -- m_strLocation(strLocation), -- m_strDeviceName(strDeviceName), -+CPeripheral::CPeripheral(const PeripheralScanResult& scanResult) : -+ m_type(scanResult.m_mappedType), -+ m_busType(scanResult.m_busType), -+ m_mappedBusType(scanResult.m_mappedBusType), -+ m_strLocation(scanResult.m_strLocation), -+ m_strDeviceName(scanResult.m_strDeviceName), - m_strFileLocation(StringUtils::EmptyString), -- m_iVendorId(iVendorId), -- m_iProductId(iProductId), -- m_strVersionInfo(g_localizeStrings.Get(13205)), // "unknown" -- m_bInitialised(false), -- m_bHidden(false), -- m_bError(false) --{ -- PeripheralTypeTranslator::FormatHexString(iVendorId, m_strVendorId); -- PeripheralTypeTranslator::FormatHexString(iProductId, m_strProductId); -- m_strFileLocation.Format("peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(busType), strLocation.c_str()); --} -- --CPeripheral::CPeripheral(void) : -- m_type(PERIPHERAL_UNKNOWN), -- m_busType(PERIPHERAL_BUS_UNKNOWN), -- m_strLocation(StringUtils::EmptyString), -- m_strDeviceName(StringUtils::EmptyString), -- m_strFileLocation(StringUtils::EmptyString), -- m_iVendorId(0), -- m_strVendorId("0000"), -- m_iProductId(0), -- m_strProductId("0000"), -+ m_iVendorId(scanResult.m_iVendorId), -+ m_iProductId(scanResult.m_iProductId), - m_strVersionInfo(g_localizeStrings.Get(13205)), // "unknown" - m_bInitialised(false), - m_bHidden(false), - m_bError(false) - { -+ PeripheralTypeTranslator::FormatHexString(scanResult.m_iVendorId, m_strVendorId); -+ PeripheralTypeTranslator::FormatHexString(scanResult.m_iProductId, m_strProductId); -+ m_strFileLocation.Format(scanResult.m_iSequence > 0 ? "peripherals://%s/%s_%d.dev" : "peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(scanResult.m_busType), scanResult.m_strLocation.c_str(), scanResult.m_iSequence); - } - - CPeripheral::~CPeripheral(void) -@@ -146,7 +130,7 @@ bool CPeripheral::Initialise(void) - return bReturn; - - g_peripherals.GetSettingsFromMapping(*this); -- m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_busType), m_strVendorId.c_str(), m_strProductId.c_str()); -+ m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_mappedBusType), m_strVendorId.c_str(), m_strProductId.c_str()); - LoadPersistedSettings(); - - for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++) -@@ -535,3 +519,13 @@ void CPeripheral::ClearSettings(void) - } - m_settings.clear(); - } -+ -+bool CPeripheral::operator ==(const PeripheralScanResult& right) const -+{ -+ return m_strLocation.Equals(right.m_strLocation); -+} -+ -+bool CPeripheral::operator !=(const PeripheralScanResult& right) const -+{ -+ return !(*this == right); -+} -diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h -index d42e83e..64cf64e 100644 ---- a/xbmc/peripherals/devices/Peripheral.h -+++ b/xbmc/peripherals/devices/Peripheral.h -@@ -34,12 +34,13 @@ - friend class CGUIDialogPeripheralSettings; - - public: -- CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -- CPeripheral(void); -+ CPeripheral(const PeripheralScanResult& scanResult); - virtual ~CPeripheral(void); - - bool operator ==(const CPeripheral &right) const; - bool operator !=(const CPeripheral &right) const; -+ bool operator ==(const PeripheralScanResult& right) const; -+ bool operator !=(const PeripheralScanResult& right) const; - - const CStdString &FileLocation(void) const { return m_strFileLocation; } - const CStdString &Location(void) const { return m_strLocation; } -@@ -158,6 +159,7 @@ - - PeripheralType m_type; - PeripheralBusType m_busType; -+ PeripheralBusType m_mappedBusType; - CStdString m_strLocation; - CStdString m_strDeviceName; - CStdString m_strSettingsFile; -diff --git a/xbmc/peripherals/devices/PeripheralBluetooth.cpp b/xbmc/peripherals/devices/PeripheralBluetooth.cpp -index a2f4e06..4785f7b 100644 ---- a/xbmc/peripherals/devices/PeripheralBluetooth.cpp -+++ b/xbmc/peripherals/devices/PeripheralBluetooth.cpp -@@ -23,8 +23,8 @@ - - using namespace PERIPHERALS; - --CPeripheralBluetooth::CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) -+CPeripheralBluetooth::CPeripheralBluetooth(const PeripheralScanResult& scanResult) : -+ CPeripheral(scanResult) - { - m_features.push_back(FEATURE_BLUETOOTH); - } -diff --git a/xbmc/peripherals/devices/PeripheralBluetooth.h b/xbmc/peripherals/devices/PeripheralBluetooth.h -index 6b79be9..a1be1ff 100644 ---- a/xbmc/peripherals/devices/PeripheralBluetooth.h -+++ b/xbmc/peripherals/devices/PeripheralBluetooth.h -@@ -26,7 +26,7 @@ - class CPeripheralBluetooth : public CPeripheral - { - public: -- CPeripheralBluetooth(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralBluetooth(const PeripheralScanResult& scanResult); - virtual ~CPeripheralBluetooth(void) {}; - }; - } -diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp -index e578dc3..983e1a7 100644 ---- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp -+++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp -@@ -80,14 +80,15 @@ class DllLibCEC : public DllDynamic, DllLibCECInterface - END_METHOD_RESOLVE() - }; - --CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheralHID(type, busType, strLocation, strDeviceName, iVendorId, iProductId), -+CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralScanResult& scanResult) : -+ CPeripheralHID(scanResult), - CThread("CEC Adapter"), - m_dll(NULL), - m_cecAdapter(NULL) - { - ResetMembers(); - m_features.push_back(FEATURE_CEC); -+ m_strComPort = scanResult.m_strLocation; - } - - CPeripheralCecAdapter::~CPeripheralCecAdapter(void) -@@ -98,6 +99,7 @@ class DllLibCEC : public DllDynamic, DllLibCECInterface - m_bStop = true; - } - -+ SAFE_DELETE(m_queryThread); - StopThread(true); - - if (m_dll && m_cecAdapter) -@@ -302,38 +304,6 @@ void CPeripheralCecAdapter::SetVersionInfo(const libcec_configuration &configura - } - } - --CStdString CPeripheralCecAdapter::GetComPort(void) --{ -- CStdString strPort = GetSettingString("port"); -- if (strPort.IsEmpty()) -- { -- strPort = m_strFileLocation; -- cec_adapter deviceList[10]; -- TranslateComPort(strPort); -- uint8_t iFound = m_cecAdapter->FindAdapters(deviceList, 10, strPort.c_str()); -- -- if (iFound <= 0) -- { -- CLog::Log(LOGWARNING, "%s - no CEC adapters found on %s", __FUNCTION__, strPort.c_str()); -- // display warning: couldn't set up com port -- CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36011)); -- strPort = ""; -- } -- else -- { -- cec_adapter *dev = &deviceList[0]; -- if (iFound > 1) -- CLog::Log(LOGDEBUG, "%s - multiple com ports found for device. taking the first one", __FUNCTION__); -- else -- CLog::Log(LOGDEBUG, "%s - autodetect com port '%s'", __FUNCTION__, dev->comm); -- -- strPort = dev->comm; -- } -- } -- -- return strPort; --} -- - bool CPeripheralCecAdapter::OpenConnection(void) - { - bool bIsOpen(false); -@@ -345,12 +315,8 @@ bool CPeripheralCecAdapter::OpenConnection(void) - return bIsOpen; - } - -- CStdString strPort = GetComPort(); -- if (strPort.empty()) -- return bIsOpen; -- - // open the CEC adapter -- CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, strPort.c_str()); -+ CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, m_strComPort.c_str()); - - // scanning the CEC bus takes about 5 seconds, so display a notification to inform users that we're busy - CStdString strMessage; -@@ -361,7 +327,7 @@ bool CPeripheralCecAdapter::OpenConnection(void) - - while (!m_bStop && !bIsOpen) - { -- if ((bIsOpen = m_cecAdapter->Open(strPort.c_str(), 10000)) == false) -+ if ((bIsOpen = m_cecAdapter->Open(m_strComPort.c_str(), 10000)) == false) - { - // display warning: couldn't initialise libCEC - CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__); -@@ -430,8 +396,7 @@ void CPeripheralCecAdapter::Process(void) - Sleep(5); - } - -- delete m_queryThread; -- m_queryThread = NULL; -+ SAFE_DELETE(m_queryThread); - - bool bSendStandbyCommands(false); - { -@@ -1255,8 +1220,7 @@ int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message me - - bool CPeripheralCecAdapter::TranslateComPort(CStdString &strLocation) - { -- if ((strLocation.Left(18).Equals("peripherals://usb/") || -- strLocation.Left(18).Equals("peripherals://rpi/")) && -+ if ((strLocation.Left(18).Equals("peripherals://cec/")) && - strLocation.Right(4).Equals(".dev")) - { - strLocation = strLocation.Right(strLocation.length() - 18); -diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h -index 23cd99e..c681e60 100644 ---- a/xbmc/peripherals/devices/PeripheralCecAdapter.h -+++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h -@@ -86,7 +86,7 @@ - friend class CPeripheralCecAdapterUpdateThread; - - public: -- CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralCecAdapter(const PeripheralScanResult& scanResult); - virtual ~CPeripheralCecAdapter(void); - - void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); -@@ -106,7 +106,6 @@ - int GetButton(void); - unsigned int GetHoldTime(void); - void ResetButton(void); -- CStdString GetComPort(void); - - void PushCecKeypress(const CEC::cec_keypress &key); - -@@ -171,6 +170,7 @@ - bool m_bActiveSourceBeforeStandby; - bool m_bOnPlayReceived; - bool m_bPlaybackPaused; -+ CStdString m_strComPort; - }; - - class CPeripheralCecAdapterUpdateThread : public CThread -diff --git a/xbmc/peripherals/devices/PeripheralDisk.cpp b/xbmc/peripherals/devices/PeripheralDisk.cpp -index 96d7fcf..b5507fc 100644 ---- a/xbmc/peripherals/devices/PeripheralDisk.cpp -+++ b/xbmc/peripherals/devices/PeripheralDisk.cpp -@@ -23,8 +23,9 @@ - - using namespace PERIPHERALS; - --CPeripheralDisk::CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35003) : strDeviceName, iVendorId, iProductId) -+CPeripheralDisk::CPeripheralDisk(const PeripheralScanResult& scanResult) : -+ CPeripheral(scanResult) - { -+ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35003) : scanResult.m_strDeviceName; - m_features.push_back(FEATURE_DISK); - } -diff --git a/xbmc/peripherals/devices/PeripheralDisk.h b/xbmc/peripherals/devices/PeripheralDisk.h -index 4fab920..fc44ff6 100644 ---- a/xbmc/peripherals/devices/PeripheralDisk.h -+++ b/xbmc/peripherals/devices/PeripheralDisk.h -@@ -26,7 +26,7 @@ - class CPeripheralDisk : public CPeripheral - { - public: -- CPeripheralDisk(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralDisk(const PeripheralScanResult& scanResult); - virtual ~CPeripheralDisk(void) {}; - }; - } -diff --git a/xbmc/peripherals/devices/PeripheralHID.cpp b/xbmc/peripherals/devices/PeripheralHID.cpp -index fe1f355..27152f1 100644 ---- a/xbmc/peripherals/devices/PeripheralHID.cpp -+++ b/xbmc/peripherals/devices/PeripheralHID.cpp -@@ -27,10 +27,11 @@ - using namespace PERIPHERALS; - using namespace std; - --CPeripheralHID::CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId), -+CPeripheralHID::CPeripheralHID(const PeripheralScanResult& scanResult) : -+ CPeripheral(scanResult), - m_bInitialised(false) - { -+ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : scanResult.m_strDeviceName; - m_features.push_back(FEATURE_HID); - } - -diff --git a/xbmc/peripherals/devices/PeripheralHID.h b/xbmc/peripherals/devices/PeripheralHID.h -index ac60dcf..fb8bf44 100644 ---- a/xbmc/peripherals/devices/PeripheralHID.h -+++ b/xbmc/peripherals/devices/PeripheralHID.h -@@ -27,7 +27,7 @@ - class CPeripheralHID : public CPeripheral - { - public: -- CPeripheralHID(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralHID(const PeripheralScanResult& scanResult); - virtual ~CPeripheralHID(void); - virtual bool InitialiseFeature(const PeripheralFeature feature); - virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode) { return false; } -diff --git a/xbmc/peripherals/devices/PeripheralImon.cpp b/xbmc/peripherals/devices/PeripheralImon.cpp -index 6fbbb33..b0474a1 100644 ---- a/xbmc/peripherals/devices/PeripheralImon.cpp -+++ b/xbmc/peripherals/devices/PeripheralImon.cpp -@@ -37,8 +37,8 @@ - volatile long CPeripheralImon::m_lCountOfImonsConflictWithDInput = 0; - - --CPeripheralImon::CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheralHID(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35001) : strDeviceName, iVendorId, iProductId) -+CPeripheralImon::CPeripheralImon(const PeripheralScanResult& scanResult) : -+ CPeripheralHID(scanResult) - { - m_features.push_back(FEATURE_IMON); - m_bImonConflictsWithDInput = false; -diff --git a/xbmc/peripherals/devices/PeripheralImon.h b/xbmc/peripherals/devices/PeripheralImon.h -index 8444906..87905b4 100644 ---- a/xbmc/peripherals/devices/PeripheralImon.h -+++ b/xbmc/peripherals/devices/PeripheralImon.h -@@ -26,7 +26,7 @@ - class CPeripheralImon : public CPeripheralHID - { - public: -- CPeripheralImon(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralImon(const PeripheralScanResult& scanResult); - virtual ~CPeripheralImon(void) {} - virtual bool InitialiseFeature(const PeripheralFeature feature); - virtual void OnSettingChanged(const CStdString &strChangedSetting); -diff --git a/xbmc/peripherals/devices/PeripheralNIC.cpp b/xbmc/peripherals/devices/PeripheralNIC.cpp -index 747c2f7..ee950e8 100644 ---- a/xbmc/peripherals/devices/PeripheralNIC.cpp -+++ b/xbmc/peripherals/devices/PeripheralNIC.cpp -@@ -25,8 +25,9 @@ - using namespace PERIPHERALS; - using namespace std; - --CPeripheralNIC::CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheral(type, busType, strLocation, strDeviceName.IsEmpty() ? g_localizeStrings.Get(35002) : strDeviceName, iVendorId, iProductId) -+CPeripheralNIC::CPeripheralNIC(const PeripheralScanResult& scanResult) : -+ CPeripheral(scanResult) - { -+ m_strDeviceName = scanResult.m_strDeviceName.IsEmpty() ? g_localizeStrings.Get(35002) : scanResult.m_strDeviceName; - m_features.push_back(FEATURE_NIC); - } -diff --git a/xbmc/peripherals/devices/PeripheralNIC.h b/xbmc/peripherals/devices/PeripheralNIC.h -index 49abc2b..fc12302 100644 ---- a/xbmc/peripherals/devices/PeripheralNIC.h -+++ b/xbmc/peripherals/devices/PeripheralNIC.h -@@ -26,7 +26,7 @@ - class CPeripheralNIC : public CPeripheral - { - public: -- CPeripheralNIC(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralNIC(const PeripheralScanResult& scanResult); - virtual ~CPeripheralNIC(void) {}; - }; - } -diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.cpp b/xbmc/peripherals/devices/PeripheralNyxboard.cpp -index 5e3f649..df9c290 100644 ---- a/xbmc/peripherals/devices/PeripheralNyxboard.cpp -+++ b/xbmc/peripherals/devices/PeripheralNyxboard.cpp -@@ -27,8 +27,8 @@ - using namespace PERIPHERALS; - using namespace std; - --CPeripheralNyxboard::CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheralHID(type, busType, strLocation, strDeviceName, iVendorId, iProductId) -+CPeripheralNyxboard::CPeripheralNyxboard(const PeripheralScanResult& scanResult) : -+ CPeripheralHID(scanResult) - { - m_features.push_back(FEATURE_NYXBOARD); - } -diff --git a/xbmc/peripherals/devices/PeripheralNyxboard.h b/xbmc/peripherals/devices/PeripheralNyxboard.h -index 346d555..254c6c6 100644 ---- a/xbmc/peripherals/devices/PeripheralNyxboard.h -+++ b/xbmc/peripherals/devices/PeripheralNyxboard.h -@@ -26,7 +26,7 @@ - class CPeripheralNyxboard : public CPeripheralHID - { - public: -- CPeripheralNyxboard(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralNyxboard(const PeripheralScanResult& scanResult); - virtual ~CPeripheralNyxboard(void) {}; - virtual bool LookupSymAndUnicode(XBMC_keysym &keysym, uint8_t *key, char *unicode); - }; -diff --git a/xbmc/peripherals/devices/PeripheralTuner.cpp b/xbmc/peripherals/devices/PeripheralTuner.cpp -index ef5630c..8937598 100644 ---- a/xbmc/peripherals/devices/PeripheralTuner.cpp -+++ b/xbmc/peripherals/devices/PeripheralTuner.cpp -@@ -23,8 +23,8 @@ - - using namespace PERIPHERALS; - --CPeripheralTuner::CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) : -- CPeripheral(type, busType, strLocation, strDeviceName, iVendorId, iProductId) -+CPeripheralTuner::CPeripheralTuner(const PeripheralScanResult& scanResult) : -+ CPeripheral(scanResult) - { - m_features.push_back(FEATURE_TUNER); - } -diff --git a/xbmc/peripherals/devices/PeripheralTuner.h b/xbmc/peripherals/devices/PeripheralTuner.h -index b4b15f8..7130130 100644 ---- a/xbmc/peripherals/devices/PeripheralTuner.h -+++ b/xbmc/peripherals/devices/PeripheralTuner.h -@@ -26,7 +26,7 @@ - class CPeripheralTuner : public CPeripheral - { - public: -- CPeripheralTuner(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId); -+ CPeripheralTuner(const PeripheralScanResult& scanResult); - virtual ~CPeripheralTuner(void) {}; - }; - } --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch b/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch deleted file mode 100644 index b757a9fb23..0000000000 --- a/packages/mediacenter/xbmc/patches/xbmc-990.30-PR2252.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 80a8ad68567f89b3f6810c07daaf42d2edddee87 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 Feb 2013 23:49:43 +0000 -Subject: [PATCH] [rbp] Fix for audiotoggledigital on Pi. - -Pi only has two audio output modes so the three way toggle gets stuck. This fix corresponds to Pi specific settings code: -https://github.com/xbmc/xbmc/blob/master/xbmc/settings/GUISettings.cpp#L458 ---- - xbmc/Application.cpp | 12 ++++++++---- - xbmc/settings/GUISettings.h | 1 + - 2 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index d6e663b..5e9d979 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2863,11 +2863,15 @@ bool CApplication::OnAction(const CAction &action) - - if (action.GetID() == ACTION_TOGGLE_DIGITAL_ANALOG) - { -- switch(g_guiSettings.GetInt("audiooutput.mode")) -+ // we are only allowed to SetInt to a value supported in GUISettings, so we keep trying until it sticks -+ int mode = g_guiSettings.GetInt("audiooutput.mode"); -+ for (int i = 0; i < AUDIO_COUNT; i++) - { -- case AUDIO_ANALOG: g_guiSettings.SetInt("audiooutput.mode", AUDIO_IEC958); break; -- case AUDIO_IEC958: g_guiSettings.SetInt("audiooutput.mode", AUDIO_HDMI ); break; -- case AUDIO_HDMI : g_guiSettings.SetInt("audiooutput.mode", AUDIO_ANALOG); break; -+ if (++mode == AUDIO_COUNT) -+ mode = 0; -+ g_guiSettings.SetInt("audiooutput.mode", mode); -+ if (g_guiSettings.GetInt("audiooutput.mode") == mode) -+ break; - } - - g_application.Restart(); -diff --git a/xbmc/settings/GUISettings.h b/xbmc/settings/GUISettings.h -index b48ba35..98f9836 100644 ---- a/xbmc/settings/GUISettings.h -+++ b/xbmc/settings/GUISettings.h -@@ -84,6 +84,7 @@ - #define AUDIO_ANALOG 0 - #define AUDIO_IEC958 1 - #define AUDIO_HDMI 2 -+#define AUDIO_COUNT 3 - #define AUDIO_IS_BITSTREAM(x) ((x) == AUDIO_IEC958 || (x) == AUDIO_HDMI) - - #define VIDEO_NORMAL 0 --- -1.7.10 - diff --git a/tools/mkpkg/mkpkg_xbmc-frodo b/tools/mkpkg/mkpkg_xbmc-frodo index 2a4bd460e8..8109893465 100755 --- a/tools/mkpkg/mkpkg_xbmc-frodo +++ b/tools/mkpkg/mkpkg_xbmc-frodo @@ -20,7 +20,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="12.0.4" +PKG_VERSION="12.0.5" GIT_REPO="-b Frodo git://github.com/xbmc/xbmc.git" DEST_DIR="$PKG_NAME-frodo"