From ad9c750f571143a85b6e22b7f0a9e90c8313a74d Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sat, 20 Jul 2013 20:52:23 +0200 Subject: [PATCH] xbmc (frodo): switch to own repo Signed-off-by: Stephan Raue --- .../mediacenter/xbmc-theme-Confluence/meta | 2 +- packages/mediacenter/xbmc/meta | 2 +- .../todo}/xbmc-990.26.01-PR2890.patch | 0 .../todo}/xbmc-990.26.02-PR2890.patch | 0 .../todo}/xbmc-990.26.03-PR2890.patch | 0 .../todo}/xbmc-990.26.04-PR2890.patch | 0 .../todo/xbmc-990.27-PR2232.patch.bk | 746 + ...x_incorrect_usage_of_flag_talled.patch.bk} | 0 ...layer-some_caching_fixes_for_pvr.patch.bk} | 0 ...1-texturepacker-hostflags-and-rework.patch | 0 ...HONOPTIMIZE_with_external_Python-0.1.patch | 0 .../xbmc-452-change_lcd_content-0.1.patch | 0 ...bmc-453-add_openelec.tv_RSS_news-0.1.patch | 0 ...-990.00-remove-windowed-display-mode.patch | 0 ...nfsdeinit-and-wait-for-nic-on-wakeup.patch | 0 ...xbmc-995.11-enable-vpp-deinterlacing.patch | 0 ....12-enable-vpp-fix-audio-out-of-sync.patch | 0 .../xbmc-995.13-vpp-fix-skipping.patch | 0 ...free_unused_textures_after_a_flip.patch.bk | 29 - .../patches/12.2.0/xbmc-990.01-PR1934.patch | 55 - .../patches/12.2.0/xbmc-990.02-PR2193.patch | 88 - .../patches/12.2.0/xbmc-990.03-PR2449-1.patch | 26 - .../patches/12.2.0/xbmc-990.04-PR2231.patch | 138 - .../12.2.0/xbmc-990.05-PR2403-01.patch | 94 - ...0.06-add-builtin-to-set-GUI-Language.patch | 32 - .../patches/12.2.0/xbmc-990.07-PR2435.patch | 184 - .../patches/12.2.0/xbmc-990.08-PR2637.patch | 60 - .../patches/12.2.0/xbmc-990.09-PR2686.patch | 32 - .../patches/12.2.0/xbmc-990.10-PR2713.patch | 331 - .../patches/12.2.0/xbmc-990.11-PR2712.patch | 77 - .../patches/12.2.0/xbmc-990.12-PR2570.patch | 89 - .../patches/12.2.0/xbmc-990.12-PR2586.patch | 555 - ...ix_for_hang_following_seek_after_eos.patch | 32 - .../12.2.0/xbmc-990.14-PR2700.patch.bk | 322 - ...s-mark_our_wrapped_functions_as_used.patch | 456 - .../12.2.0/xbmc-990.16-XB822abd9.patch | 25 - .../12.2.0/xbmc-990.17.01-XB67fbfc5.patch | 43 - .../12.2.0/xbmc-990.17.02-XBef82d9b.patch | 41 - .../12.2.0/xbmc-990.17.03-XB07c1ed5.patch | 44 - .../12.2.0/xbmc-990.17.04-XB01480bb.patch | 26 - .../12.2.0/xbmc-990.17.05-XBff283b0.patch | 29 - .../12.2.0/xbmc-990.17.06-XB937e565.patch | 45 - .../patches/12.2.0/xbmc-990.18-2758.patch.bk | 28 - .../patches/12.2.0/xbmc-990.19-PR2761.patch | 85 - .../12.2.0/xbmc-990.20-XB812a890.patch | 27 - .../12.2.0/xbmc-990.21-XB2e18d81.patch | 28 - .../12.2.0/xbmc-990.22-XB3e58f24.patch | 300 - .../patches/12.2.0/xbmc-990.23-PR2861.patch | 26 - .../12.2.0/xbmc-990.25-XB21eb522.patch | 13 - .../xbmc-995.01-xvba_support-cc55dcb.patch | 21656 ---------------- .../12.2.0/xbmc-995.10-disable-alt-tab.patch | 12 - ...2-xbmc-revert-799d6ff03-setwakeup.sh.patch | 27 - ...add_as.xml_busy_dialog_delay_control.patch | 57 - ...97.01-audio-engine-fix-buffer-access.patch | 746 - tools/mkpkg/mkpkg_xbmc-frodo-oe | 81 + 55 files changed, 829 insertions(+), 25860 deletions(-) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b/todo}/xbmc-990.26.01-PR2890.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b/todo}/xbmc-990.26.02-PR2890.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b/todo}/xbmc-990.26.03-PR2890.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b/todo}/xbmc-990.26.04-PR2890.patch (100%) create mode 100644 packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.27-PR2232.patch.bk rename packages/mediacenter/xbmc/patches/{12.2.0/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch => 12.2-9064b9b/todo/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch.bk} (100%) rename packages/mediacenter/xbmc/patches/{12.2.0/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch => 12.2-9064b9b/todo/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch.bk} (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-321-texturepacker-hostflags-and-rework.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-452-change_lcd_content-0.1.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-453-add_openelec.tv_RSS_news-0.1.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-990.00-remove-windowed-display-mode.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-990.24-smbnfsdeinit-and-wait-for-nic-on-wakeup.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-995.11-enable-vpp-deinterlacing.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-995.12-enable-vpp-fix-audio-out-of-sync.patch (100%) rename packages/mediacenter/xbmc/patches/{12.2.0 => 12.2-9064b9b}/xbmc-995.13-vpp-fix-skipping.patch (100%) delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/todo/xbmc-995.02-only_free_unused_textures_after_a_flip.patch.bk delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.01-PR1934.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.02-PR2193.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.03-PR2449-1.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.04-PR2231.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.05-PR2403-01.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.06-add-builtin-to-set-GUI-Language.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.07-PR2435.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.08-PR2637.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.09-PR2686.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.10-PR2713.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.11-PR2712.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2586.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.13-RPB-Fix_for_hang_following_seek_after_eos.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.14-PR2700.patch.bk delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.16-XB822abd9.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.01-XB67fbfc5.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.02-XBef82d9b.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.03-XB07c1ed5.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.04-XB01480bb.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.05-XBff283b0.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.06-XB937e565.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.18-2758.patch.bk delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.19-PR2761.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.20-XB812a890.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.21-XB2e18d81.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.22-XB3e58f24.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.23-PR2861.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.25-XB21eb522.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.01-xvba_support-cc55dcb.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.10-disable-alt-tab.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.02-xbmc-revert-799d6ff03-setwakeup.sh.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.03-add_as.xml_busy_dialog_delay_control.patch delete mode 100644 packages/mediacenter/xbmc/patches/12.2.0/xbmc-997.01-audio-engine-fix-buffer-access.patch create mode 100755 tools/mkpkg/mkpkg_xbmc-frodo-oe diff --git a/packages/mediacenter/xbmc-theme-Confluence/meta b/packages/mediacenter/xbmc-theme-Confluence/meta index 8a7de7974..e87473e5c 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.2.0" +PKG_VERSION="12.2-9064b9b" if [ "$XBMC" = "master" ]; then PKG_VERSION="c218d5c" elif [ "$XBMC" = "xbmc-aml" ]; then diff --git a/packages/mediacenter/xbmc/meta b/packages/mediacenter/xbmc/meta index d2035628b..05449ddbf 100644 --- a/packages/mediacenter/xbmc/meta +++ b/packages/mediacenter/xbmc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="12.2.0" +PKG_VERSION="12.2-9064b9b" if [ "$XBMC" = "master" ]; then PKG_VERSION="c218d5c" elif [ "$XBMC" = "xbmc-aml" ]; then diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.01-PR2890.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.01-PR2890.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.01-PR2890.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.01-PR2890.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.02-PR2890.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.02-PR2890.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.02-PR2890.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.02-PR2890.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.03-PR2890.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.03-PR2890.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.03-PR2890.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.03-PR2890.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.04-PR2890.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.04-PR2890.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.26.04-PR2890.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.26.04-PR2890.patch diff --git a/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.27-PR2232.patch.bk b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.27-PR2232.patch.bk new file mode 100644 index 000000000..fff3c4477 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-990.27-PR2232.patch.bk @@ -0,0 +1,746 @@ +From 1a93a46fe38c926ccd7658ce6f8c827d0491c117 Mon Sep 17 00:00:00 2001 +From: stupid-boy +Date: Wed, 13 Feb 2013 23:47:07 +0200 +Subject: [PATCH 1/2] [OMXPlayer] Both HDMI and Analog output + +--- + xbmc/cores/omxplayer/OMXAudio.cpp | 407 +++++++++++++++++++++++++------- + xbmc/cores/omxplayer/OMXAudio.h | 12 +- + xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 9 +- + xbmc/settings/GUISettings.cpp | 2 + + xbmc/settings/GUISettings.h | 3 + + 5 files changed, 341 insertions(+), 92 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp +index 10c3329..1470685 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.cpp ++++ b/xbmc/cores/omxplayer/OMXAudio.cpp +@@ -111,8 +111,7 @@ + m_eEncoding (OMX_AUDIO_CodingPCM), + m_extradata (NULL ), + m_extrasize (0 ), +- m_last_pts (DVD_NOPTS_VALUE), +- m_omx_render (NULL ) ++ m_last_pts (DVD_NOPTS_VALUE) + { + m_vizBufferSize = m_vizRemapBufferSize = VIS_PACKET_SIZE * sizeof(float); + m_vizRemapBuffer = (uint8_t *)_aligned_malloc(m_vizRemapBufferSize,16); +@@ -161,7 +160,7 @@ CAEChannelInfo COMXAudio::GetChannelLayout(AEAudioFormat format) + return info; + } + +-bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode) ++bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode) + { + Deinitialize(); + +@@ -320,32 +319,62 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * + + componentName = "OMX.broadcom.audio_render"; + +- if(!m_omx_render) +- m_omx_render = new COMXCoreComponent(); +- if(!m_omx_render) ++ std::string device = ""; ++ ++ if((g_guiSettings.GetInt("audiooutput.mode") == AUDIO_HDMI) || ++ (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_BOTH)) + { +- CLog::Log(LOGERROR, "COMXAudio::Initialize error allocate OMX.broadcom.audio_render\n"); +- return false; ++ device = "hdmi"; ++ if(!m_omx_render_HDMI.Initialize((const std::string)componentName, OMX_IndexParamAudioInit)) ++ return false; ++ ++ OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest; ++ OMX_INIT_STRUCTURE(audioDest); ++ strncpy((char *)audioDest.sName, device.c_str(), strlen(device.c_str())); ++ ++ omx_err = m_omx_render_HDMI.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); ++ if (omx_err != OMX_ErrorNone) ++ return false; ++ ++ OMX_CONFIG_BOOLEANTYPE configBool; ++ OMX_INIT_STRUCTURE(configBool); ++ configBool.bEnabled = OMX_FALSE; ++ ++ omx_err = m_omx_render_HDMI.SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool); ++ if (omx_err != OMX_ErrorNone) ++ return false; + } + +- if(!m_omx_render->Initialize((const std::string)componentName, OMX_IndexParamAudioInit)) +- return false; ++ if((g_guiSettings.GetInt("audiooutput.mode") == AUDIO_ANALOG) || ++ (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_BOTH)) ++ { ++ device = "local"; ++ if(!m_omx_render_analog.Initialize((const std::string)componentName, OMX_IndexParamAudioInit)) ++ return false; + +- OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest; +- OMX_INIT_STRUCTURE(audioDest); +- strncpy((char *)audioDest.sName, device.c_str(), strlen(device.c_str())); ++ OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest; ++ OMX_INIT_STRUCTURE(audioDest); ++ strncpy((char *)audioDest.sName, device.c_str(), strlen(device.c_str())); + +- omx_err = m_omx_render->SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); +- if (omx_err != OMX_ErrorNone) +- return false; ++ omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest); ++ if (omx_err != OMX_ErrorNone) ++ return false; + +- OMX_CONFIG_BOOLEANTYPE configBool; +- OMX_INIT_STRUCTURE(configBool); +- configBool.bEnabled = OMX_FALSE; ++ OMX_CONFIG_BOOLEANTYPE configBool; ++ OMX_INIT_STRUCTURE(configBool); ++ configBool.bEnabled = OMX_FALSE; + +- omx_err = m_omx_render->SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool); +- if (omx_err != OMX_ErrorNone) +- return false; ++ omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool); ++ if (omx_err != OMX_ErrorNone) ++ return false; ++ } ++ ++ if(g_guiSettings.GetInt("audiooutput.mode") == AUDIO_BOTH) ++ { ++ componentName = "OMX.broadcom.audio_splitter"; ++ if(!m_omx_splitter.Initialize((const std::string)componentName, OMX_IndexParamAudioInit)) ++ return false; ++ } + + componentName = "OMX.broadcom.audio_decode"; + if(!m_omx_decoder.Initialize((const std::string)componentName, OMX_IndexParamAudioInit)) +@@ -411,13 +440,30 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * + } + } + +- m_omx_tunnel_clock.Initialize(m_omx_clock, m_omx_clock->GetInputPort(), m_omx_render, m_omx_render->GetInputPort()+1); ++ if( m_omx_render_analog.IsInitialized()) ++ { ++ m_omx_tunnel_clock_analog.Initialize(m_omx_clock, m_omx_clock->GetInputPort(), ++ &m_omx_render_analog, m_omx_render_analog.GetInputPort()+1); + +- omx_err = m_omx_tunnel_clock.Establish(false); +- if(omx_err != OMX_ErrorNone) ++ omx_err = m_omx_tunnel_clock_analog.Establish(false, true); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize m_omx_tunnel_clock_analog.Establish\n"); ++ return false; ++ } ++ } ++ ++ if( m_omx_render_HDMI.IsInitialized()) + { +- CLog::Log(LOGERROR, "COMXAudio::Initialize m_omx_tunnel_clock.Establish\n"); +- return false; ++ m_omx_tunnel_clock_HDMI.Initialize(m_omx_clock, m_omx_clock->GetInputPort()+ ( m_omx_render_analog.IsInitialized() ? 2 : 0), ++ &m_omx_render_HDMI, m_omx_render_HDMI.GetInputPort()+1); ++ ++ omx_err = m_omx_tunnel_clock_HDMI.Establish(false, true); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize m_omx_tunnel_clock_HDMI.Establish\n"); ++ return false; ++ } + } + + omx_err = m_omx_decoder.AllocInputBuffers(); +@@ -443,12 +489,56 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * + return false; + } + +- m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), m_omx_render, m_omx_render->GetInputPort()); +- omx_err = m_omx_tunnel_mixer.Establish(false); +- if(omx_err != OMX_ErrorNone) ++ if(g_guiSettings.GetInt("audiooutput.mode") == AUDIO_ANALOG) + { +- CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_decoder.Establish 0x%08x", omx_err); +- return false; ++ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), ++ &m_omx_render_analog, m_omx_render_analog.GetInputPort()); ++ omx_err = m_omx_tunnel_mixer.Establish(false); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_decoder.Establish 0x%08x", omx_err); ++ return false; ++ } ++ } ++ else if (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_HDMI) ++ { ++ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), ++ &m_omx_render_HDMI, m_omx_render_HDMI.GetInputPort()); ++ omx_err = m_omx_tunnel_mixer.Establish(false); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_decoder.Establish 0x%08x", omx_err); ++ return false; ++ } ++ } ++ else // AUDIO_BOTH ++ { ++ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), ++ &m_omx_splitter, m_omx_splitter.GetInputPort()); ++ omx_err = m_omx_tunnel_mixer.Establish(false); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_mixer.Establish 0x%08x", omx_err); ++ return false; ++ } ++ ++ m_omx_tunnel_splitter_analog.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort(), ++ &m_omx_render_analog, m_omx_render_analog.GetInputPort()); ++ omx_err = m_omx_tunnel_splitter_analog.Establish(false); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_analog.Establish 0x%08x", omx_err); ++ return false; ++ } ++ ++ m_omx_tunnel_splitter_HDMI.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort() + 1, ++ &m_omx_render_HDMI, m_omx_render_HDMI.GetInputPort()); ++ omx_err = m_omx_tunnel_splitter_HDMI.Establish(false); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_HDMI.Establish 0x%08x", omx_err); ++ return false; ++ } + } + + omx_err = m_omx_mixer.SetStateForComponent(OMX_StateExecuting); +@@ -459,7 +549,9 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * + } + else + { +- m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), m_omx_render, m_omx_render->GetInputPort()); ++ // Passthrough work only for HDMI ++ m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), ++ &m_omx_render_HDMI, m_omx_render_HDMI.GetInputPort()); + omx_err = m_omx_tunnel_decoder.Establish(false); + if(omx_err != OMX_ErrorNone) + { +@@ -474,11 +566,34 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * + } + } + +- omx_err = m_omx_render->SetStateForComponent(OMX_StateExecuting); +- if(omx_err != OMX_ErrorNone) ++ if ( m_omx_splitter.IsInitialized()) + { +- CLog::Log(LOGERROR, "COMXAudio::Initialize - Error setting OMX_StateExecuting 0x%08x", omx_err); +- return false; ++ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error setting OMX_StateExecuting 0x%08x for m_omx_splitter", omx_err); ++ return false; ++ } ++ } ++ ++ if ( m_omx_render_analog.IsInitialized()) ++ { ++ omx_err = m_omx_render_analog.SetStateForComponent(OMX_StateExecuting); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error setting OMX_StateExecuting 0x%08x for m_omx_render_analog", omx_err); ++ return false; ++ } ++ } ++ ++ if ( m_omx_render_HDMI.IsInitialized()) ++ { ++ omx_err = m_omx_render_HDMI.SetStateForComponent(OMX_StateExecuting); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error setting OMX_StateExecuting 0x%08x for m_omx_render_HDMI", omx_err); ++ return false; ++ } + } + + m_omx_decoder.EnablePort(m_omx_decoder.GetInputPort(), true); +@@ -570,9 +685,12 @@ bool COMXAudio::Deinitialize() + m_omx_tunnel_decoder.Flush(); + if(!m_Passthrough) + m_omx_tunnel_mixer.Flush(); +- m_omx_tunnel_clock.Flush(); + +- m_omx_tunnel_clock.Deestablish(); ++ m_omx_tunnel_clock_analog.Flush(); ++ m_omx_tunnel_clock_HDMI.Flush(); ++ m_omx_tunnel_clock_analog.Deestablish(); ++ m_omx_tunnel_clock_HDMI.Deestablish(); ++ + if(!m_Passthrough) + { + // workaround for the strange BCM mixer component +@@ -587,8 +705,16 @@ bool COMXAudio::Deinitialize() + + m_omx_decoder.FlushInput(); + +- if(m_omx_render) +- m_omx_render->Deinitialize(true); ++ m_omx_tunnel_splitter_analog.Flush(); ++ m_omx_tunnel_splitter_analog.Deestablish(true); ++ m_omx_tunnel_splitter_HDMI.Flush(); ++ m_omx_tunnel_splitter_HDMI.Deestablish(true); ++ ++ m_omx_splitter.Deinitialize(true); ++ ++ m_omx_render_analog.Deinitialize(true); ++ m_omx_render_HDMI.Deinitialize(true); ++ + if(!m_Passthrough) + m_omx_mixer.Deinitialize(true); + m_omx_decoder.Deinitialize(true); +@@ -613,9 +739,6 @@ bool COMXAudio::Deinitialize() + m_first_frame = true; + m_last_pts = DVD_NOPTS_VALUE; + +- delete m_omx_render; +- m_omx_render = NULL; +- + return true; + } + +@@ -696,7 +819,7 @@ void COMXAudio::Mute(bool bMute) + //*********************************************************************************************** + bool COMXAudio::SetCurrentVolume(float fVolume) + { +- CSingleLock lock (m_critSection); ++CSingleLock lock (m_critSection); + + if(!m_Initialized || m_Passthrough) + return false; +@@ -754,22 +877,39 @@ bool COMXAudio::SetCurrentVolume(float fVolume) + { + OMX_AUDIO_CONFIG_VOLUMETYPE volume; + OMX_INIT_STRUCTURE(volume); +- volume.nPortIndex = m_omx_render->GetInputPort(); ++ OMX_ERRORTYPE omx_err; + + volume.bLinear = OMX_TRUE; + float hardwareVolume = fVolume * gain * 100.0f; + volume.sVolume.nValue = (int)(hardwareVolume + 0.5f); + +- OMX_ERRORTYPE omx_err = +- m_omx_render->SetConfig(OMX_IndexConfigAudioVolume, &volume); +- if(omx_err != OMX_ErrorNone) ++ if(m_omx_render_analog.IsInitialized()) + { +- CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x\n", ++ volume.nPortIndex = m_omx_render_analog.GetInputPort(); ++ omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigAudioVolume, &volume); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x for m_omx_render_analog\n", + CLASSNAME, __func__, omx_err); +- return false; ++ return false; ++ } ++ } ++ if(m_omx_render_HDMI.IsInitialized()) ++ { ++ volume.nPortIndex = m_omx_render_HDMI.GetInputPort(); ++ omx_err = m_omx_render_HDMI.SetConfig(OMX_IndexConfigAudioVolume, &volume); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x for m_omx_render_HDMI\n", ++ CLASSNAME, __func__, omx_err); ++ return false; ++ } + } ++ + } + return true; ++ ++ return true; + } + + +@@ -927,7 +1067,18 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + m_first_frame = false; + //m_omx_render.WaitForEvent(OMX_EventPortSettingsChanged); + +- m_omx_render->DisablePort(m_omx_render->GetInputPort(), false); ++ if(m_omx_render_analog.IsInitialized()) ++ m_omx_render_analog.DisablePort(m_omx_render_analog.GetInputPort(), false); ++ if(m_omx_render_HDMI.IsInitialized()) ++ m_omx_render_HDMI.DisablePort(m_omx_render_HDMI.GetInputPort(), false); ++ ++ if(m_omx_splitter.IsInitialized()) ++ { ++ m_omx_splitter.DisablePort(m_omx_splitter.GetOutputPort(), false); ++ m_omx_splitter.DisablePort(m_omx_splitter.GetOutputPort()+1, false); ++ m_omx_splitter.DisablePort(m_omx_splitter.GetInputPort(), false); ++ } ++ + if(!m_Passthrough) + { + m_omx_mixer.DisablePort(m_omx_mixer.GetOutputPort(), false); +@@ -965,6 +1116,11 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + } + + m_pcm_output.nSamplingRate = m_format.m_sampleRate; ++ // "Currently this component only supports raw PCM on all audio ports." ++ if(m_omx_splitter.IsInitialized()) ++ { ++ m_pcm_output.ePCMMode = OMX_AUDIO_PCMModeLinear; ++ } + + /* setup mixer output */ + m_pcm_output.nPortIndex = m_omx_mixer.GetOutputPort(); +@@ -981,16 +1137,64 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + + m_pcm_output.nSamplingRate = m_format.m_sampleRate; + +- m_pcm_output.nPortIndex = m_omx_render->GetInputPort(); +- omx_err = m_omx_render->SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); +- if(omx_err != OMX_ErrorNone) ++ if(m_omx_splitter.IsInitialized()) + { +- CLog::Log(LOGERROR, "COMXAudio::AddPackets error SetParameter 1 render omx_err(0x%08x)\n", omx_err); ++ m_pcm_output.nPortIndex = m_omx_splitter.GetInputPort(); ++ omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets error SetParameter 1 omx_err(0x%08x) for m_omx_splitter\n", omx_err); ++ } ++ ++ ++ // Splitter will copy input params to output when input port is enabled. ++ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateIdle); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets - Error setting OMX_StateIdle 0x%08x for m_omx_splitter", omx_err); ++ return false; ++ } ++ ++ m_omx_splitter.EnablePort(m_omx_splitter.GetInputPort(), false); ++ m_omx_splitter.DisablePort(m_omx_splitter.GetInputPort(), false); ++ ++ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets - Error setting OMX_StateExecuting 0x%08x for m_omx_splitter", omx_err); ++ return false; ++ } ++ ++ m_pcm_output.nPortIndex = m_omx_splitter.GetOutputPort(); ++ omx_err = m_omx_splitter.GetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets error GetParameter 3 omx_err(0x%08x) for m_omx_splitter\n", omx_err); ++ } ++ ++ m_pcm_output.nSamplingRate = m_format.m_sampleRate; + } +- omx_err = m_omx_render->GetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); +- if(omx_err != OMX_ErrorNone) ++ ++ if(m_omx_render_analog.IsInitialized()) ++ { ++ m_pcm_output.nPortIndex = m_omx_render_analog.GetInputPort(); ++ omx_err = m_omx_render_analog.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets error SetParameter 1 render omx_err(0x%08x) for m_omx_render_analog\n", omx_err); ++ } ++ ++ } ++ ++ if(m_omx_render_HDMI.IsInitialized()) + { +- CLog::Log(LOGERROR, "COMXAudio::AddPackets error GetParameter 2 render omx_err(0x%08x)\n", omx_err); ++ m_pcm_output.nPortIndex = m_omx_render_HDMI.GetInputPort(); ++ omx_err = m_omx_render_HDMI.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "COMXAudio::AddPackets error SetParameter 1 render omx_err(0x%08x) for m_omx_render_HDMI\n", omx_err); ++ } ++ + } + + PrintPCM(&m_pcm_input, std::string("input")); +@@ -1000,9 +1204,9 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + { + OMX_AUDIO_PARAM_PORTFORMATTYPE formatType; + OMX_INIT_STRUCTURE(formatType); +- formatType.nPortIndex = m_omx_render->GetInputPort(); ++ formatType.nPortIndex = m_omx_render_HDMI.GetInputPort(); + +- omx_err = m_omx_render->GetParameter(OMX_IndexParamAudioPortFormat, &formatType); ++ omx_err = m_omx_render_HDMI.GetParameter(OMX_IndexParamAudioPortFormat, &formatType); + if(omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXAudio::AddPackets error OMX_IndexParamAudioPortFormat omx_err(0x%08x)\n", omx_err); +@@ -1011,7 +1215,7 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + + formatType.eEncoding = m_eEncoding; + +- omx_err = m_omx_render->SetParameter(OMX_IndexParamAudioPortFormat, &formatType); ++ omx_err = m_omx_render_HDMI.SetParameter(OMX_IndexParamAudioPortFormat, &formatType); + if(omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXAudio::AddPackets error OMX_IndexParamAudioPortFormat omx_err(0x%08x)\n", omx_err); +@@ -1023,7 +1227,7 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + OMX_AUDIO_PARAM_DDPTYPE m_ddParam; + OMX_INIT_STRUCTURE(m_ddParam); + +- m_ddParam.nPortIndex = m_omx_render->GetInputPort(); ++ m_ddParam.nPortIndex = m_omx_render_HDMI.GetInputPort(); + + m_ddParam.nChannels = m_format.m_channelLayout.Count(); //(m_InputChannels == 6) ? 8 : m_InputChannels; + m_ddParam.nSampleRate = m_SampleRate; +@@ -1038,13 +1242,13 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + m_ddParam.eChannelMapping[i] = OMXChannels[i]; + } + +- m_omx_render->SetParameter(OMX_IndexParamAudioDdp, &m_ddParam); +- m_omx_render->GetParameter(OMX_IndexParamAudioDdp, &m_ddParam); ++ m_omx_render_HDMI.SetParameter(OMX_IndexParamAudioDdp, &m_ddParam); ++ m_omx_render_HDMI.GetParameter(OMX_IndexParamAudioDdp, &m_ddParam); + PrintDDP(&m_ddParam); + } + else if(m_eEncoding == OMX_AUDIO_CodingDTS) + { +- m_dtsParam.nPortIndex = m_omx_render->GetInputPort(); ++ m_dtsParam.nPortIndex = m_omx_render_HDMI.GetInputPort(); + + m_dtsParam.nChannels = m_format.m_channelLayout.Count(); //(m_InputChannels == 6) ? 8 : m_InputChannels; + m_dtsParam.nBitRate = 0; +@@ -1057,13 +1261,24 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt + m_dtsParam.eChannelMapping[i] = OMXChannels[i]; + } + +- m_omx_render->SetParameter(OMX_IndexParamAudioDts, &m_dtsParam); +- m_omx_render->GetParameter(OMX_IndexParamAudioDts, &m_dtsParam); ++ m_omx_render_HDMI.SetParameter(OMX_IndexParamAudioDts, &m_dtsParam); ++ m_omx_render_HDMI.GetParameter(OMX_IndexParamAudioDts, &m_dtsParam); + PrintDTS(&m_dtsParam); + } + } + +- m_omx_render->EnablePort(m_omx_render->GetInputPort(), false); ++ if(m_omx_render_analog.IsInitialized()) ++ m_omx_render_analog.EnablePort(m_omx_render_analog.GetInputPort(), false); ++ if(m_omx_render_HDMI.IsInitialized()) ++ m_omx_render_HDMI.EnablePort(m_omx_render_HDMI.GetInputPort(), false); ++ ++ if(m_omx_splitter.IsInitialized()) ++ { ++ m_omx_splitter.EnablePort(m_omx_splitter.GetOutputPort(), false); ++ m_omx_splitter.EnablePort(m_omx_splitter.GetOutputPort()+1, false); ++ m_omx_splitter.EnablePort(m_omx_splitter.GetInputPort(), false); ++ } ++ + if(!m_Passthrough) + { + m_omx_mixer.EnablePort(m_omx_mixer.GetOutputPort(), false); +@@ -1139,21 +1354,49 @@ unsigned int COMXAudio::GetAudioRenderingLatency() + if(!m_Initialized) + return 0; + +- OMX_PARAM_U32TYPE param; +- OMX_INIT_STRUCTURE(param); +- param.nPortIndex = m_omx_render->GetInputPort(); ++ unsigned int latAnalog = 0; ++ unsigned int latHDMI = 0; + +- OMX_ERRORTYPE omx_err = +- m_omx_render->GetConfig(OMX_IndexConfigAudioRenderingLatency, ¶m); ++ // Prefer HDMI latency if both are used ++ if(m_omx_render_analog.IsInitialized() && !m_omx_render_HDMI.IsInitialized()) ++ { ++ OMX_PARAM_U32TYPE param; ++ OMX_INIT_STRUCTURE(param); ++ param.nPortIndex = m_omx_render_analog.GetInputPort(); + +- if(omx_err != OMX_ErrorNone) ++ OMX_ERRORTYPE omx_err = ++ m_omx_render_analog.GetConfig(OMX_IndexConfigAudioRenderingLatency, ¶m); ++ ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n for m_omx_render_analog", ++ CLASSNAME, __func__, omx_err); ++ return 0; ++ } ++ ++ latAnalog = param.nU32; ++ } ++ ++ if(m_omx_render_HDMI.IsInitialized()) + { +- CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n", +- CLASSNAME, __func__, omx_err); +- return 0; ++ OMX_PARAM_U32TYPE param; ++ OMX_INIT_STRUCTURE(param); ++ param.nPortIndex = m_omx_render_HDMI.GetInputPort(); ++ ++ OMX_ERRORTYPE omx_err = ++ m_omx_render_HDMI.GetConfig(OMX_IndexConfigAudioRenderingLatency, ¶m); ++ ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n for m_omx_render_HDMI", ++ CLASSNAME, __func__, omx_err); ++ return 0; ++ } ++ ++ latHDMI = param.nU32; + } + +- return param.nU32; ++ return std::max(latAnalog, latHDMI); + } + + void COMXAudio::WaitCompletion() +@@ -1188,7 +1431,8 @@ void COMXAudio::WaitCompletion() + unsigned int nTimeOut = AUDIO_BUFFER_SECONDS * 1000; + while(nTimeOut) + { +- if(m_omx_render->IsEOS()) ++ if((m_omx_render_analog.IsInitialized() ? m_omx_render_analog.IsEOS() : true) && ++ (m_omx_render_HDMI.IsInitialized() ? m_omx_render_HDMI.IsEOS() : true)) + { + CLog::Log(LOGDEBUG, "%s::%s - got eos\n", CLASSNAME, __func__); + break; +@@ -1218,7 +1462,8 @@ void COMXAudio::WaitCompletion() + nTimeOut -= 50; + } + +- m_omx_render->ResetEos(); ++ m_omx_render_analog.ResetEos(); ++ m_omx_render_HDMI.ResetEos(); + + return; + } +diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h +index d812e0a..81aeb7e 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.h ++++ b/xbmc/cores/omxplayer/OMXAudio.h +@@ -60,7 +60,7 @@ class COMXAudio + float GetCacheTime(); + float GetCacheTotal(); + COMXAudio(); +- bool Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode); ++ bool Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode); + ~COMXAudio(); + + unsigned int AddPackets(const void* data, unsigned int len); +@@ -132,12 +132,18 @@ class COMXAudio + WAVEFORMATEXTENSIBLE m_wave_header; + AEAudioFormat m_format; + protected: +- COMXCoreComponent *m_omx_render; ++ void DumpStates(); ++ COMXCoreComponent m_omx_render_analog; ++ COMXCoreComponent m_omx_render_HDMI; ++ COMXCoreComponent m_omx_splitter; + COMXCoreComponent m_omx_mixer; + COMXCoreComponent m_omx_decoder; +- COMXCoreTunel m_omx_tunnel_clock; ++ COMXCoreTunel m_omx_tunnel_clock_analog; ++ COMXCoreTunel m_omx_tunnel_clock_HDMI; + COMXCoreTunel m_omx_tunnel_mixer; + COMXCoreTunel m_omx_tunnel_decoder; ++ COMXCoreTunel m_omx_tunnel_splitter_analog; ++ COMXCoreTunel m_omx_tunnel_splitter_HDMI; + DllAvUtil m_dllAvUtil; + + OMX_AUDIO_CHANNELTYPE m_input_channels[OMX_AUDIO_MAXCHANNELS]; +diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp +index 58c3a4f..f3276d2 100644 +--- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp +@@ -731,17 +731,10 @@ bool OMXPlayerAudio::OpenDecoder() + /* GetDataFormat is setting up evrything */ + m_format.m_dataFormat = GetDataFormat(m_hints); + +- std::string device = ""; +- +- if(g_guiSettings.GetInt("audiooutput.mode") == AUDIO_HDMI) +- device = "hdmi"; +- else +- device = "local"; +- + m_av_clock->Lock(); + m_av_clock->OMXStop(false); + +- bool bAudioRenderOpen = m_omxAudio.Initialize(m_format, device, m_av_clock, m_hints, m_passthrough, m_hw_decode); ++ bool bAudioRenderOpen = m_omxAudio.Initialize(m_format, m_av_clock, m_hints, m_passthrough, m_hw_decode); + + m_codec_name = ""; + m_bad_state = !bAudioRenderOpen; +diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp +index e92a82d..e798683 100644 +--- a/xbmc/settings/GUISettings.cpp ++++ b/xbmc/settings/GUISettings.cpp +@@ -457,6 +457,8 @@ void CGUISettings::Initialize() + audiomode.insert(make_pair(338,AUDIO_ANALOG)); + #if !defined(TARGET_RASPBERRY_PI) + audiomode.insert(make_pair(339,AUDIO_IEC958)); ++#else ++ audiomode.insert(make_pair(593,AUDIO_BOTH)); + #endif + audiomode.insert(make_pair(420,AUDIO_HDMI )); + #if defined(TARGET_RASPBERRY_PI) +diff --git a/xbmc/settings/GUISettings.h b/xbmc/settings/GUISettings.h +index b48ba35..500ec36 100644 +--- a/xbmc/settings/GUISettings.h ++++ b/xbmc/settings/GUISettings.h +@@ -84,6 +84,9 @@ + #define AUDIO_ANALOG 0 + #define AUDIO_IEC958 1 + #define AUDIO_HDMI 2 ++#ifdef TARGET_RASPBERRY_PI ++#define AUDIO_BOTH 3 ++#endif + #define AUDIO_IS_BITSTREAM(x) ((x) == AUDIO_IEC958 || (x) == AUDIO_HDMI) + + #define VIDEO_NORMAL 0 +-- +1.8.1.6 + + +From 85bb82a3f78a63385767e8e1a7490860077b1b32 Mon Sep 17 00:00:00 2001 +From: stupid-boy +Date: Thu, 7 Mar 2013 20:46:21 +0200 +Subject: [PATCH 2/2] Seek fixed + +--- + xbmc/cores/omxplayer/OMXAudio.cpp | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp +index 1470685..6b0e71a 100644 +--- a/xbmc/cores/omxplayer/OMXAudio.cpp ++++ b/xbmc/cores/omxplayer/OMXAudio.cpp +@@ -749,8 +749,16 @@ void COMXAudio::Flush() + + m_omx_decoder.FlushInput(); + m_omx_tunnel_decoder.Flush(); +- if(!m_Passthrough) ++ if ( m_omx_mixer.IsInitialized() ) ++ m_omx_mixer.FlushAll(); ++ if( m_omx_tunnel_mixer.IsInitialized() ) + m_omx_tunnel_mixer.Flush(); ++ if ( m_omx_splitter.IsInitialized() ) ++ m_omx_splitter.FlushAll(); ++ if ( m_omx_tunnel_splitter_analog.IsInitialized() ) ++ m_omx_tunnel_splitter_analog.Flush(); ++ if ( m_omx_tunnel_splitter_HDMI.IsInitialized() ) ++ m_omx_tunnel_splitter_HDMI.Flush(); + + m_last_pts = DVD_NOPTS_VALUE; + m_LostSync = true; +-- +1.8.1.6 + diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch.bk similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-995.03-OMXPlayer-Audio-fix_incorrect_usage_of_flag_talled.patch.bk diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch.bk similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/todo/xbmc-995.04-OMXPlayer-some_caching_fixes_for_pvr.patch.bk diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-321-texturepacker-hostflags-and-rework.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-321-texturepacker-hostflags-and-rework.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-321-texturepacker-hostflags-and-rework.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-321-texturepacker-hostflags-and-rework.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-452-change_lcd_content-0.1.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-452-change_lcd_content-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-452-change_lcd_content-0.1.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-452-change_lcd_content-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-453-add_openelec.tv_RSS_news-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-453-add_openelec.tv_RSS_news-0.1.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.00-remove-windowed-display-mode.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-990.00-remove-windowed-display-mode.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.00-remove-windowed-display-mode.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-990.00-remove-windowed-display-mode.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.24-smbnfsdeinit-and-wait-for-nic-on-wakeup.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-990.24-smbnfsdeinit-and-wait-for-nic-on-wakeup.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.24-smbnfsdeinit-and-wait-for-nic-on-wakeup.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-990.24-smbnfsdeinit-and-wait-for-nic-on-wakeup.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.11-enable-vpp-deinterlacing.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.11-enable-vpp-deinterlacing.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.11-enable-vpp-deinterlacing.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.11-enable-vpp-deinterlacing.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.12-enable-vpp-fix-audio-out-of-sync.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.12-enable-vpp-fix-audio-out-of-sync.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.12-enable-vpp-fix-audio-out-of-sync.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.12-enable-vpp-fix-audio-out-of-sync.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.13-vpp-fix-skipping.patch b/packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.13-vpp-fix-skipping.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.13-vpp-fix-skipping.patch rename to packages/mediacenter/xbmc/patches/12.2-9064b9b/xbmc-995.13-vpp-fix-skipping.patch diff --git a/packages/mediacenter/xbmc/patches/12.2.0/todo/xbmc-995.02-only_free_unused_textures_after_a_flip.patch.bk b/packages/mediacenter/xbmc/patches/12.2.0/todo/xbmc-995.02-only_free_unused_textures_after_a_flip.patch.bk deleted file mode 100644 index 6ee705e97..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/todo/xbmc-995.02-only_free_unused_textures_after_a_flip.patch.bk +++ /dev/null @@ -1,29 +0,0 @@ -From f3ffe4e25bfca41379e4e2ffba75ad55d13ba30e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 21 Mar 2013 07:53:20 +0100 -Subject: [PATCH] only free unused textures after a flip - ---- - xbmc/Application.cpp | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index fa0e71d..5bd2d72 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -2363,11 +2363,10 @@ void CApplication::Render() - { - g_graphicsContext.Flip(dirtyRegions); - g_renderManager.NotifyDisplayFlip(); -+ g_TextureManager.FreeUnusedTextures(); - } - CTimeUtils::UpdateFrameTime(flip); - -- g_TextureManager.FreeUnusedTextures(); -- - g_renderManager.UpdateResolution(); - g_renderManager.ManageCaptures(); - } --- -1.8.1.5 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.01-PR1934.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.01-PR1934.patch deleted file mode 100644 index 8079f1049..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.01-PR1934.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1704ff69ba704bf53505f7f9ac51ec06f93401ee Mon Sep 17 00:00:00 2001 -From: wsnipex -Date: Sun, 9 Dec 2012 14:37:21 +0100 -Subject: [PATCH 1/2] configure: allow GIT_REV to be read from VERSION file - needed for building outside of a git repo - ---- - configure.in | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/configure.in b/configure.in -index d8c7804..ac1445c 100644 ---- a/configure.in -+++ b/configure.in -@@ -2160,7 +2160,12 @@ if test "$HAVE_GIT" = "yes"; then - GIT_REV=$(git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h %ci" HEAD | awk '{gsub("-", "");print $2"-"$1}') - fi - if test "$GIT_REV" = ""; then -- GIT_REV="Unknown" -+ if test -f VERSION ; then -+ GIT_REV=$(awk 'END{print substr($1,1,16)}' VERSION) -+ if test -z $GIT_REV ; then GIT_REV="Unknown" ; fi -+ else -+ GIT_REV="Unknown" -+ fi - fi - if test "$host_vendor" = "apple"; then - echo "#define GIT_REV \"$GIT_REV\"" > git_revision.h --- -1.7.10 - - -From 4377a985c7e4e4d1f1c0abba68c2367d33ddab03 Mon Sep 17 00:00:00 2001 -From: wsnipex -Date: Sun, 16 Dec 2012 17:46:12 +0100 -Subject: [PATCH 2/2] release-source script needs bash on some systems /bin/sh - is a simplistic posix shell - ---- - tools/mk-release-source | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tools/mk-release-source b/tools/mk-release-source -index 7964665..68bdfa1 100755 ---- a/tools/mk-release-source -+++ b/tools/mk-release-source -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/bin/bash - REVISION="${1}" - COMPRESS="gzip" - WORKDIR="xbmc-${REVISION}" --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.02-PR2193.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.02-PR2193.patch deleted file mode 100644 index ab619e9a6..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.02-PR2193.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 1e3abea7b9a4212005b11dbb5a9542ca9cbcd21a Mon Sep 17 00:00:00 2001 -From: Stephan Raue -Date: Thu, 7 Feb 2013 18:27:08 +0100 -Subject: [PATCH] configure.in: change check for 'VERSION' file: - first check - if this file exist and use the content from there - if it - not exist check with 'git log' - if this fails set to - 'Unknown' - -This patch also shows the GIT_REV in the configure summary message. To display This message on top of the messages we move the whole block a bit above ---- - configure.in | 40 ++++++++++++++++++++-------------------- - 1 file changed, 20 insertions(+), 20 deletions(-) - -diff --git a/configure.in b/configure.in -index ac1445c..869fd29 100644 ---- a/configure.in -+++ b/configure.in -@@ -687,6 +687,25 @@ case $use_platform in - ;; - esac - -+# check for GIT_REV -+AC_CHECK_PROG(HAVE_GIT,git,"yes","no",) -+if test "$GIT_REV" = ""; then -+ if test -f VERSION ; then -+ GIT_REV=$(awk 'END{print substr($1,1,16)}' VERSION) -+ elif test "$HAVE_GIT" = "yes"; then -+ GIT_REV=$(git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h %ci" HEAD | awk '{gsub("-", "");print $2"-"$1}') -+ else -+ GIT_REV="Unknown" -+ fi -+fi -+final_message="$final_message\n git Rev.:\t${GIT_REV}" -+ -+if test "$host_vendor" = "apple"; then -+ echo "#define GIT_REV \"$GIT_REV\"" > git_revision.h -+else -+ SDL_DEFINES="$SDL_DEFINES -D'GIT_REV=\"$GIT_REV\"'" -+fi -+ - if test "$build_shared_lib" = "yes"; then - final_message="$final_message\n Shared lib\tYes" - AC_SUBST(USE_LIBXBMC,1) -@@ -1886,8 +1905,6 @@ if test "$ARCH" = "i486-linux" || test "$ARCH" = "x86-freebsd"; then - fi - fi - --AC_CHECK_PROG(HAVE_GIT,git,"yes","no",) -- - # Checks for header files. - AC_HEADER_DIRENT - AC_HEADER_STDC -@@ -1943,7 +1960,7 @@ else - USE_OPENGL=1 - else - final_message="$final_message\n OpenGL:\tNo (Very Slow)" -- SDL_DEFINES="-DHAS_SDL_2D" -+ SDL_DEFINES="$SDL_DEFINES -DHAS_SDL_2D" - USE_OPENGL=0 - fi - fi -@@ -2156,23 +2173,6 @@ else - final_message="$final_message\n Avahi:\tNo" - fi - --if test "$HAVE_GIT" = "yes"; then -- GIT_REV=$(git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h %ci" HEAD | awk '{gsub("-", "");print $2"-"$1}') --fi --if test "$GIT_REV" = ""; then -- if test -f VERSION ; then -- GIT_REV=$(awk 'END{print substr($1,1,16)}' VERSION) -- if test -z $GIT_REV ; then GIT_REV="Unknown" ; fi -- else -- GIT_REV="Unknown" -- fi --fi --if test "$host_vendor" = "apple"; then -- echo "#define GIT_REV \"$GIT_REV\"" > git_revision.h --else -- SDL_DEFINES="$SDL_DEFINES -D'GIT_REV=\"$GIT_REV\"'" --fi -- - if test "$use_nonfree" = "yes"; then - final_message="$final_message\n Non-free:\tYes" - HAVE_XBMC_NONFREE=1 --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.03-PR2449-1.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.03-PR2449-1.patch deleted file mode 100644 index 9f56960ed..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.03-PR2449-1.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3180ec7e5e065c0f9276a2d8999e8e8d997c4dba Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Mar 2013 15:52:55 +0100 -Subject: [PATCH] dvdplayer: put line break into video codec info because it - gets too long - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index be89406..bb1fc42 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -2579,7 +2579,7 @@ void CDVDPlayer::GetVideoInfo(CStdString& strVideoInfo) - { CSingleLock lock(m_StateSection); - strVideoInfo.Format("D(%s)", m_StateInput.demux_video.c_str()); - } -- strVideoInfo.AppendFormat(" P(%s)", m_dvdPlayerVideo.GetPlayerInfo().c_str()); -+ strVideoInfo.AppendFormat("\nP(%s)", m_dvdPlayerVideo.GetPlayerInfo().c_str()); - } - - void CDVDPlayer::GetGeneralInfo(CStdString& strGeneralInfo) --- -1.8.1.5 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.04-PR2231.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.04-PR2231.patch deleted file mode 100644 index b65672ae8..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.04-PR2231.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 07b4e2c80c046bad566ed4a70e49ae4bfb3ecc47 Mon Sep 17 00:00:00 2001 -From: stupid-boy -Date: Wed, 13 Feb 2013 20:56:12 +0200 -Subject: [PATCH] Changed cpu frequency for all Linux platforms, added RPI - specific cpu temp command and removed irrelevant gpu temp - for all ARM platforms. - ---- - xbmc/utils/CPUInfo.cpp | 41 +++++++++++++++++----------------- - xbmc/utils/CPUInfo.h | 2 +- - xbmc/windows/GUIWindowSystemInfo.cpp | 4 +++- - 3 files changed, 24 insertions(+), 23 deletions(-) - -diff --git a/xbmc/utils/CPUInfo.cpp b/xbmc/utils/CPUInfo.cpp -index 64c90b9..f605751 100644 ---- a/xbmc/utils/CPUInfo.cpp -+++ b/xbmc/utils/CPUInfo.cpp -@@ -107,7 +107,7 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz ) - - CCPUInfo::CCPUInfo(void) - { -- m_fProcStat = m_fProcTemperature = m_fCPUInfo = NULL; -+ m_fProcStat = m_fProcTemperature = m_fCPUFreq = NULL; - m_lastUsedPercentage = 0; - m_cpuFeatures = 0; - -@@ -235,15 +235,20 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz ) - // read from the new location of the temperature data on new kernels, 2.6.39, 3.0 etc - if (m_fProcTemperature == NULL) - m_fProcTemperature = fopen("/sys/class/hwmon/hwmon0/temp1_input", "r"); -- -- m_fCPUInfo = fopen("/proc/cpuinfo", "r"); -+ if (m_fProcTemperature == NULL) -+ m_fProcTemperature = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); // On Raspberry PIs -+ -+ m_fCPUFreq = fopen ("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r"); -+ -+ -+ FILE* fCPUInfo = fopen("/proc/cpuinfo", "r"); - m_cpuCount = 0; -- if (m_fCPUInfo) -+ if (fCPUInfo) - { - char buffer[512]; - - int nCurrId = 0; -- while (fgets(buffer, sizeof(buffer), m_fCPUInfo)) -+ while (fgets(buffer, sizeof(buffer), fCPUInfo)) - { - if (strncmp(buffer, "processor", strlen("processor"))==0) - { -@@ -369,6 +374,7 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz ) - } - } - } -+ fclose(fCPUInfo); - } - else - { -@@ -409,8 +415,8 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz ) - if (m_fProcTemperature != NULL) - fclose(m_fProcTemperature); - -- if (m_fCPUInfo != NULL) -- fclose(m_fCPUInfo); -+ if (m_fCPUFreq != NULL) -+ fclose(m_fCPUFreq); - } - - int CCPUInfo::getUsedPercentage() -@@ -482,21 +488,14 @@ float CCPUInfo::getCPUFrequency() - hz = 0; - return (float)hz; - #else -- float mhz = 0.f; -- char buf[256], -- *needle = NULL; -- if (!m_fCPUInfo) -- return mhz; -- rewind(m_fCPUInfo); -- fflush(m_fCPUInfo); -- while (fgets(buf, 256, m_fCPUInfo) != NULL) { -- if (strncmp(buf, "cpu MHz", 7) == 0) { -- needle = strchr(buf, ':'); -- sscanf(++needle, "%f", &mhz); -- break; -- } -+ int value = 0; -+ if (m_fCPUFreq) -+ { -+ rewind(m_fCPUFreq); -+ fflush(m_fCPUFreq); -+ fscanf(m_fCPUFreq, "%d", &value); - } -- return mhz; -+ return value / 1000.0; - #endif - } - -diff --git a/xbmc/utils/CPUInfo.h b/xbmc/utils/CPUInfo.h -index 638c19f..ae9447d 100644 ---- a/xbmc/utils/CPUInfo.h -+++ b/xbmc/utils/CPUInfo.h -@@ -93,7 +93,7 @@ class CCPUInfo - - FILE* m_fProcStat; - FILE* m_fProcTemperature; -- FILE* m_fCPUInfo; -+ FILE* m_fCPUFreq; - - unsigned long long m_userTicks; - unsigned long long m_niceTicks; -diff --git a/xbmc/windows/GUIWindowSystemInfo.cpp b/xbmc/windows/GUIWindowSystemInfo.cpp -index fcc1f89..75fd0cd 100644 ---- a/xbmc/windows/GUIWindowSystemInfo.cpp -+++ b/xbmc/windows/GUIWindowSystemInfo.cpp -@@ -141,7 +141,9 @@ void CGUIWindowSystemInfo::FrameMove() - SetControlLabel(i++, "%s %s", 22023, SYSTEM_RENDER_VENDOR); - SetControlLabel(i++, "%s %s", 22024, SYSTEM_RENDER_VERSION); - #endif -+#ifndef __arm__ - SetControlLabel(i++, "%s %s", 22010, SYSTEM_GPU_TEMPERATURE); -+#endif - } - else if (m_section == CONTROL_BT_HARDWARE) - { -@@ -155,7 +157,7 @@ void CGUIWindowSystemInfo::FrameMove() - SET_CONTROL_LABEL(i++, g_sysinfo.GetCPUSerial()); - #endif - SetControlLabel(i++, "%s %s", 22011, SYSTEM_CPU_TEMPERATURE); --#if !defined(__arm__) -+#if !defined(__arm__) || defined(TARGET_RASPBERRY_PI) - SetControlLabel(i++, "%s %s", 13284, SYSTEM_CPUFREQUENCY); - #endif - #endif --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.05-PR2403-01.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.05-PR2403-01.patch deleted file mode 100644 index 6eac2089e..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.05-PR2403-01.patch +++ /dev/null @@ -1,94 +0,0 @@ -diff -Naur xbmc-12.0.6/xbmc/powermanagement/linux/FallbackPowerSyscall.h xbmc-12.0.6.patch/xbmc/powermanagement/linux/FallbackPowerSyscall.h ---- xbmc-12.0.6/xbmc/powermanagement/linux/FallbackPowerSyscall.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-12.0.6.patch/xbmc/powermanagement/linux/FallbackPowerSyscall.h 2013-03-13 22:25:29.220700789 +0100 -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (C) 2005-2013 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 "powermanagement/IPowerSyscall.h" -+#include "system.h" -+#if defined(TARGET_LINUX) -+ -+class CFallbackPowerSyscall : public CPowerSyscallWithoutEvents -+{ -+public: -+ virtual bool Powerdown() {return true; } -+ virtual bool Suspend() {return false; } -+ virtual bool Hibernate() {return false; } -+ virtual bool Reboot() {return true; } -+ -+ virtual bool CanPowerdown() {return true; } -+ virtual bool CanSuspend() {return false; } -+ virtual bool CanHibernate() {return false; } -+ virtual bool CanReboot() {return true; } -+ virtual int BatteryLevel() {return 0; } -+}; -+#endif -diff -Naur xbmc-12.0.6/xbmc/powermanagement/PowerManager.cpp xbmc-12.0.6.patch/xbmc/powermanagement/PowerManager.cpp ---- xbmc-12.0.6/xbmc/powermanagement/PowerManager.cpp 2013-03-11 18:01:45.000000000 +0100 -+++ xbmc-12.0.6.patch/xbmc/powermanagement/PowerManager.cpp 2013-03-14 00:20:43.263315592 +0100 -@@ -41,14 +41,17 @@ - #include "osx/CocoaPowerSyscall.h" - #elif defined(TARGET_ANDROID) - #include "android/AndroidPowerSyscall.h" --#elif defined(_LINUX) && defined(HAS_DBUS) -+#elif defined(TARGET_LINUX) -+#include "linux/FallbackPowerSyscall.h" -+#if defined(HAS_DBUS) - #include "linux/ConsoleUPowerSyscall.h" - #include "linux/ConsoleDeviceKitPowerSyscall.h" - #include "linux/SystemdUPowerSyscall.h" - #include "linux/UPowerSyscall.h" --#ifdef HAS_HAL -+#if defined(HAS_HAL) - #include "linux/HALPowerSyscall.h" --#endif -+#endif // HAS_HAL -+#endif // HAS_DBUS - #elif defined(_WIN32) - #include "powermanagement/windows/Win32PowerSyscall.h" - extern HWND g_hWnd; -@@ -74,7 +77,8 @@ - m_instance = new CCocoaPowerSyscall(); - #elif defined(TARGET_ANDROID) - m_instance = new CAndroidPowerSyscall(); --#elif defined(_LINUX) && defined(HAS_DBUS) -+#elif defined(TARGET_LINUX) -+#if defined(HAS_DBUS) - if (CConsoleUPowerSyscall::HasConsoleKitAndUPower()) - m_instance = new CConsoleUPowerSyscall(); - else if (CConsoleDeviceKitPowerSyscall::HasDeviceConsoleKit()) -@@ -83,10 +87,13 @@ - m_instance = new CSystemdUPowerSyscall(); - else if (CUPowerSyscall::HasUPower()) - m_instance = new CUPowerSyscall(); --#ifdef HAS_HAL -- else -+#if defined(HAS_HAL) -+ else if(1) - m_instance = new CHALPowerSyscall(); --#endif -+#endif // HAS_HAL -+#endif // HAS_DBUS -+ else -+ m_instance = new CFallbackPowerSyscall(); - #elif defined(_WIN32) - m_instance = new CWin32PowerSyscall(); - #endif diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.06-add-builtin-to-set-GUI-Language.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.06-add-builtin-to-set-GUI-Language.patch deleted file mode 100644 index 884e1f31f..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.06-add-builtin-to-set-GUI-Language.patch +++ /dev/null @@ -1,32 +0,0 @@ -commit d1fcd3007827ddd2ab20864677a5baf64e4782a4 -Author: Stefan Saraev -Date: Mon Jan 21 17:11:21 2013 +0200 - - add builtin to set GUI Language - -diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp -index fae2524..3f5ceab 100644 ---- a/xbmc/interfaces/Builtins.cpp -+++ b/xbmc/interfaces/Builtins.cpp -@@ -120,6 +120,7 @@ const BUILT_IN commands[] = { - { "Minimize", false, "Minimize XBMC" }, - { "Reset", false, "Reset the system (same as reboot)" }, - { "Mastermode", false, "Control master mode" }, -+ { "SetGUILanguage", true, "Set GUI Language" }, - { "ActivateWindow", true, "Activate the specified window" }, - { "ActivateWindowAndFocus", true, "Activate the specified window and sets focus to the specified id" }, - { "ReplaceWindow", true, "Replaces the current window with the new one" }, -@@ -321,6 +322,13 @@ int CBuiltins::Execute(const CStdString& execString) - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); - g_windowManager.SendMessage(msg); - } -+ else if (execute.Equals("setguilanguage")) -+ { -+ if (params.size()) -+ { -+ CApplicationMessenger::Get().SetGUILanguage(params[0]); -+ } -+ } - else if (execute.Equals("takescreenshot")) - { - CScreenShot::TakeScreenshot(); diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.07-PR2435.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.07-PR2435.patch deleted file mode 100644 index 1b6809910..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.07-PR2435.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 2da77839fbf972e8c6f09c56d25f8c7bf999f3fa Mon Sep 17 00:00:00 2001 -From: dezi -Date: Mon, 18 Mar 2013 12:29:27 +0000 -Subject: [PATCH] Added hotplug support for Linux input devices. - ---- - xbmc/input/linux/LinuxInputDevices.cpp | 80 ++++++++++++++++++++++++++++++++++ - xbmc/input/linux/LinuxInputDevices.h | 6 +++ - 2 files changed, 86 insertions(+) - -diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp -index 9d253bb..1d3d315 100644 ---- a/xbmc/input/linux/LinuxInputDevices.cpp -+++ b/xbmc/input/linux/LinuxInputDevices.cpp -@@ -338,6 +338,7 @@ - m_deviceMinKeyCode = 0; - m_deviceMaxKeyCode = 0; - m_deviceMaxAxis = 0; -+ m_bUnplugged = false; - - Open(); - } -@@ -744,7 +745,15 @@ XBMC_Event CLinuxInputDevice::ReadEvent() - readlen = read(m_fd, &levt, sizeof(levt)); - - if (readlen <= 0) -+ { -+ if (errno == ENODEV) -+ { -+ CLog::Log(LOGINFO,"input device was unplugged %s",m_deviceName); -+ m_bUnplugged = true; -+ } -+ - break; -+ } - - //printf("read event readlen = %d device name %s m_fileName %s\n", readlen, m_deviceName, m_fileName.c_str()); - -@@ -963,6 +972,16 @@ void CLinuxInputDevice::GetInfo(int fd) - //printf("pref: %d\n", m_devicePreferredId); - } - -+char* CLinuxInputDevice::GetDeviceName() -+{ -+ return m_deviceName; -+} -+ -+bool CLinuxInputDevice::IsUnplugged() -+{ -+ return m_bUnplugged; -+} -+ - bool CLinuxInputDevices::CheckDevice(const char *device) - { - int fd; -@@ -1021,6 +1040,41 @@ void CLinuxInputDevices::InitAvailable() - } - - /* -+ * Check for hot plugged devices. -+ */ -+void CLinuxInputDevices::CheckHotplugged() -+{ -+ CSingleLock lock(m_devicesListLock); -+ -+ int deviceId = m_devices.size(); -+ -+ /* No devices specified. Try to guess some. */ -+ for (int i = 0; i < MAX_LINUX_INPUT_DEVICES; i++) -+ { -+ char buf[32]; -+ bool ispresent = false; -+ -+ snprintf(buf, 32, "/dev/input/event%d", i); -+ -+ for (size_t j = 0; j < m_devices.size(); j++) -+ { -+ if (strcmp(m_devices[j]->GetDeviceName(),buf) == 0) -+ { -+ ispresent = true; -+ break; -+ } -+ } -+ -+ if (!ispresent && CheckDevice(buf)) -+ { -+ CLog::Log(LOGINFO, "Found input device %s", buf); -+ m_devices.push_back(new CLinuxInputDevice(buf, deviceId)); -+ ++deviceId; -+ } -+ } -+} -+ -+/* - * Open the device, fill out information about it, - * allocate and fill private data, start input thread. - */ -@@ -1076,6 +1130,9 @@ bool CLinuxInputDevice::Open() - { - if (m_vt_fd < 0) - m_vt_fd = open("/dev/tty0", O_RDWR | O_NOCTTY); -+ -+ if (m_vt_fd < 0) -+ m_vt_fd = open("/dev/tty1", O_RDWR | O_NOCTTY); - - if (m_vt_fd < 0) - CLog::Log(LOGWARNING, "no keymap support (requires /dev/tty0 - CONFIG_VT)"); -@@ -1195,6 +1252,23 @@ void CLinuxInputDevice::Close() - - XBMC_Event CLinuxInputDevices::ReadEvent() - { -+ if (m_bReInitialize) -+ { -+ InitAvailable(); -+ m_bReInitialize = false; -+ } -+ else -+ { -+ time_t now; -+ time(&now); -+ -+ if ((now - m_lastHotplugCheck) >= 10) -+ { -+ CheckHotplugged(); -+ m_lastHotplugCheck = now; -+ } -+ } -+ - CSingleLock lock(m_devicesListLock); - - XBMC_Event event; -@@ -1207,6 +1281,12 @@ XBMC_Event CLinuxInputDevices::ReadEvent() - { - break; - } -+ -+ if (m_devices[i]->IsUnplugged()) -+ { -+ m_bReInitialize = true; -+ break; -+ } - } - - return event; -diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h -index 18224a9..b7626f4 100644 ---- a/xbmc/input/linux/LinuxInputDevices.h -+++ b/xbmc/input/linux/LinuxInputDevices.h -@@ -41,6 +41,8 @@ class CLinuxInputDevice - CLinuxInputDevice(const std::string fileName, int index); - ~CLinuxInputDevice(); - XBMC_Event ReadEvent(); -+ char* GetDeviceName(); -+ bool IsUnplugged(); - - private: - void SetupKeyboardAutoRepeat(int fd); -@@ -76,12 +78,14 @@ class CLinuxInputDevice - int m_deviceMaxKeyCode; - int m_deviceMaxAxis; - bool m_bSkipNonKeyEvents; -+ bool m_bUnplugged; - }; - - class CLinuxInputDevices - { - public: - void InitAvailable(); -+ void CheckHotplugged(); - XBMC_Event ReadEvent(); - bool IsRemoteLowBattery(); - bool IsRemoteNotPaired(); -@@ -89,6 +93,8 @@ class CLinuxInputDevices - CCriticalSection m_devicesListLock; - bool CheckDevice(const char *device); - std::vector m_devices; -+ bool m_bReInitialize; -+ time_t m_lastHotplugCheck; - }; - - #endif /* LINUXINPUTDEVICES_H_ */ --- -1.8.1.5 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.08-PR2637.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.08-PR2637.patch deleted file mode 100644 index 61ba30e4c..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.08-PR2637.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d4c34400b9bdebbb1a943603a54fdf207034ddd1 Mon Sep 17 00:00:00 2001 -From: Dag Wieers -Date: Sat, 20 Apr 2013 02:59:47 +0200 -Subject: [PATCH] Increase USB and CEC rescan interval to 5 seconds - -In one of my investigations to see why XBMC performance is so bad (even when idle) I found one of the threads (in my case PeripheralBusCEC) scan a big sysfs tree recursively. On the 1Ghz AppleTV 1 device this would be about 2% of the CPU *every* second. For the USB thread we luckily have Udev events, but for CEC it is using sysfs polling which is quite expensive. It would be better to make use of Udev as well for CEC (where available) however 5 seconds should be fine for everyone. - -In my own builds I even brought it down to 30 seconds. Which means 29 seconds of reduced CPU usage. - -The CEC polling probably should be more restricted to specific sysfs sections, or preferably use Udev as well, when available. - -PS XBMC needs a special idle-state where it can turn down these expensive threads to make sure hardware can go into deeper sleep states. Especially for devices that doesn't do suspend for various reasons this is a requirement. (The ATV1 device for instance gets warm even when idle) If we can combine display-sleep with low-power states and a less expensive main-loop, that would be already quite an improvement without needing a complete refactoring of the code. ---- - xbmc/peripherals/bus/PeripheralBus.cpp | 2 +- - xbmc/peripherals/bus/PeripheralBus.h | 2 +- - xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp -index 0e673ee..f0219f1 100644 ---- a/xbmc/peripherals/bus/PeripheralBus.cpp -+++ b/xbmc/peripherals/bus/PeripheralBus.cpp -@@ -27,7 +27,7 @@ - using namespace std; - using namespace PERIPHERALS; - --#define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 1000 -+#define PERIPHERAL_DEFAULT_RESCAN_INTERVAL 5000 - - CPeripheralBus::CPeripheralBus(CPeripherals *manager, PeripheralBusType type) : - CThread("PeripheralBus"), -diff --git a/xbmc/peripherals/bus/PeripheralBus.h b/xbmc/peripherals/bus/PeripheralBus.h -index cc368ac..24e1524 100644 ---- a/xbmc/peripherals/bus/PeripheralBus.h -+++ b/xbmc/peripherals/bus/PeripheralBus.h -@@ -33,7 +33,7 @@ - - /*! - * @class CPeripheralBus -- * This represents a bus on the system. By default, this bus instance will scan for changes every second. -+ * This represents a bus on the system. By default, this bus instance will scan for changes every 5 seconds. - * If this bus only has to be updated after a notification sent by the system, set m_bNeedsPolling to false - * in the constructor, and implement the OnDeviceAdded(), OnDeviceChanged() and OnDeviceRemoved() methods. - * -diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp -index da169c1..0db7423 100644 ---- a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp -+++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp -@@ -57,7 +57,7 @@ class PERIPHERALS::DllLibCEC : public DllDynamic, DllLibCECInterface - m_dll(new DllLibCEC), - m_cecAdapter(NULL) - { -- m_iRescanTime = 1000; -+ m_iRescanTime = 5000; - if (!m_dll->Load() || !m_dll->IsLoaded()) - { - delete m_dll; --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.09-PR2686.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.09-PR2686.patch deleted file mode 100644 index c295c354d..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.09-PR2686.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7ee7e59e858c7f1901c6879e39b30480c42ef126 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Apr 2013 22:50:08 +0100 -Subject: [PATCH] [rbp] Remove unnecessary gl ifdef - -I'm not sure why this was originally added. -I couldn't think of a reason why the Pi would want things done differently here, -so I tried without the ifdef. I can't see any difference in behaviour, -so I think we're better off removing it. ---- - xbmc/rendering/gles/RenderSystemGLES.cpp | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp -index e7795fb..472f441 100644 ---- a/xbmc/rendering/gles/RenderSystemGLES.cpp -+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp -@@ -138,11 +138,7 @@ bool CRenderSystemGLES::ResetRenderSystem(int width, int height, bool fullScreen - g_matrices.MatrixMode(MM_PROJECTION); - g_matrices.LoadIdentity(); - --#ifdef TARGET_RASPBERRY_PI -- g_matrices.Ortho(0.0f, width-1, height-1, 0.0f, +1.0f, 1.0f); --#else - g_matrices.Ortho(0.0f, width-1, height-1, 0.0f, -1.0f, 1.0f); --#endif - - g_matrices.MatrixMode(MM_MODELVIEW); - g_matrices.LoadIdentity(); --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.10-PR2713.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.10-PR2713.patch deleted file mode 100644 index 19c9cf7fe..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.10-PR2713.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 1c12a2f021cceee0d7eee2de5df993d73d790aa5 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Thu, 9 May 2013 19:27:14 -0400 -Subject: [PATCH 1/2] texture: combine Load() and GetTexture() since they must - be used together - ---- - xbmc/guilib/GUITexture.cpp | 19 ++++++++-------- - xbmc/guilib/TextureManager.cpp | 51 ++++++++++++++++++++---------------------- - xbmc/guilib/TextureManager.h | 3 +-- - 3 files changed, 34 insertions(+), 39 deletions(-) - -diff --git a/xbmc/guilib/GUITexture.cpp b/xbmc/guilib/GUITexture.cpp -index 9da2030..5896606 100644 ---- a/xbmc/guilib/GUITexture.cpp -+++ b/xbmc/guilib/GUITexture.cpp -@@ -301,11 +301,12 @@ bool CGUITextureBase::AllocResources() - { // we want to use the large image loader, but we first check for bundled textures - if (!IsAllocated()) - { -- int images = g_TextureManager.Load(m_info.filename, true); -- if (images) -+ CTextureArray texture; -+ texture = g_TextureManager.Load(m_info.filename, true); -+ if (texture.size()) - { - m_isAllocated = NORMAL; -- m_texture = g_TextureManager.GetTexture(m_info.filename); -+ m_texture = texture; - changed = true; - } - } -@@ -329,15 +330,14 @@ bool CGUITextureBase::AllocResources() - } - else if (!IsAllocated()) - { -- int images = g_TextureManager.Load(m_info.filename); -+ CTextureArray texture = g_TextureManager.Load(m_info.filename); - - // set allocated to true even if we couldn't load the image to save - // us hitting the disk every frame -- m_isAllocated = images ? NORMAL : NORMAL_FAILED; -- if (!images) -+ m_isAllocated = texture.size() ? NORMAL : NORMAL_FAILED; -+ if (!texture.size()) - return false; -- -- m_texture = g_TextureManager.GetTexture(m_info.filename); -+ m_texture = texture; - changed = true; - } - m_frameWidth = (float)m_texture.m_width; -@@ -346,8 +346,7 @@ bool CGUITextureBase::AllocResources() - // load the diffuse texture (if necessary) - if (!m_info.diffuse.IsEmpty()) - { -- g_TextureManager.Load(m_info.diffuse); -- m_diffuse = g_TextureManager.GetTexture(m_info.diffuse); -+ m_diffuse = g_TextureManager.Load(m_info.diffuse); - } - - CalculateSize(); -diff --git a/xbmc/guilib/TextureManager.cpp b/xbmc/guilib/TextureManager.cpp -index 93fdcd1..6d6c4d9 100644 ---- a/xbmc/guilib/TextureManager.cpp -+++ b/xbmc/guilib/TextureManager.cpp -@@ -221,22 +221,6 @@ void CTextureMap::Add(CBaseTexture* texture, int delay) - Cleanup(); - } - --const CTextureArray& CGUITextureManager::GetTexture(const CStdString& strTextureName) --{ -- static CTextureArray emptyTexture; -- // CLog::Log(LOGINFO, " refcount++ for GetTexture(%s)\n", strTextureName.c_str()); -- for (int i = 0; i < (int)m_vecTextures.size(); ++i) -- { -- CTextureMap *pMap = m_vecTextures[i]; -- if (pMap->GetName() == strTextureName) -- { -- //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); -- return pMap->GetTexture(); -- } -- } -- return emptyTexture; --} -- - /************************************************************************/ - /* */ - /************************************************************************/ -@@ -290,19 +274,32 @@ bool CGUITextureManager::HasTexture(const CStdString &textureName, CStdString *p - return !fullPath.IsEmpty(); - } - --int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleOnly /*= false */) -+const CTextureArray& CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleOnly /*= false */) - { - CStdString strPath; -+ static CTextureArray emptyTexture; - int bundle = -1; - int size = 0; - if (!HasTexture(strTextureName, &strPath, &bundle, &size)) -- return 0; -+ return emptyTexture; - - if (size) // we found the texture -- return size; -+ { -+ for (int i = 0; i < (int)m_vecTextures.size(); ++i) -+ { -+ CTextureMap *pMap = m_vecTextures[i]; -+ if (pMap->GetName() == strTextureName) -+ { -+ //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); -+ return pMap->GetTexture(); -+ } -+ } -+ // Whoops, not there. -+ return emptyTexture; -+ } - - if (checkBundleOnly && bundle == -1) -- return 0; -+ return emptyTexture; - - //Lock here, we will do stuff that could break rendering - CSingleLock lock(g_graphicsContext); -@@ -327,7 +324,7 @@ int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleO - CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); - delete [] pTextures; - delete [] Delay; -- return 0; -+ return emptyTexture; - } - - pMap = new CTextureMap(strTextureName, width, height, nLoops); -@@ -348,7 +345,7 @@ int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleO - CStdString rootPath = strPath.Left(g_SkinInfo->Path().GetLength()); - if (0 == rootPath.CompareNoCase(g_SkinInfo->Path())) - CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); -- return 0; -+ return emptyTexture; - } - int iWidth = AnimatedGifSet.FrameWidth; - int iHeight = AnimatedGifSet.FrameHeight; -@@ -386,7 +383,7 @@ int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleO - #endif - - m_vecTextures.push_back(pMap); -- return 1; -+ return pMap->GetTexture(); - } // of if (strPath.Right(4).ToLower()==".gif") - - CBaseTexture *pTexture = NULL; -@@ -396,19 +393,19 @@ int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleO - if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)) - { - CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); -- return 0; -+ return emptyTexture; - } - } - else - { - pTexture = CBaseTexture::LoadFromFile(strPath); - if (!pTexture) -- return 0; -+ return emptyTexture; - width = pTexture->GetWidth(); - height = pTexture->GetHeight(); - } - -- if (!pTexture) return 0; -+ if (!pTexture) return emptyTexture; - - CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); - pMap->Add(pTexture, 100); -@@ -423,7 +420,7 @@ int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleO - OutputDebugString(temp); - #endif - -- return 1; -+ return pMap->GetTexture(); - } - - -diff --git a/xbmc/guilib/TextureManager.h b/xbmc/guilib/TextureManager.h -index c982e6a..22fc192 100644 ---- a/xbmc/guilib/TextureManager.h -+++ b/xbmc/guilib/TextureManager.h -@@ -108,8 +108,7 @@ class CGUITextureManager - - bool HasTexture(const CStdString &textureName, CStdString *path = NULL, int *bundle = NULL, int *size = NULL); - bool CanLoad(const CStdString &texturePath) const; ///< Returns true if the texture manager can load this texture -- int Load(const CStdString& strTextureName, bool checkBundleOnly = false); -- const CTextureArray& GetTexture(const CStdString& strTextureName); -+ const CTextureArray& Load(const CStdString& strTextureName, bool checkBundleOnly = false); - void ReleaseTexture(const CStdString& strTextureName); - void Cleanup(); - void Dump() const; --- -1.8.1.6 - - -From ece7ac520231ff144d7bc4d8393d1ca36f227927 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Tue, 30 Apr 2013 23:01:57 -0400 -Subject: [PATCH 2/2] texture: two texture speedups - -1. Check to see if we have a texture loaded already before opening/uploading - another instance of it. - -2. Set a time-out for deleting textures. If they are needed again before the - time-out expires, they are re-added to the loaded textures array and ready - for use again. Otherwise, they are deleted after X msec. This helps to avoid - doing _really_ nasty things, like re-loading the background image when - moving from home to settings. ---- - xbmc/Application.cpp | 2 +- - xbmc/guilib/TextureManager.cpp | 30 +++++++++++++++++++++++++----- - xbmc/guilib/TextureManager.h | 6 ++++-- - 3 files changed, 30 insertions(+), 8 deletions(-) - -diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 37d17e3..df456ec 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -4953,7 +4953,7 @@ void CApplication::ProcessSlow() - if (!IsPlayingVideo()) - g_largeTextureManager.CleanupUnusedImages(); - -- g_TextureManager.FreeUnusedTextures(); -+ g_TextureManager.FreeUnusedTextures(5000); - - #ifdef HAS_DVD_DRIVE - // checks whats in the DVD drive and tries to autostart the content (xbox games, dvd, cdda, avi files...) -diff --git a/xbmc/guilib/TextureManager.cpp b/xbmc/guilib/TextureManager.cpp -index 6d6c4d9..f214489 100644 ---- a/xbmc/guilib/TextureManager.cpp -+++ b/xbmc/guilib/TextureManager.cpp -@@ -29,6 +29,7 @@ - #ifdef _DEBUG - #include "utils/TimeUtils.h" - #endif -+#include "threads/SystemClock.h" - #include "filesystem/File.h" - #include "filesystem/Directory.h" - #include "URL.h" -@@ -298,6 +299,17 @@ bool CGUITextureManager::HasTexture(const CStdString &textureName, CStdString *p - return emptyTexture; - } - -+ for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); i++) -+ { -+ CTextureMap* pMap = i->first; -+ if (pMap->GetName() == strTextureName) -+ { -+ m_vecTextures.push_back(pMap); -+ m_unusedTextures.erase(i); -+ return pMap->GetTexture(); -+ } -+ } -+ - if (checkBundleOnly && bundle == -1) - return emptyTexture; - -@@ -439,7 +451,7 @@ void CGUITextureManager::ReleaseTexture(const CStdString& strTextureName) - { - //CLog::Log(LOGINFO, " cleanup:%s", strTextureName.c_str()); - // add to our textures to free -- m_unusedTextures.push_back(pMap); -+ m_unusedTextures.push_back(make_pair(pMap, XbmcThreads::SystemClockMillis())); - i = m_vecTextures.erase(i); - } - return; -@@ -449,12 +461,20 @@ void CGUITextureManager::ReleaseTexture(const CStdString& strTextureName) - CLog::Log(LOGWARNING, "%s: Unable to release texture %s", __FUNCTION__, strTextureName.c_str()); - } - --void CGUITextureManager::FreeUnusedTextures() -+void CGUITextureManager::FreeUnusedTextures(unsigned int timeDelay) - { -+ unsigned int currFrameTime = XbmcThreads::SystemClockMillis(); - CSingleLock lock(g_graphicsContext); -- for (ivecTextures i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i) -- delete *i; -- m_unusedTextures.clear(); -+ for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end();) -+ { -+ if (currFrameTime - i->second >= timeDelay) -+ { -+ delete i->first; -+ i = m_unusedTextures.erase(i); -+ } -+ else -+ i++; -+ } - - #if defined(HAS_GL) || defined(HAS_GLES) - for (unsigned int i = 0; i < m_unusedHwTextures.size(); ++i) -diff --git a/xbmc/guilib/TextureManager.h b/xbmc/guilib/TextureManager.h -index 22fc192..2633c39d 100644 ---- a/xbmc/guilib/TextureManager.h -+++ b/xbmc/guilib/TextureManager.h -@@ -27,6 +27,7 @@ - #define GUILIB_TEXTUREMANAGER_H - - #include -+#include - #include "TextureBundle.h" - #include "threads/CriticalSection.h" - -@@ -121,13 +122,14 @@ class CGUITextureManager - void SetTexturePath(const CStdString &texturePath); ///< Set a single path as the path to check when loading media (clear then add) - void RemoveTexturePath(const CStdString &texturePath); ///< Remove a path from the paths to check when loading media - -- void FreeUnusedTextures(); ///< Free textures (called from app thread only) -+ void FreeUnusedTextures(unsigned int timeDelay = 0); ///< Free textures (called from app thread only) - void ReleaseHwTexture(unsigned int texture); - protected: - std::vector m_vecTextures; -- std::vector m_unusedTextures; -+ std::list > m_unusedTextures; - std::vector m_unusedHwTextures; - typedef std::vector::iterator ivecTextures; -+ typedef std::list >::iterator ilistUnused; - // we have 2 texture bundles (one for the base textures, one for the theme) - CTextureBundle m_TexBundle[2]; - --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.11-PR2712.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.11-PR2712.patch deleted file mode 100644 index 63e296949..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.11-PR2712.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 101fbc2d6869d6f02c4345a232854dbbb3f1a855 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Thu, 2 May 2013 16:45:41 -0400 -Subject: [PATCH] build: stop using whole-archive for our final binary - -This nasty hack has been around for ages. By changing, we get the following -benefits: - -- We don't link in _every_ object in _every_ archive! -- Builds will no longer fail if a source file has been removed but its object - still exists in the archive -- Filesize reduction -- Ability to use lto, garbage collection, dead-code stripping, etc in a - useful manner - -This is achieved by specifying a main object on the link line, and using -start-group/end-group to search through the archives multiple times until each -symbol is found. ---- - Makefile.in | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/Makefile.in b/Makefile.in -index 3cbe1a2..f0827f2 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -92,6 +92,9 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \ - xbmc/windows/windows.a \ - xbmc/xbmc.a \ - -+ifneq (@USE_LIBXBMC@,1) -+DIRECTORY_ARCHIVES +=xbmc/main/main.a -+endif - - NWAOBJSXBMC= xbmc/threads/threads.a \ - xbmc/commons/commons.a -@@ -425,24 +428,29 @@ endif - - OBJSXBMC:=$(filter-out $(DYNOBJSXBMC), $(OBJSXBMC)) - --libxbmc.so: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) -+MAINOBJS=xbmc/xbmc.o -+ifeq (@USE_ANDROID@,1) -+MAINOBJS+=xbmc/android/activity/android_main.o -+endif -+ifneq (@USE_LIBXBMC@,1) -+MAINOBJS+=xbmc/main/main.o -+endif -+ -+libxbmc.so: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) - ifeq ($(findstring osx,@ARCH@), osx) - $(SILENT_LD) $(CXX) $(LDFLAGS) -bundle -o $@ -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) - else -- $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ -Wl,--whole-archive $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--no-whole-archive -Wl,--no-undefined $(NWAOBJSXBMC) $(LIBS) -+ $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ $(MAINOBJS) -Wl,--start-group $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group -Wl,--no-undefined $(NWAOBJSXBMC) $(LIBS) - endif - --xbmc.bin: xbmc/main/main.a $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) -+xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) - - ifeq ($(findstring osx,@ARCH@), osx) -- $(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) xbmc/main/main.a $(LIBS) -rdynamic -+ $(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic - else -- $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xbmc.bin -Wl,--whole-archive $(DYNOBJSXBMC) $(OBJSXBMC) xbmc/main/main.a -Wl,--no-whole-archive $(NWAOBJSXBMC) $(LIBS) -rdynamic -+ $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,--start-group $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group $(NWAOBJSXBMC) $(LIBS) -rdynamic - endif - --xbmc/main/main.a: force -- $(MAKE) -C xbmc/main -- - xbmc-xrandr: xbmc-xrandr.c - ifneq (1,@USE_XRANDR@) - # xbmc-xrandr.c gets picked up by the default make rules --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch deleted file mode 100644 index a57c5a8b3..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2570.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0aaeb72ed3d76134f11b80a4d17e50b40d6459be Mon Sep 17 00:00:00 2001 -From: hmis -Date: Mon, 8 Apr 2013 21:35:35 +0300 -Subject: [PATCH] Read CD audio USB drive bug fixed - -libcdio seems to allow read no more than about 10 audio sectors at once when CD audio device is connected via USB. -This patch makes XBMC read small number of sectors if default one fails. It uses more CPU but allows to use USB CD devices. -Tested on GNU/Linux x86 and RPi. (On Rpi OMXPlayer does not play CD, but I can rip tracks). ---- - xbmc/filesystem/CDDAFile.cpp | 34 +++++++++++++++++++++++++++------- - xbmc/filesystem/CDDAFile.h | 1 + - 2 files changed, 28 insertions(+), 7 deletions(-) - -diff --git a/xbmc/filesystem/CDDAFile.cpp b/xbmc/filesystem/CDDAFile.cpp -index 5342629..f5eaf37 100644 ---- a/xbmc/filesystem/CDDAFile.cpp -+++ b/xbmc/filesystem/CDDAFile.cpp -@@ -40,6 +40,7 @@ - m_lsnCurrent = CDIO_INVALID_LSN; - m_lsnEnd = CDIO_INVALID_LSN; - m_cdio = CLibcdio::GetInstance(); -+ m_iSectorCount = 52; - } - - CFileCDDA::~CFileCDDA(void) -@@ -120,7 +121,8 @@ unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) - if (!m_pCdIo || !g_mediaManager.IsDiscInDrive()) - return 0; - -- int iSectorCount = (int)uiBufSize / CDIO_CD_FRAMESIZE_RAW; -+ // limit number of sectors that fits in buffer by m_iSectorCount -+ int iSectorCount = std::min((int)uiBufSize / CDIO_CD_FRAMESIZE_RAW, m_iSectorCount); - - if (iSectorCount <= 0) - return 0; -@@ -129,14 +131,32 @@ unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize) - if (m_lsnCurrent + iSectorCount > m_lsnEnd) - iSectorCount = m_lsnEnd - m_lsnCurrent; - -- int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount); -- -- if ( iret != DRIVER_OP_SUCCESS) -+ // The loop tries to solve read error problem by lowering number of sectors to read (iSectorCount). -+ // When problem is solved the proper number of sectors is stored in m_iSectorCount -+ int big_iSectorCount = iSectorCount; -+ while (iSectorCount > 0) - { -- CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret); -- return 0; -+ int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount); -+ -+ if (iret == DRIVER_OP_SUCCESS) -+ { -+ // If lower iSectorCount solved the problem limit it's value -+ if (iSectorCount < big_iSectorCount) -+ { -+ m_iSectorCount = iSectorCount; -+ } -+ break; -+ } -+ -+ // iSectorCount is low so it cannot solve read problem -+ if (iSectorCount <= 10) -+ { -+ CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret); -+ return 0; -+ } -+ -+ iSectorCount = 10; - } -- - m_lsnCurrent += iSectorCount; - - return iSectorCount*CDIO_CD_FRAMESIZE_RAW; -diff --git a/xbmc/filesystem/CDDAFile.h b/xbmc/filesystem/CDDAFile.h -index f041e0b..72b8d5b 100644 ---- a/xbmc/filesystem/CDDAFile.h -+++ b/xbmc/filesystem/CDDAFile.h -@@ -53,6 +53,7 @@ class CFileCDDA : public IFile - lsn_t m_lsnStart; // Start of m_iTrack in logical sector number - lsn_t m_lsnCurrent; // Position inside the track in logical sector number - lsn_t m_lsnEnd; // End of m_iTrack in logical sector number -+ int m_iSectorCount; // max number of sectors to read at once - boost::shared_ptr m_cdio; - }; - } --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2586.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2586.patch deleted file mode 100644 index 63357752c..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.12-PR2586.patch +++ /dev/null @@ -1,555 +0,0 @@ -diff -Naur xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp ---- xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp 2013-05-10 07:16:56.061904946 +0200 -@@ -0,0 +1,180 @@ -+/* -+ * Copyright (C) 2013 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 "DVDInputStreams/DVDInputStream.h" -+#include "DVDDemuxCDDA.h" -+#include "DVDDemuxUtils.h" -+#include "utils/log.h" -+#include "../DVDClock.h" -+ -+// CDDA audio demuxer based on AirTunes audio Demuxer. -+ -+using namespace std; -+ -+class CDemuxStreamAudioCDDA -+ : public CDemuxStreamAudio -+{ -+public: -+ void GetStreamInfo(string& strInfo) -+ { -+ strInfo = "pcm"; -+ } -+}; -+ -+CDVDDemuxCDDA::CDVDDemuxCDDA() : CDVDDemux() -+{ -+ m_pInput = NULL; -+ m_stream = NULL; -+ m_bytes = 0; -+} -+ -+CDVDDemuxCDDA::~CDVDDemuxCDDA() -+{ -+ Dispose(); -+} -+ -+bool CDVDDemuxCDDA::Open(CDVDInputStream* pInput) -+{ -+ Abort(); -+ -+ Dispose(); -+ -+ if(!pInput || !pInput->IsStreamType(DVDSTREAM_TYPE_FILE)) -+ return false; -+ -+ m_pInput = pInput; -+ -+ m_stream = new CDemuxStreamAudioCDDA(); -+ -+ if(!m_stream) -+ return false; -+ -+ m_stream->iSampleRate = 44100; -+ m_stream->iBitsPerSample = 16; -+ m_stream->iBitRate = 44100 * 2 * 16; -+ m_stream->iChannels = 2; -+ m_stream->type = STREAM_AUDIO; -+ m_stream->codec = CODEC_ID_PCM_S16LE; -+ -+ return true; -+} -+ -+void CDVDDemuxCDDA::Dispose() -+{ -+ delete m_stream; -+ m_stream = NULL; -+ -+ m_pInput = NULL; -+ m_bytes = 0; -+} -+ -+void CDVDDemuxCDDA::Reset() -+{ -+ CDVDInputStream* pInputStream = m_pInput; -+ Dispose(); -+ Open(pInputStream); -+} -+ -+void CDVDDemuxCDDA::Abort() -+{ -+ if(m_pInput) -+ return m_pInput->Abort(); -+} -+ -+void CDVDDemuxCDDA::Flush() -+{ -+} -+ -+#define CDDA_READ_SIZE 4096 -+DemuxPacket* CDVDDemuxCDDA::Read() -+{ -+ if(!m_pInput) -+ return NULL; -+ -+ DemuxPacket* pPacket = CDVDDemuxUtils::AllocateDemuxPacket(CDDA_READ_SIZE); -+ -+ if (!pPacket) -+ { -+ if (m_pInput) -+ m_pInput->Close(); -+ return NULL; -+ } -+ -+ pPacket->iSize = m_pInput->Read(pPacket->pData, CDDA_READ_SIZE); -+ pPacket->iStreamId = 0; -+ -+ if(pPacket->iSize < 1) -+ { -+ delete pPacket; -+ pPacket = NULL; -+ } -+ else -+ { -+ int n = m_stream->iBitRate>>3; -+ if (n > 0) -+ { -+ m_bytes += pPacket->iSize; -+ pPacket->dts = (double)m_bytes * DVD_TIME_BASE / n; -+ pPacket->pts = pPacket->dts; -+ } -+ else -+ { -+ pPacket->dts = DVD_NOPTS_VALUE; -+ pPacket->pts = DVD_NOPTS_VALUE; -+ } -+ } -+ -+ return pPacket; -+} -+ -+int CDVDDemuxCDDA::GetStreamLength() -+{ -+ int64_t num_track_bytes = m_pInput->GetLength(); -+ int bytes_per_second = (m_stream->iBitRate>>3); -+ int64_t track_mseconds = num_track_bytes*1000 / bytes_per_second; -+ return (int)track_mseconds; -+} -+ -+CDemuxStream* CDVDDemuxCDDA::GetStream(int iStreamId) -+{ -+ if(iStreamId != 0) -+ return NULL; -+ -+ return m_stream; -+} -+ -+int CDVDDemuxCDDA::GetNrOfStreams() -+{ -+ return (m_stream == NULL ? 0 : 1); -+} -+ -+std::string CDVDDemuxCDDA::GetFileName() -+{ -+ if(m_pInput) -+ return m_pInput->GetFileName(); -+ else -+ return ""; -+} -+ -+void CDVDDemuxCDDA::GetStreamCodecName(int iStreamId, CStdString &strName) -+{ -+ if (m_stream && iStreamId == 0) -+ strName = "pcm"; -+} -diff -Naur xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h ---- xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h 1970-01-01 01:00:00.000000000 +0100 -+++ xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h 2013-05-10 07:16:56.061904946 +0200 -@@ -0,0 +1,59 @@ -+#pragma once -+/* -+ * Copyright (C) 2013 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 "DVDDemux.h" -+ -+#ifdef _WIN32 -+#define __attribute__(dummy_val) -+#else -+#include -+#endif -+ -+class CDemuxStreamAudioCDDA; -+ -+class CDVDDemuxCDDA : public CDVDDemux -+{ -+public: -+ -+ CDVDDemuxCDDA(); -+ ~CDVDDemuxCDDA(); -+ -+ bool Open(CDVDInputStream* pInput); -+ void Dispose(); -+ void Reset(); -+ void Abort(); -+ void Flush(); -+ DemuxPacket* Read(); -+ bool SeekTime(int time, bool backwords = false, double* startpts = NULL) { return false; }; -+ void SetSpeed(int iSpeed) {}; -+ int GetStreamLength() ; -+ CDemuxStream* GetStream(int iStreamId); -+ int GetNrOfStreams(); -+ std::string GetFileName(); -+ virtual void GetStreamCodecName(int iStreamId, CStdString &strName); -+ -+protected: -+ friend class CDemuxStreamAudioCDDA; -+ CDVDInputStream* m_pInput; -+ int64_t m_bytes; -+ -+ CDemuxStreamAudioCDDA *m_stream; -+}; -diff -Naur xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp ---- xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp 2013-05-02 17:00:07.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp 2013-05-10 07:16:56.061904946 +0200 -@@ -31,6 +31,7 @@ - #include "DVDDemuxHTSP.h" - #endif - #include "DVDDemuxBXA.h" -+#include "DVDDemuxCDDA.h" - #include "DVDDemuxPVRClient.h" - #include "pvr/PVRManager.h" - #include "pvr/addons/PVRClients.h" -@@ -51,6 +52,22 @@ - else - return NULL; - } -+ -+ // Try to open CDDA demuxer -+ if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FILE) && pInputStream->GetContent().compare("application/octet-stream") == 0) -+ { -+ std::string filename = pInputStream->GetFileName(); -+ if (filename.substr(0, 7) == "cdda://") -+ { -+ CLog::Log(LOGDEBUG, "DVDFactoryDemuxer: Stream is probably CD audio. Creating CDDA demuxer."); -+ -+ auto_ptr demuxer(new CDVDDemuxCDDA()); -+ if (demuxer->Open(pInputStream)) -+ { -+ return demuxer.release(); -+ } -+ } -+ } - - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_HTTP)) - { -diff -Naur xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp.orig xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp.orig -diff -Naur xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in ---- xbmc-12.2.0/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in 2013-05-02 17:00:07.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in 2013-05-10 07:16:56.061904946 +0200 -@@ -2,6 +2,7 @@ - - SRCS = DVDDemux.cpp - SRCS += DVDDemuxBXA.cpp -+SRCS += DVDDemuxCDDA.cpp - SRCS += DVDDemuxFFmpeg.cpp - SRCS += DVDDemuxHTSP.cpp - SRCS += DVDDemuxPVRClient.cpp -diff -Naur xbmc-12.2.0/xbmc/cores/paplayer/CDDAcodec.cpp xbmc-12.2.0.patch/xbmc/cores/paplayer/CDDAcodec.cpp ---- xbmc-12.2.0/xbmc/cores/paplayer/CDDAcodec.cpp 2013-05-02 17:00:08.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/paplayer/CDDAcodec.cpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,159 +0,0 @@ --/* -- * 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 "CDDAcodec.h" --#if !defined(TARGET_DARWIN_IOS) --#include --#else --typedef int32_t lsn_t; --#define CDIO_CD_FRAMESIZE_RAW 2352 --#define CDIO_CD_FRAMES_PER_SEC 75 --#endif --#include "cores/AudioEngine/Utils/AEUtil.h" -- --#define SECTOR_COUNT 55 // max. sectors that can be read at once --#define MAX_BUFFER_SIZE 2*SECTOR_COUNT*CDIO_CD_FRAMESIZE_RAW -- --CDDACodec::CDDACodec() --{ -- m_SampleRate = 44100; -- m_Channels = 2; -- m_BitsPerSample = 16; -- m_DataFormat = AE_FMT_S16NE; -- m_TotalTime = 0; -- m_Bitrate = 0; -- m_CodecName = "cdda"; -- -- m_BufferSize=0; -- m_Buffer = new BYTE[MAX_BUFFER_SIZE]; -- m_BufferPos = 0; --} -- --CDDACodec::~CDDACodec() --{ -- DeInit(); -- -- if (m_Buffer) -- { -- delete[] m_Buffer; -- m_Buffer = NULL; -- } --} -- --bool CDDACodec::Init(const CStdString &strFile, unsigned int filecache) --{ -- if (!m_file.Open(strFile, READ_CACHED)) -- return false; -- -- // Calculate total time of the track -- m_TotalTime=(m_file.GetLength()/CDIO_CD_FRAMESIZE_RAW)/CDIO_CD_FRAMES_PER_SEC; -- if (m_TotalTime > 0) -- m_Bitrate = (int)((m_file.GetLength() * 8) / m_TotalTime); -- else -- m_Bitrate = 0; -- m_TotalTime*=1000; // ms -- return true; --} -- --void CDDACodec::DeInit() --{ -- m_file.Close(); --} -- --int64_t CDDACodec::Seek(int64_t iSeekTime) --{ -- // Calculate the next full second... -- int iSeekTimeFullSec=(int)(iSeekTime+(1000-(iSeekTime%1000)))/1000; -- -- // ...and the logical sector on the cd... -- lsn_t lsnSeek=iSeekTimeFullSec*CDIO_CD_FRAMES_PER_SEC; -- -- // ... then seek to its position... -- int iNewOffset=(int)m_file.Seek(lsnSeek*CDIO_CD_FRAMESIZE_RAW, SEEK_SET); -- m_BufferSize=m_BufferPos=0; -- -- // ... and look if we really got there. -- int iNewSeekTime=(iNewOffset/CDIO_CD_FRAMESIZE_RAW)/CDIO_CD_FRAMES_PER_SEC; -- return iNewSeekTime*(int64_t)1000; // ms --} -- --int CDDACodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize) --{ -- *actualsize=0; -- -- bool bEof=false; -- // Reached end of track? -- if (m_file.GetLength()==m_file.GetPosition()) -- bEof=true; -- -- // Do we have to refill our audio buffer? -- if (m_BufferSize-m_BufferPos=size) -- { // we have enough data in our buffer -- memcpy(pBuffer, m_Buffer + m_BufferPos, size); -- m_BufferPos+=size; -- *actualsize=size; -- } -- else -- { // Only a smaller amount of data left as the player wants -- memcpy(pBuffer, m_Buffer + m_BufferPos, m_BufferSize-m_BufferPos); -- *actualsize=m_BufferSize-m_BufferPos; -- m_BufferPos+=m_BufferSize-m_BufferPos; -- } -- -- return READ_SUCCESS; --} -- --bool CDDACodec::CanInit() --{ -- return true; --} -- --CAEChannelInfo CDDACodec::GetChannelInfo() --{ -- static enum AEChannel map[2][3] = { -- {AE_CH_FC, AE_CH_NULL}, -- {AE_CH_FL, AE_CH_FR , AE_CH_NULL} -- }; -- -- if (m_Channels > 2) -- return CAEUtil::GuessChLayout(m_Channels); -- -- return CAEChannelInfo(map[m_Channels - 1]); --} -diff -Naur xbmc-12.2.0/xbmc/cores/paplayer/CDDAcodec.h xbmc-12.2.0.patch/xbmc/cores/paplayer/CDDAcodec.h ---- xbmc-12.2.0/xbmc/cores/paplayer/CDDAcodec.h 2013-05-02 17:00:08.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/paplayer/CDDAcodec.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,43 +0,0 @@ --#pragma once -- --/* -- * 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 "CachingCodec.h" -- --class CDDACodec : public CachingCodec --{ --public: -- CDDACodec(); -- virtual ~CDDACodec(); -- -- virtual bool Init(const CStdString &strFile, unsigned int filecache); -- virtual void DeInit(); -- virtual int64_t Seek(int64_t iSeekTime); -- virtual int ReadPCM(BYTE *pBuffer, int size, int *actualsize); -- virtual bool CanInit(); -- virtual CAEChannelInfo GetChannelInfo(); -- --private: -- // Input buffer to read our cdda data into -- BYTE* m_Buffer; -- int m_BufferSize; -- int m_BufferPos; --}; -diff -Naur xbmc-12.2.0/xbmc/cores/paplayer/CodecFactory.cpp xbmc-12.2.0.patch/xbmc/cores/paplayer/CodecFactory.cpp ---- xbmc-12.2.0/xbmc/cores/paplayer/CodecFactory.cpp 2013-05-02 17:00:08.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/paplayer/CodecFactory.cpp 2013-05-10 07:16:56.061904946 +0200 -@@ -21,7 +21,6 @@ - #include "system.h" - #include "CodecFactory.h" - #include "MP3codec.h" --#include "CDDAcodec.h" - #include "OGGcodec.h" - #include "FLACcodec.h" - #include "WAVcodec.h" -@@ -51,7 +50,7 @@ - else if (strFileType.Equals("ape") || strFileType.Equals("mac")) - return new DVDPlayerCodec(); - else if (strFileType.Equals("cdda")) -- return new CDDACodec(); -+ return new DVDPlayerCodec(); - else if (strFileType.Equals("mpc") || strFileType.Equals("mp+") || strFileType.Equals("mpp")) - return new DVDPlayerCodec(); - else if (strFileType.Equals("shn")) -@@ -183,20 +182,6 @@ - } - delete codec; - } -- if (urlFile.GetFileType().Equals("cdda")) -- { -- //lets see what it contains... -- //this kinda sucks 'cause if it's plain cdda the file -- //will be opened, sniffed and closed before it is opened *again* for cdda -- //would be better if the papcodecs could work with bitstreams instead of filenames. -- DVDPlayerCodec *dvdcodec = new DVDPlayerCodec(); -- dvdcodec->SetContentType("audio/x-spdif-compressed"); -- if (dvdcodec->Init(strFile, filecache)) -- { -- return dvdcodec; -- } -- delete dvdcodec; -- } - else if (urlFile.GetFileType().Equals("ogg") || urlFile.GetFileType().Equals("oggstream") || urlFile.GetFileType().Equals("oga")) - return CreateOGGCodec(strFile,filecache); - -diff -Naur xbmc-12.2.0/xbmc/cores/paplayer/Makefile.in xbmc-12.2.0.patch/xbmc/cores/paplayer/Makefile.in ---- xbmc-12.2.0/xbmc/cores/paplayer/Makefile.in 2013-05-02 17:00:08.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/paplayer/Makefile.in 2013-05-10 07:16:56.062904942 +0200 -@@ -9,7 +9,6 @@ - - SRCS = ADPCMCodec.cpp - SRCS += AudioDecoder.cpp --SRCS += CDDAcodec.cpp - SRCS += CodecFactory.cpp - SRCS += DVDPlayerCodec.cpp - SRCS += FLACcodec.cpp diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.13-RPB-Fix_for_hang_following_seek_after_eos.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.13-RPB-Fix_for_hang_following_seek_after_eos.patch deleted file mode 100644 index b259666b7..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.13-RPB-Fix_for_hang_following_seek_after_eos.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 5b75f44b448bcefb9b802a3a28d0e6846284d22e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 6 May 2013 14:20:05 +0100 -Subject: [PATCH] [rbp/omxplayer] Fix for hang following seek after eos - -If you seek after the demuxer eof, the eof state is cleared, but we are not clearing the flags relating to sending eos stream to audio/video players ---- - xbmc/cores/omxplayer/OMXPlayer.cpp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index 156a3ad..82d0024 100644 ---- a/xbmc/cores/omxplayer/OMXPlayer.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp -@@ -1178,7 +1178,13 @@ void COMXPlayer::Process() - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - continue; - } -- -+ if (pPacket) -+ { -+ // reset eos state when we get a packet (e.g. for case of seek after eos) -+ bOmxWaitVideo = false; -+ bOmxWaitAudio = false; -+ bOmxSentEOFs = false; -+ } - if (!pPacket) - { - // when paused, demuxer could be be returning empty --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.14-PR2700.patch.bk b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.14-PR2700.patch.bk deleted file mode 100644 index 0ac0d2cc1..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.14-PR2700.patch.bk +++ /dev/null @@ -1,322 +0,0 @@ -From 85891c135b848d8f11a5410d867f67e0515d3d0b Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Sun, 17 Mar 2013 19:04:52 +0100 -Subject: [PATCH 1/3] dvdplayer: move CanSeek/CanPause to seekable interface - ---- - .../dvdplayer/DVDInputStreams/DVDInputStream.h | 8 ++++++++ - .../DVDInputStreams/DVDInputStreamPVRManager.h | 1 + - xbmc/cores/dvdplayer/DVDPlayer.cpp | 22 +++++++++++----------- - 3 files changed, 20 insertions(+), 11 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -index b3b7ae3..a5ee3ae 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -@@ -122,6 +122,14 @@ class CDVDInputStream - virtual double GetTimeStampCorrection() = 0; - }; - -+ class ISeekable -+ { -+ public: -+ virtual ~ISeekable() {}; -+ virtual bool CanSeek() = 0; -+ virtual bool CanPause() = 0; -+ }; -+ - enum ENextStream - { - NEXTSTREAM_NONE, -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.h -index 79389a4..89f05a7 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.h -@@ -39,6 +39,7 @@ class CDVDInputStreamPVRManager - : public CDVDInputStream - , public CDVDInputStream::IChannel - , public CDVDInputStream::IDisplayTime -+ , public CDVDInputStream::ISeekable - { - public: - CDVDInputStreamPVRManager(IDVDPlayer* pPlayer); -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index e5a1e71..5baf57a 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -3833,6 +3833,9 @@ void CDVDPlayer::UpdatePlayState(double timeout) - state.time_src = ETIMESOURCE_CLOCK; - } - -+ state.canpause = true; -+ state.canseek = true; -+ - if(m_pInputStream) - { - // override from input stream if needed -@@ -3861,16 +3864,10 @@ void CDVDPlayer::UpdatePlayState(double timeout) - } - } - -- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) -- { -- CDVDInputStreamPVRManager* pvrinputstream = static_cast(m_pInputStream); -- state.canpause = pvrinputstream->CanPause(); -- state.canseek = pvrinputstream->CanSeek(); -- } -- else -+ if (CDVDInputStream::ISeekable* ptr = dynamic_cast(m_pInputStream)) - { -- state.canseek = state.time_total > 0 ? true : false; -- state.canpause = true; -+ state.canpause = ptr->CanPause(); -+ state.canseek = ptr->CanSeek(); - } - } - -@@ -3880,10 +3877,13 @@ void CDVDPlayer::UpdatePlayState(double timeout) - state.time_total = m_Edl.RemoveCutTime(llrint(state.time_total)); - } - -+ if(state.time_total <= 0) -+ state.canseek = false; -+ - state.player_state = ""; -- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) -+ if(CDVDInputStreamNavigator* ptr = dynamic_cast(m_pInputStream)) - { -- if(!((CDVDInputStreamNavigator*)m_pInputStream)->GetNavigatorState(state.player_state)) -+ if(!ptr->GetNavigatorState(state.player_state)) - state.player_state = ""; - } - --- -1.8.1.6 - - -From c817ed00d875174b6789621aba4dc15123c4f3bd Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Sun, 17 Mar 2013 19:15:13 +0100 -Subject: [PATCH 2/3] dvdplayer: disable seeking and pause for udp/rtp and seek - for tcp - ---- - .../dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp | 17 +++++++++++++++++ - .../dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h | 9 ++++++++- - 2 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp -index 72ea5f8..fb5001a 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp -@@ -47,7 +47,24 @@ bool CDVDInputStreamFFmpeg::Open(const char* strFile, const std::string& content - if (!CDVDInputStream::Open(strFile, content)) - return false; - -+ m_can_pause = true; -+ m_can_seek = true; -+ -+ if(strnicmp(strFile, "udp://", 6) == 0 -+ || strnicmp(strFile, "rtp://", 6) == 0) -+ { -+ m_can_pause = false; -+ m_can_seek = false; -+ } -+ -+ if(strnicmp(strFile, "tcp://", 6) == 0) -+ { -+ m_can_pause = true; -+ m_can_seek = false; -+ } -+ - m_aborted = false; -+ - return true; - } - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h -index 6149233..cf80e8f 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.h -@@ -22,7 +22,9 @@ - - #include "DVDInputStream.h" - --class CDVDInputStreamFFmpeg : public CDVDInputStream -+class CDVDInputStreamFFmpeg -+ : public CDVDInputStream -+ , public CDVDInputStream::ISeekable - { - public: - CDVDInputStreamFFmpeg(); -@@ -38,6 +40,11 @@ class CDVDInputStreamFFmpeg : public CDVDInputStream - virtual void Abort() { m_aborted = true; } - bool Aborted() { return m_aborted; } - -+ bool CanSeek() { return m_can_seek; } -+ bool CanPause() { return m_can_pause; } -+ - protected: - bool m_aborted; -+ bool m_can_pause; -+ bool m_can_seek; - }; --- -1.8.1.6 - - -From 20562d6450d481967833de7895cd27352a4fdea1 Mon Sep 17 00:00:00 2001 -From: Wolfgang Haupt -Date: Tue, 7 May 2013 09:43:03 +0200 -Subject: [PATCH 3/3] dvdplayer: move navigator state into IMenus - ---- - .../dvdplayer/DVDInputStreams/DVDInputStream.h | 2 ++ - .../DVDInputStreams/DVDInputStreamBluray.h | 2 ++ - .../DVDInputStreams/DVDInputStreamNavigator.cpp | 4 +-- - .../DVDInputStreams/DVDInputStreamNavigator.h | 4 +-- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 38 ++++++++++------------ - 5 files changed, 25 insertions(+), 25 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -index a5ee3ae..76414b2 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h -@@ -120,6 +120,8 @@ class CDVDInputStream - virtual bool OnMouseClick(const CPoint &point) = 0; - virtual bool IsInMenu() = 0; - virtual double GetTimeStampCorrection() = 0; -+ virtual bool GetState(std::string &xmlstate) { return false; } -+ virtual bool SetState(const std::string &xmlstate) { return false; } - }; - - class ISeekable -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h -index 6897d0f..a7d8f6b 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h -@@ -81,6 +81,8 @@ class CDVDInputStreamBluray - virtual bool OnMouseMove(const CPoint &point) { return false; } - virtual bool OnMouseClick(const CPoint &point) { return false; } - virtual double GetTimeStampCorrection() { return 0.0; } -+ virtual bool GetState(std::string &xmlstate) { return false; } -+ virtual bool SetState(const std::string &xmlstate) { return false; } - - void UserInput(bd_vk_key_e vk); - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp -index 9cd8cf9..102b862 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp -@@ -1144,7 +1144,7 @@ bool CDVDInputStreamNavigator::IsSubtitleStreamEnabled() - return false; - } - --bool CDVDInputStreamNavigator::GetNavigatorState(std::string &xmlstate) -+bool CDVDInputStreamNavigator::GetState(std::string &xmlstate) - { - if( !m_dvdnav ) - return false; -@@ -1165,7 +1165,7 @@ bool CDVDInputStreamNavigator::GetNavigatorState(std::string &xmlstate) - return true; - } - --bool CDVDInputStreamNavigator::SetNavigatorState(std::string &xmlstate) -+bool CDVDInputStreamNavigator::SetState(const std::string &xmlstate) - { - if( !m_dvdnav ) - return false; -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h -index 0c16642..45b2632 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h -@@ -108,8 +108,8 @@ class CDVDInputStreamNavigator - int GetAudioStreamCount(); - bool SetActiveAudioStream(int iId); - -- bool GetNavigatorState(std::string &xmlstate); -- bool SetNavigatorState(std::string &xmlstate); -+ bool GetState(std::string &xmlstate); -+ bool SetState(const std::string &xmlstate); - - int GetChapter() { return m_iPart; } // the current part in the current title - int GetChapterCount() { return m_iPartCount; } // the number of parts in the current title -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 5baf57a..cb8a62b 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -936,16 +936,15 @@ void CDVDPlayer::Process() - return; - } - -- if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) -+ if (CDVDInputStream::IMenus* ptr = dynamic_cast(m_pInputStream)) - { -- CLog::Log(LOGNOTICE, "DVDPlayer: playing a dvd with menu's"); -+ CLog::Log(LOGNOTICE, "DVDPlayer: playing a file with menu's"); - m_PlayerOptions.starttime = 0; - -- - if(m_PlayerOptions.state.size() > 0) -- ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(m_PlayerOptions.state); -- else -- ((CDVDInputStreamNavigator*)m_pInputStream)->EnableSubtitleStream(g_settings.m_currentVideoSettings.m_SubtitleOn); -+ ptr->SetState(m_PlayerOptions.state); -+ else if(CDVDInputStreamNavigator* nav = dynamic_cast(m_pInputStream)) -+ nav->EnableSubtitleStream(g_settings.m_currentVideoSettings.m_SubtitleOn); - - g_settings.m_currentVideoSettings.m_SubtitleCached = true; - } -@@ -2147,13 +2146,14 @@ void CDVDPlayer::HandleMessages() - - CDVDMsgPlayerSetState* pMsgPlayerSetState = (CDVDMsgPlayerSetState*)pMsg; - -- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) -+ if (CDVDInputStream::IMenus* ptr = dynamic_cast(m_pInputStream)) - { -- std::string s = pMsgPlayerSetState->GetState(); -- ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(s); -- m_dvd.state = DVDSTATE_NORMAL; -- m_dvd.iDVDStillStartTime = 0; -- m_dvd.iDVDStillTime = 0; -+ if(ptr->SetState(pMsgPlayerSetState->GetState())) -+ { -+ m_dvd.state = DVDSTATE_NORMAL; -+ m_dvd.iDVDStillStartTime = 0; -+ m_dvd.iDVDStillTime = 0; -+ } - } - - g_infoManager.SetDisplayAfterSeek(); -@@ -3853,9 +3853,12 @@ void CDVDPlayer::UpdatePlayState(double timeout) - state.time_total = pDisplayTime->GetTotalTime(); - state.time_src = ETIMESOURCE_INPUT; - } -- -- if (dynamic_cast(m_pInputStream)) -+ -+ if (CDVDInputStream::IMenus* ptr = dynamic_cast(m_pInputStream)) - { -+ if(!ptr->GetState(state.player_state)) -+ state.player_state = ""; -+ - if(m_dvd.state == DVDSTATE_STILL) - { - state.time = XbmcThreads::SystemClockMillis() - m_dvd.iDVDStillStartTime; -@@ -3880,13 +3883,6 @@ void CDVDPlayer::UpdatePlayState(double timeout) - if(state.time_total <= 0) - state.canseek = false; - -- state.player_state = ""; -- if(CDVDInputStreamNavigator* ptr = dynamic_cast(m_pInputStream)) -- { -- if(!ptr->GetNavigatorState(state.player_state)) -- state.player_state = ""; -- } -- - if (state.time_src == ETIMESOURCE_CLOCK) - state.time_offset = m_offset_pts; - else --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch deleted file mode 100644 index 4eeb6cd46..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch +++ /dev/null @@ -1,456 +0,0 @@ -From 0c2eaf5082a30fb06bad553775e805a745d59ee2 Mon Sep 17 00:00:00 2001 -From: theuni -Date: Tue, 22 Jan 2013 04:09:07 -0500 -Subject: [PATCH] depends: mark our wrapped functions as used - -otherwise they get stripped when enabling dead code stripping ---- - xbmc/cores/DllLoader/exports/wrapper.c | 138 ++++++++++++++++----------------- - 1 file changed, 69 insertions(+), 69 deletions(-) - -diff --git a/xbmc/cores/DllLoader/exports/wrapper.c b/xbmc/cores/DllLoader/exports/wrapper.c -index cb7bbf7..67189e9 100644 ---- a/xbmc/cores/DllLoader/exports/wrapper.c -+++ b/xbmc/cores/DllLoader/exports/wrapper.c -@@ -115,7 +115,7 @@ - int dll_setvbuf(FILE *stream, char *buf, int type, size_t size); - struct mntent *dll_getmntent(FILE *fp); - --void *__wrap_dlopen(const char *filename, int flag) -+__attribute__((used)) void *__wrap_dlopen(const char *filename, int flag) - { - #if defined(TARGET_ANDROID) - return dll_dlopen(filename, flag); -@@ -124,213 +124,213 @@ void *__wrap_dlopen(const char *filename, int flag) - #endif - } - --FILE *__wrap_popen(const char *command, const char *mode) -+__attribute__((used)) FILE *__wrap_popen(const char *command, const char *mode) - { - return dll_popen(command, mode); - } - --void* __wrap_calloc( size_t num, size_t size ) -+__attribute__((used)) void* __wrap_calloc( size_t num, size_t size ) - { - return dllcalloc(num, size); - } - --void* __wrap_malloc(size_t size) -+__attribute__((used)) void* __wrap_malloc(size_t size) - { - return dllmalloc(size); - } - --void* __wrap_realloc( void *memblock, size_t size ) -+__attribute__((used)) void* __wrap_realloc( void *memblock, size_t size ) - { - return dllrealloc(memblock, size); - } - --void __wrap_free( void* pPtr ) -+__attribute__((used)) void __wrap_free( void* pPtr ) - { - dllfree(pPtr); - } - --int __wrap_open(const char *file, int oflag, ...) -+__attribute__((used)) int __wrap_open(const char *file, int oflag, ...) - { - return dll_open(file, oflag); - } - --int __wrap_open64(const char *file, int oflag, ...) -+__attribute__((used)) int __wrap_open64(const char *file, int oflag, ...) - { - return dll_open(file, oflag); - } - --int __wrap_close(int fd) -+__attribute__((used)) int __wrap_close(int fd) - { - return dll_close(fd); - } - --ssize_t __wrap_write(int fd, const void *buf, size_t count) -+__attribute__((used)) ssize_t __wrap_write(int fd, const void *buf, size_t count) - { - return dll_write(fd, buf, count); - } - --ssize_t __wrap_read(int fd, void *buf, size_t count) -+__attribute__((used)) ssize_t __wrap_read(int fd, void *buf, size_t count) - { - return dll_read(fd, buf, count); - } - --__off_t __wrap_lseek(int fildes, __off_t offset, int whence) -+__attribute__((used)) __off_t __wrap_lseek(int fildes, __off_t offset, int whence) - { - return dll_lseek(fildes, offset, whence); - } - --__off64_t __wrap_lseek64(int fildes, __off64_t offset, int whence) -+__attribute__((used)) __off64_t __wrap_lseek64(int fildes, __off64_t offset, int whence) - { - __off64_t seekRes = dll_lseeki64(fildes, offset, whence); - return seekRes; - } - --int __wrap_fclose(FILE *fp) -+__attribute__((used)) int __wrap_fclose(FILE *fp) - { - return dll_fclose(fp); - } - --int __wrap_ferror(FILE *stream) -+__attribute__((used)) int __wrap_ferror(FILE *stream) - { - return dll_ferror(stream); - } - --void __wrap_clearerr(FILE *stream) -+__attribute__((used)) void __wrap_clearerr(FILE *stream) - { - return dll_clearerr(stream); - } - --int __wrap_feof(FILE *stream) -+__attribute__((used)) int __wrap_feof(FILE *stream) - { - return dll_feof(stream); - } - --int __wrap_fileno(FILE *stream) -+__attribute__((used)) int __wrap_fileno(FILE *stream) - { - return dll_fileno(stream); - } - --FILE *__wrap_fopen(const char *path, const char *mode) -+__attribute__((used)) FILE *__wrap_fopen(const char *path, const char *mode) - { - return dll_fopen(path, mode); - } - --FILE *__wrap_fopen64(const char *path, const char *mode) -+__attribute__((used)) FILE *__wrap_fopen64(const char *path, const char *mode) - { - return dll_fopen(path, mode); - } - --FILE *__wrap_fdopen(int fildes, const char *mode) -+__attribute__((used)) FILE *__wrap_fdopen(int fildes, const char *mode) - { - return dll_fdopen(fildes, mode); - } - --FILE *__wrap_freopen(const char *path, const char *mode, FILE *stream) -+__attribute__((used)) FILE *__wrap_freopen(const char *path, const char *mode, FILE *stream) - { - return dll_freopen(path, mode, stream); - } - --size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) -+__attribute__((used)) size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) - { - return dll_fread(ptr, size, nmemb, stream); - } - --size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) -+__attribute__((used)) size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) - { - return dll_fwrite(ptr, size, nmemb, stream); - } - --int __wrap_fflush(FILE *stream) -+__attribute__((used)) int __wrap_fflush(FILE *stream) - { - return dll_fflush(stream); - } - --int __wrap_fputc(int c, FILE *stream) -+__attribute__((used)) int __wrap_fputc(int c, FILE *stream) - { - return dll_fputc(c, stream); - } - --int __wrap_fputs(const char *s, FILE *stream) -+__attribute__((used)) int __wrap_fputs(const char *s, FILE *stream) - { - return dll_fputs(s, stream); - } - --int __wrap__IO_putc(int c, FILE *stream) -+__attribute__((used)) int __wrap__IO_putc(int c, FILE *stream) - { - return dll_putc(c, stream); - } - --int __wrap_fseek(FILE *stream, long offset, int whence) -+__attribute__((used)) int __wrap_fseek(FILE *stream, long offset, int whence) - { - return dll_fseek(stream, offset, whence); - } - --int __wrap_fseeko64(FILE *stream, off64_t offset, int whence) -+__attribute__((used)) int __wrap_fseeko64(FILE *stream, off64_t offset, int whence) - { - return dll_fseek64(stream, offset, whence); - } - --long __wrap_ftell(FILE *stream) -+__attribute__((used)) long __wrap_ftell(FILE *stream) - { - return dll_ftell(stream); - } - --off64_t __wrap_ftello64(FILE *stream) -+__attribute__((used)) off64_t __wrap_ftello64(FILE *stream) - { - return dll_ftell64(stream); - } - --void __wrap_rewind(FILE *stream) -+__attribute__((used)) void __wrap_rewind(FILE *stream) - { - dll_rewind(stream); - } - --int __wrap_fgetpos(FILE *stream, fpos_t *pos) -+__attribute__((used)) int __wrap_fgetpos(FILE *stream, fpos_t *pos) - { - return dll_fgetpos(stream, pos); - } - --int __wrap_fgetpos64(FILE *stream, fpos64_t *pos) -+__attribute__((used)) int __wrap_fgetpos64(FILE *stream, fpos64_t *pos) - { - return dll_fgetpos64(stream, pos); - } - --int __wrap_fsetpos(FILE *stream, fpos_t *pos) -+__attribute__((used)) int __wrap_fsetpos(FILE *stream, fpos_t *pos) - { - return dll_fsetpos(stream, pos); - } - --int __wrap_fsetpos64(FILE *stream, fpos64_t *pos) -+__attribute__((used)) int __wrap_fsetpos64(FILE *stream, fpos64_t *pos) - { - return dll_fsetpos64(stream, pos); - } - --DIR * __wrap_opendir(const char *name) -+__attribute__((used)) DIR * __wrap_opendir(const char *name) - { - return dll_opendir(name); - } - --struct dirent * __wrap_readdir(DIR* dirp) -+__attribute__((used)) struct dirent * __wrap_readdir(DIR* dirp) - { - return dll_readdir(dirp); - } - --struct dirent * __wrap_readdir64(DIR* dirp) -+__attribute__((used)) struct dirent * __wrap_readdir64(DIR* dirp) - { - return dll_readdir(dirp); - } - --int __wrap_closedir(DIR* dirp) -+__attribute__((used)) int __wrap_closedir(DIR* dirp) - { - return dll_closedir(dirp); - } - --void __wrap_rewinddir(DIR* dirp) -+__attribute__((used)) void __wrap_rewinddir(DIR* dirp) - { - dll_rewinddir(dirp); - } - --int __wrap_fprintf(FILE *stream, const char *format, ...) -+__attribute__((used)) int __wrap_fprintf(FILE *stream, const char *format, ...) - { - int res; - va_list va; -@@ -340,12 +340,12 @@ int __wrap_fprintf(FILE *stream, const char *format, ...) - return res; - } - --int __wrap_vfprintf(FILE *stream, const char *format, va_list ap) -+__attribute__((used)) int __wrap_vfprintf(FILE *stream, const char *format, va_list ap) - { - return dll_vfprintf(stream, format, ap); - } - --int __wrap_printf(const char *format, ...) -+__attribute__((used)) int __wrap_printf(const char *format, ...) - { - int res; - va_list va; -@@ -355,42 +355,42 @@ int __wrap_printf(const char *format, ...) - return res; - } - --int __wrap_fgetc(FILE *stream) -+__attribute__((used)) int __wrap_fgetc(FILE *stream) - { - return dll_fgetc(stream); - } - --char *__wrap_fgets(char *s, int size, FILE *stream) -+__attribute__((used)) char *__wrap_fgets(char *s, int size, FILE *stream) - { - return dll_fgets(s, size, stream); - } - --int __wrap__IO_getc(FILE *stream) -+__attribute__((used)) int __wrap__IO_getc(FILE *stream) - { - return dll_getc(stream); - } - --int __wrap__IO_getc_unlocked(FILE *stream) -+__attribute__((used)) int __wrap__IO_getc_unlocked(FILE *stream) - { - return dll_getc(stream); - } - --int __wrap_getc_unlocked(FILE *stream) -+__attribute__((used)) int __wrap_getc_unlocked(FILE *stream) - { - return dll_getc(stream); - } - --int __wrap_ungetc(int c, FILE *stream) -+__attribute__((used)) int __wrap_ungetc(int c, FILE *stream) - { - return dll_ungetc(c, stream); - } - --int __wrap_getc(FILE *stream) -+__attribute__((used)) int __wrap_getc(FILE *stream) - { - return dll_getc(stream); - } - --int __wrap_ioctl(int d, unsigned long int request, ...) -+__attribute__((used)) int __wrap_ioctl(int d, unsigned long int request, ...) - { - int res; - va_list va; -@@ -400,52 +400,52 @@ int __wrap_ioctl(int d, unsigned long int request, ...) - return res; - } - --int __wrap__stat(const char *path, struct _stat *buffer) -+__attribute__((used)) int __wrap__stat(const char *path, struct _stat *buffer) - { - return dll_stat(path, buffer); - } - --int __wrap___xstat64(int __ver, const char *__filename, struct stat64 *__stat_buf) -+__attribute__((used)) int __wrap___xstat64(int __ver, const char *__filename, struct stat64 *__stat_buf) - { - return dll_stat64(__filename, __stat_buf); - } - --int __wrap___lxstat64(int __ver, const char *__filename, struct stat64 *__stat_buf) -+__attribute__((used)) int __wrap___lxstat64(int __ver, const char *__filename, struct stat64 *__stat_buf) - { - return dll_stat64(__filename, __stat_buf); - } - --void __wrap_flockfile(FILE *file) -+__attribute__((used)) void __wrap_flockfile(FILE *file) - { - dll_flockfile(file); - } - --int __wrap_ftrylockfile(FILE *file) -+__attribute__((used)) int __wrap_ftrylockfile(FILE *file) - { - return dll_ftrylockfile(file); - } - --void __wrap_funlockfile(FILE *file) -+__attribute__((used)) void __wrap_funlockfile(FILE *file) - { - dll_funlockfile(file); - } - --int __wrap___fxstat64(int ver, int fd, struct stat64 *buf) -+__attribute__((used)) int __wrap___fxstat64(int ver, int fd, struct stat64 *buf) - { - return dll_fstat64(fd, buf); - } - --int __wrap_fstat(int fd, struct _stat *buf) -+__attribute__((used)) int __wrap_fstat(int fd, struct _stat *buf) - { - return dll_fstat(fd, buf); - } - --int __wrap_setvbuf(FILE *stream, char *buf, int type, size_t size) -+__attribute__((used)) int __wrap_setvbuf(FILE *stream, char *buf, int type, size_t size) - { - return dll_setvbuf(stream, buf, type, size); - } - --struct mntent *__wrap_getmntent(FILE *fp) -+__attribute__((used)) struct mntent *__wrap_getmntent(FILE *fp) - { - #ifdef _LINUX - return dll_getmntent(fp); -@@ -459,12 +459,12 @@ struct mntent *__wrap_getmntent(FILE *fp) - // thing to actually call our wrapped functions. - #if _FORTIFY_SOURCE > 1 - --size_t __wrap___fread_chk(void * ptr, size_t ptrlen, size_t size, size_t n, FILE * stream) -+__attribute__((used)) size_t __wrap___fread_chk(void * ptr, size_t ptrlen, size_t size, size_t n, FILE * stream) - { - return dll_fread(ptr, size, n, stream); - } - --int __wrap___printf_chk(int flag, const char *format, ...) -+__attribute__((used)) int __wrap___printf_chk(int flag, const char *format, ...) - { - int res; - va_list va; -@@ -474,12 +474,12 @@ int __wrap___printf_chk(int flag, const char *format, ...) - return res; - } - --int __wrap___vfprintf_chk(FILE* stream, int flag, const char *format, _G_va_list ap) -+__attribute__((used)) int __wrap___vfprintf_chk(FILE* stream, int flag, const char *format, _G_va_list ap) - { - return dll_vfprintf(stream, format, ap); - } - --int __wrap___fprintf_chk(FILE * stream, int flag, const char *format, ...) -+__attribute__((used)) int __wrap___fprintf_chk(FILE * stream, int flag, const char *format, ...) - { - int res; - va_list va; -@@ -489,12 +489,12 @@ int __wrap___fprintf_chk(FILE * stream, int flag, const char *format, ...) - return res; - } - --char *__wrap___fgets_chk(char *s, size_t size, int n, FILE *stream) -+__attribute__((used)) char *__wrap___fgets_chk(char *s, size_t size, int n, FILE *stream) - { - return dll_fgets(s, n, stream); - } - --size_t __wrap___read_chk(int fd, void *buf, size_t nbytes, size_t buflen) -+__attribute__((used)) size_t __wrap___read_chk(int fd, void *buf, size_t nbytes, size_t buflen) - { - return dll_read(fd, buf, nbytes); - } --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.16-XB822abd9.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.16-XB822abd9.patch deleted file mode 100644 index 0fd16ed00..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.16-XB822abd9.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 822abd913ab38a742f710173f551bac22477eebd Mon Sep 17 00:00:00 2001 -From: Lee Pollock -Date: Wed, 8 May 2013 18:04:41 +0100 -Subject: [PATCH] [Fix] Re-get details from nfo file after advancing to first - episodedetails - ---- - xbmc/NfoFile.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/NfoFile.cpp b/xbmc/NfoFile.cpp -index 973e4d0..791c92e 100644 ---- a/xbmc/NfoFile.cpp -+++ b/xbmc/NfoFile.cpp -@@ -71,6 +71,7 @@ - { - int infos=0; - m_headofdoc = strstr(m_headofdoc," -Date: Sat, 11 May 2013 06:03:55 +0800 -Subject: [PATCH] Fix color index overflow by reuse existed color in the - vector. Fix #14293 - ---- - xbmc/guilib/GUITextLayout.cpp | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/xbmc/guilib/GUITextLayout.cpp b/xbmc/guilib/GUITextLayout.cpp -index 33c8c48..8dc8b45 100644 ---- a/xbmc/guilib/GUITextLayout.cpp -+++ b/xbmc/guilib/GUITextLayout.cpp -@@ -401,9 +401,22 @@ void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, v - { // color - size_t finish = text.Find(L']', pos + 5); - if (on && finish != CStdString::npos && (size_t)text.Find(L"[/COLOR]",finish) != CStdString::npos) -- { // create new color -- newColor = colors.size(); -- colors.push_back(g_colorManager.GetColor(text.Mid(pos + 5, finish - pos - 5))); -+ { -+ color_t color = g_colorManager.GetColor(text.Mid(pos + 5, finish - pos - 5)); -+ vecColors::const_iterator it = std::find(colors.begin(), colors.end(), color); -+ if (it == colors.end()) -+ { // create new color -+ if (colors.size() <= 0xFF) -+ { -+ newColor = colors.size(); -+ colors.push_back(color); -+ } -+ else // we have only 8 bits for color index, fallback to first color if reach max. -+ newColor = 0; -+ } -+ else -+ // reuse existing color -+ newColor = it - colors.begin(); - colorStack.push(newColor); - } - else if (!on && finish == pos + 5 && colorStack.size() > 1) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.02-XBef82d9b.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.02-XBef82d9b.patch deleted file mode 100644 index 8551ec48c..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.02-XBef82d9b.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ef82d9b6177a0576548e8e9cdc0eb17cf10524af Mon Sep 17 00:00:00 2001 -From: ulion -Date: Thu, 9 May 2013 13:11:59 +0800 -Subject: [PATCH] [OSX] Fix always on top after restore from fullscreen. - ---- - xbmc/windowing/osx/WinSystemOSX.mm | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm -index e45693c..cb86e0a 100644 ---- a/xbmc/windowing/osx/WinSystemOSX.mm -+++ b/xbmc/windowing/osx/WinSystemOSX.mm -@@ -710,6 +710,7 @@ static void DisplayReconfigured(CGDirectDisplayID display, - static NSView* last_view = NULL; - static NSSize last_view_size; - static NSPoint last_view_origin; -+ static NSInteger last_window_level = NSNormalWindowLevel; - bool was_fullscreen = m_bFullScreen; - static int lastDisplayNr = res.iScreen; - NSOpenGLContext* cur_context; -@@ -779,6 +780,7 @@ static void DisplayReconfigured(CGDirectDisplayID display, - last_view_origin = [last_view frame].origin; - last_window_screen = [[last_view window] screen]; - last_window_origin = [[last_view window] frame].origin; -+ last_window_level = [[last_view window] level]; - - if (CSettings::Get().GetBool("videoscreen.fakefullscreen")) - { -@@ -891,7 +893,7 @@ static void DisplayReconfigured(CGDirectDisplayID display, - if (CSettings::Get().GetBool("videoscreen.fakefullscreen")) - { - // restore the windowed window level -- [[last_view window] setLevel:NSNormalWindowLevel]; -+ [[last_view window] setLevel:last_window_level]; - - // Get rid of the new window we created. - if (windowedFullScreenwindow != NULL) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.03-XB07c1ed5.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.03-XB07c1ed5.patch deleted file mode 100644 index 99406bd7b..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.03-XB07c1ed5.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 07c1ed5752225f44a55ed9099c5cbfd34bff0906 Mon Sep 17 00:00:00 2001 -From: Ulion -Date: Mon, 29 Apr 2013 06:09:14 +0800 -Subject: [PATCH] Fix undefined reference caused by wrong detection of gcc - builtin atomic functions. - ---- - configure.in | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/configure.in b/configure.in -index f0e4905..95f12da 100644 ---- a/configure.in -+++ b/configure.in -@@ -850,7 +850,7 @@ AC_CHECK_SIZEOF([size_t]) - - # Check for intrinsics - AC_MSG_CHECKING([for __sync_add_and_fetch(temp, 1)]) --AC_TRY_COMPILE([],[long* temp=0; __sync_add_and_fetch(temp, 1);], -+AC_TRY_LINK([],[long* temp=0; long ret=__sync_add_and_fetch(temp, 1);], - [have_builtin_sync_add_and_fetch=yes], - [have_builtin_sync_add_and_fetch=no]) - AC_MSG_RESULT($have_builtin_sync_add_and_fetch) -@@ -860,7 +860,7 @@ if test "x$have_builtin_sync_add_and_fetch" = "xyes"; then - fi - - AC_MSG_CHECKING([for __sync_sub_and_fetch(temp, 1)]) --AC_TRY_COMPILE([],[long* temp=0; __sync_sub_and_fetch(temp, 1);], -+AC_TRY_LINK([],[long* temp=0; long ret=__sync_sub_and_fetch(temp, 1);], - [have_builtin_sync_sub_and_fetch=yes], - [have_builtin_sync_sub_and_fetch=no]) - AC_MSG_RESULT($have_builtin_sync_sub_and_fetch) -@@ -870,7 +870,7 @@ if test "x$have_builtin_sync_sub_and_fetch" = "xyes"; then - fi - - AC_MSG_CHECKING([for __sync_val_compare_and_swap(temp, 1, 1)]) --AC_TRY_COMPILE([],[long *temp = 0; __sync_val_compare_and_swap(temp, 1, 1);], -+AC_TRY_LINK([],[long *temp = 0; long ret=__sync_val_compare_and_swap(temp, 1, 1);], - [have_builtin_sync_val_compare_and_swap=yes], - [have_builtin_sync_val_compare_and_swap=no]) - AC_MSG_RESULT($have_builtin_sync_val_compare_and_swap) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.04-XB01480bb.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.04-XB01480bb.patch deleted file mode 100644 index 0bf2742f2..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.04-XB01480bb.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 01480bb7ab2022616c938d2fd222cfdafa243b67 Mon Sep 17 00:00:00 2001 -From: ulion -Date: Wed, 10 Apr 2013 19:54:54 +0800 -Subject: [PATCH] avoid detect folder.jpg under 'add' item. - ---- - xbmc/pictures/PictureThumbLoader.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp -index ddff86c..61c624d 100644 ---- a/xbmc/pictures/PictureThumbLoader.cpp -+++ b/xbmc/pictures/PictureThumbLoader.cpp -@@ -132,7 +132,8 @@ void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem) - return; - } - } -- if ((pItem->m_bIsFolder || pItem->IsCBR() || pItem->IsCBZ()) && !pItem->m_bIsShareOrDrive && !pItem->IsParentFolder()) -+ if ((pItem->m_bIsFolder || pItem->IsCBR() || pItem->IsCBZ()) && !pItem->m_bIsShareOrDrive -+ && !pItem->IsParentFolder() && !pItem->GetPath().Equals("add")) - { - // first check for a folder.jpg - CStdString thumb = "folder.jpg"; --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.05-XBff283b0.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.05-XBff283b0.patch deleted file mode 100644 index 21bbc0d53..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.05-XBff283b0.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ff283b0861afd35410d20c52fee8ba0542e91f8a Mon Sep 17 00:00:00 2001 -From: ulion -Date: Sun, 24 Mar 2013 13:19:39 +0800 -Subject: [PATCH] Check exists before listing dir, to avoid produce error log, - fix #14210 - ---- - xbmc/video/VideoInfoScanner.cpp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp -index 170b5a9..fbe7913 100644 ---- a/xbmc/video/VideoInfoScanner.cpp -+++ b/xbmc/video/VideoInfoScanner.cpp -@@ -1771,7 +1771,10 @@ - void CVideoInfoScanner::FetchActorThumbs(vector& actors, const CStdString& strPath) - { - CFileItemList items; -- CDirectory::GetDirectory(URIUtils::AddFileToFolder(strPath, ".actors"), items, ".png|.jpg|.tbn", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_NO_FILE_INFO); -+ CStdString actorsDir = URIUtils::AddFileToFolder(strPath, ".actors"); -+ if (CDirectory::Exists(actorsDir)) -+ CDirectory::GetDirectory(actorsDir, items, ".png|.jpg|.tbn", DIR_FLAG_NO_FILE_DIRS | -+ DIR_FLAG_NO_FILE_INFO); - for (vector::iterator i = actors.begin(); i != actors.end(); ++i) - { - if (i->thumb.IsEmpty()) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.06-XB937e565.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.06-XB937e565.patch deleted file mode 100644 index 296012c06..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.17.06-XB937e565.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 937e565410c19c0c3c3651c467c919a69cf027a2 Mon Sep 17 00:00:00 2001 -From: ulion -Date: Mon, 13 May 2013 08:41:14 +0800 -Subject: [PATCH] Fix color tag didn't hide bug introduced by PR2725. - ---- - xbmc/guilib/GUITextLayout.cpp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/xbmc/guilib/GUITextLayout.cpp b/xbmc/guilib/GUITextLayout.cpp -index 8dc8b45..49c0459 100644 ---- a/xbmc/guilib/GUITextLayout.cpp -+++ b/xbmc/guilib/GUITextLayout.cpp -@@ -354,6 +354,7 @@ void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, v - { - uint32_t newStyle = 0; - color_t newColor = currentColor; -+ bool colorTagChange = false; - bool newLine = false; - // have a [ - check if it's an ON or OFF switch - bool on(true); -@@ -418,17 +419,19 @@ void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, v - // reuse existing color - newColor = it - colors.begin(); - colorStack.push(newColor); -+ colorTagChange = true; - } - else if (!on && finish == pos + 5 && colorStack.size() > 1) - { // revert to previous color - colorStack.pop(); - newColor = colorStack.top(); -+ colorTagChange = true; - } - if (finish != CStdString::npos) - pos = finish + 1; - } - -- if (newStyle || newColor != currentColor || newLine) -+ if (newStyle || colorTagChange || newLine) - { // we have a new style or a new color, so format up the previous segment - CStdStringW subText = text.Mid(startPos, endPos - startPos); - if (currentStyle & FONT_STYLE_UPPERCASE) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.18-2758.patch.bk b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.18-2758.patch.bk deleted file mode 100644 index fa0cd1d77..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.18-2758.patch.bk +++ /dev/null @@ -1,28 +0,0 @@ -From 2441ddbbd638fb8b81c0eed46a78ba1a1b228413 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 17 May 2013 09:19:16 +0200 -Subject: [PATCH] backport some constructor initializations from - 92e8bc4a4361d730abac9ad3080cd6923e9d551a - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index f70a4f9..5af76d0 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -147,6 +147,10 @@ - dl_vdp_device_create_x11 = NULL; - dl_vdp_get_proc_address = NULL; - dl_vdp_preemption_callback_register = NULL; -+ past[0] = NULL; -+ past[1] = NULL; -+ current = NULL; -+ future = NULL; - } - - bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.19-PR2761.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.19-PR2761.patch deleted file mode 100644 index 3309abec0..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.19-PR2761.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 6cba369a0f54231b145ce6b07a42cd1cd32261ec Mon Sep 17 00:00:00 2001 -From: ulion -Date: Sun, 21 Apr 2013 04:43:30 +0800 -Subject: [PATCH] Fixed: do not send Range request header when encounter error. - ---- - xbmc/filesystem/CurlFile.cpp | 20 +++++++++++++++++++- - xbmc/filesystem/CurlFile.h | 1 + - 2 files changed, 20 insertions(+), 1 deletion(-) - -diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp -index ff8250c..8667fc6 100644 ---- a/xbmc/filesystem/CurlFile.cpp -+++ b/xbmc/filesystem/CurlFile.cpp -@@ -197,6 +197,7 @@ size_t CCurlFile::CReadState::WriteCallback(char *buffer, size_t size, size_t ni - m_bufferSize = 0; - m_cancelled = false; - m_bFirstLoop = true; -+ m_sendRange = true; - m_headerdone = false; - } - -@@ -255,8 +256,13 @@ void CCurlFile::CReadState::SetResume(void) - * request header. If we don't the server may provide different content causing seeking to fail. - * This only affects HTTP-like items, for FTP it's a null operation. - */ -- if (m_filePos == 0) -+ if (m_sendRange && m_filePos == 0) - g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RANGE, "0-"); -+ else -+ { -+ g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RANGE, NULL); -+ m_sendRange = false; -+ } - - g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RESUME_FROM_LARGE, m_filePos); - } -@@ -866,6 +872,7 @@ bool CCurlFile::Open(const CURL& url) - // setup common curl options - SetCommonOptions(m_state); - SetRequestHeaders(m_state); -+ m_state->m_sendRange = m_seekable; - - m_httpresponse = m_state->Connect(m_bufferSize); - if( m_httpresponse < 0 || m_httpresponse >= 400) -@@ -1046,6 +1053,7 @@ int64_t CCurlFile::Seek(int64_t iFilePosition, int iWhence) - SetRequestHeaders(m_state); - - m_state->m_filePos = nextPos; -+ m_state->m_sendRange = true; - if (oldstate) - m_state->m_fileSize = oldstate->m_fileSize; - -@@ -1287,6 +1295,16 @@ bool CCurlFile::CReadState::FillBuffer(unsigned int want) - msg->data.result == CURLE_RECV_ERROR) && - !m_bFirstLoop) - CURLresult = msg->data.result; -+ else if ( (msg->data.result == CURLE_HTTP_RANGE_ERROR || -+ msg->data.result == CURLE_HTTP_RETURNED_ERROR) && -+ m_bFirstLoop && -+ m_filePos == 0 && -+ m_sendRange) -+ { -+ // If server returns a range or http error, retry with range disabled -+ CURLresult = msg->data.result; -+ m_sendRange = false; -+ } - else - return false; - } -diff --git a/xbmc/filesystem/CurlFile.h b/xbmc/filesystem/CurlFile.h -index d25fb58..a48207a 100644 ---- a/xbmc/filesystem/CurlFile.h -+++ b/xbmc/filesystem/CurlFile.h -@@ -101,6 +101,7 @@ - int64_t m_fileSize; - int64_t m_filePos; - bool m_bFirstLoop; -+ bool m_sendRange; - - /* returned http header */ - CHttpHeader m_httpheader; --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.20-XB812a890.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.20-XB812a890.patch deleted file mode 100644 index 7990929a2..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.20-XB812a890.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 812a89032539d7d40d8d27b10337c1dd2ccca29b Mon Sep 17 00:00:00 2001 -From: montellese -Date: Sun, 19 May 2013 15:46:05 +0200 -Subject: [PATCH] CGUISliderControl: only switch between selectors on - if there are more than one - ---- - xbmc/guilib/GUISliderControl.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/guilib/GUISliderControl.cpp b/xbmc/guilib/GUISliderControl.cpp -index 9de3413..5cce7a8 100644 ---- a/xbmc/guilib/GUISliderControl.cpp -+++ b/xbmc/guilib/GUISliderControl.cpp -@@ -174,7 +174,8 @@ bool CGUISliderControl::OnAction(const CAction &action) - - case ACTION_SELECT_ITEM: - // switch between the two sliders -- SwitchRangeSelector(); -+ if (m_rangeSelection) -+ SwitchRangeSelector(); - return true; - - default: --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.21-XB2e18d81.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.21-XB2e18d81.patch deleted file mode 100644 index e2f0da65a..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.21-XB2e18d81.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2e18d8108e29d58199616d7d6457026ef736cf47 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 17 May 2013 09:07:27 +0200 -Subject: [PATCH] pvr: fix channel switch for addons using other stream - ---- - xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.cpp -index aa3298b..397ea5d 100644 ---- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.cpp -+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamPVRManager.cpp -@@ -315,8 +315,9 @@ bool CDVDInputStreamPVRManager::UpdateItem(CFileItem& item) - - m_eof = IsEOF(); - -- if (m_pOtherStream) -- return m_pOtherStream->NextStream(); -+ CDVDInputStream::ENextStream next; -+ if (m_pOtherStream && ((next = m_pOtherStream->NextStream()) != NEXTSTREAM_NONE)) -+ return next; - else if(m_pFile->SkipNext()) - { - if (m_eof) --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.22-XB3e58f24.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.22-XB3e58f24.patch deleted file mode 100644 index 90ad7077c..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.22-XB3e58f24.patch +++ /dev/null @@ -1,300 +0,0 @@ -diff -Naur xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerAudio.cpp xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerAudio.cpp ---- xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerAudio.cpp 2013-05-02 17:00:07.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerAudio.cpp 2013-06-12 23:56:33.134924673 +0200 -@@ -76,7 +76,6 @@ - m_buffer_empty = false; - m_nChannels = 0; - m_DecoderOpen = false; -- m_freq = CurrentHostFrequency(); - m_bad_state = false; - m_hints_current.Clear(); - -@@ -135,20 +134,11 @@ - - m_speed = DVD_PLAYSPEED_NORMAL; - m_audioClock = 0; -- m_error = 0; -- m_errorbuff = 0; -- m_errorcount = 0; -- m_integral = 0; -- m_skipdupcount = 0; -- m_prevskipped = false; -- m_syncclock = true; - m_hw_decode = false; -- m_errortime = CurrentHostCounter(); - m_silence = false; - m_started = false; - m_flush = false; - m_nChannels = 0; -- m_synctype = SYNC_DISCON; - m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; - m_use_passthrough = (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_HDMI) ? true : false ; - m_use_hw_decode = g_advancedSettings.m_omxHWAudioDecode; -@@ -190,110 +180,6 @@ - CLog::Log(LOGNOTICE, "thread end: OMXPlayerAudio::OnExit()"); - } - -- -- --void OMXPlayerAudio::HandleSyncError(double duration) --{ -- double clock = m_av_clock->GetClock(); -- double error = m_audioClock - clock; -- int64_t now; -- -- if( fabs(error) > DVD_MSEC_TO_TIME(100) || m_syncclock ) -- { -- m_av_clock->Discontinuity(clock+error); -- /* -- if(m_speed == DVD_PLAYSPEED_NORMAL) -- CLog::Log(LOGDEBUG, "OMXPlayerAudio:: Discontinuity - was:%f, should be:%f, error:%f\n", clock, clock+error, error); -- */ -- -- m_errorbuff = 0; -- m_errorcount = 0; -- m_skipdupcount = 0; -- m_error = 0; -- m_syncclock = false; -- m_errortime = CurrentHostCounter(); -- -- return; -- } -- -- if (m_speed != DVD_PLAYSPEED_NORMAL) -- { -- m_errorbuff = 0; -- m_errorcount = 0; -- m_integral = 0; -- m_skipdupcount = 0; -- m_error = 0; -- m_errortime = CurrentHostCounter(); -- return; -- } -- -- //check if measured error for 1 second -- now = CurrentHostCounter(); -- if ((now - m_errortime) >= m_freq) -- { -- m_errortime = now; -- m_error = m_errorbuff / m_errorcount; -- -- m_errorbuff = 0; -- m_errorcount = 0; -- -- if (m_synctype == SYNC_DISCON) -- { -- double limit, error; -- -- if (m_av_clock->GetRefreshRate(&limit) > 0) -- { -- //when the videoreferenceclock is running, the discontinuity limit is one vblank period -- limit *= DVD_TIME_BASE; -- -- //make error a multiple of limit, rounded towards zero, -- //so it won't interfere with the sync methods in CXBMCRenderManager::WaitPresentTime -- if (m_error > 0.0) -- error = limit * floor(m_error / limit); -- else -- error = limit * ceil(m_error / limit); -- } -- else -- { -- limit = DVD_MSEC_TO_TIME(10); -- error = m_error; -- } -- -- /* -- limit = DVD_MSEC_TO_TIME(10); -- error = m_error; -- */ -- -- if (fabs(error) > limit - 0.001) -- { -- m_av_clock->Discontinuity(clock+error); -- /* -- if(m_speed == DVD_PLAYSPEED_NORMAL) -- CLog::Log(LOGDEBUG, "COMXPlayerAudio:: Discontinuity - was:%f, should be:%f, error:%f", clock, clock+error, error); -- */ -- } -- } -- /* -- else if (m_synctype == SYNC_SKIPDUP && m_skipdupcount == 0 && fabs(m_error) > DVD_MSEC_TO_TIME(10)) -- if (m_skipdupcount == 0 && fabs(m_error) > DVD_MSEC_TO_TIME(10)) -- { -- //check how many packets to skip/duplicate -- m_skipdupcount = (int)(m_error / duration); -- //if less than one frame off, see if it's more than two thirds of a frame, so we can get better in sync -- if (m_skipdupcount == 0 && fabs(m_error) > duration / 3 * 2) -- m_skipdupcount = (int)(m_error / (duration / 3 * 2)); -- -- if (m_skipdupcount > 0) -- CLog::Log(LOGDEBUG, "OMXPlayerAudio:: Duplicating %i packet(s) of %.2f ms duration", -- m_skipdupcount, duration / DVD_TIME_BASE * 1000.0); -- else if (m_skipdupcount < 0) -- CLog::Log(LOGDEBUG, "OMXPlayerAudio:: Skipping %i packet(s) of %.2f ms duration ", -- m_skipdupcount * -1, duration / DVD_TIME_BASE * 1000.0); -- } -- */ -- } --} -- - bool OMXPlayerAudio::CodecChange() - { - unsigned int old_bitrate = m_hints.bitrate; -@@ -394,9 +280,6 @@ - int n = (m_nChannels * m_hints.bitspersample * m_hints.samplerate)>>3; - if (n > 0) - m_audioClock += ((double)decoded_size * DVD_TIME_BASE) / n; -- -- if(m_speed == DVD_PLAYSPEED_NORMAL) -- HandleSyncError((((double)decoded_size * DVD_TIME_BASE) / n)); - break; - - } -@@ -430,9 +313,6 @@ - m_omxAudio.AddPackets(pkt->pData, pkt->iSize, m_audioClock, m_audioClock); - } - -- if(m_speed == DVD_PLAYSPEED_NORMAL) -- HandleSyncError(0); -- - m_audioStats.AddSampleBytes(pkt->iSize); - - break; -@@ -525,18 +405,7 @@ - else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC)) - { //player asked us to set internal clock - CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg; -- -- if (pMsgGeneralResync->m_timestamp != DVD_NOPTS_VALUE) -- m_audioClock = pMsgGeneralResync->m_timestamp; -- -- if (pMsgGeneralResync->m_clock) -- { -- CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, 1)", m_audioClock); -- m_av_clock->Discontinuity(m_audioClock); -- //m_av_clock->OMXUpdateClock(m_audioClock); -- } -- else -- CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, 0)", m_audioClock); -+ CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, %d)", m_audioClock, pMsgGeneralResync->m_clock); - m_flush = false; - } - else if (pMsg->IsType(CDVDMsg::GENERAL_RESET)) -@@ -559,7 +428,6 @@ - m_omxAudio.Flush(); - m_av_clock->OMXReset(false); - m_av_clock->UnLock(); -- m_syncclock = true; - m_stalled = true; - m_started = false; - -@@ -599,10 +467,6 @@ - m_speed = static_cast(pMsg)->m_value; - CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_SETSPEED %d", m_speed); - } -- if (m_speed != DVD_PLAYSPEED_NORMAL) -- { -- m_syncclock = true; -- } - } - else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE)) - { -diff -Naur xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerAudio.h xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerAudio.h ---- xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerAudio.h 2013-05-02 17:00:08.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerAudio.h 2013-06-12 23:56:33.135924691 +0200 -@@ -60,19 +60,6 @@ - int m_speed; - bool m_silence; - double m_audioClock; -- double m_error; //last average error -- -- int64_t m_errortime; //timestamp of last time we measured -- int64_t m_freq; -- -- void HandleSyncError(double duration); -- double m_errorbuff; //place to store average errors -- int m_errorcount;//number of errors stored -- bool m_syncclock; -- -- double m_integral; //integral correction for resampler -- int m_skipdupcount; //counter for skip/duplicate synctype -- bool m_prevskipped; - - bool m_stalled; - bool m_started; -@@ -82,8 +69,6 @@ - struct timespec m_starttime, m_endtime; - bool m_buffer_empty; - bool m_flush; -- //SYNC_DISCON, SYNC_SKIPDUP, SYNC_RESAMPLE -- int m_synctype; - int m_nChannels; - bool m_DecoderOpen; - -diff -Naur xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerVideo.cpp xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerVideo.cpp ---- xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerVideo.cpp 2013-05-02 17:00:07.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerVideo.cpp 2013-06-13 00:11:56.443044388 +0200 -@@ -89,7 +89,6 @@ - m_iVideoDelay = 0; - m_droptime = 0.0; - m_dropbase = 0.0; -- m_autosync = 1; - m_fForcedAspectRatio = 0.0f; - m_messageQueue.SetMaxDataSize(10 * 1024 * 1024); - m_messageQueue.SetMaxTimeSize(8.0); -@@ -115,7 +114,6 @@ - m_started = false; - m_flush = false; - 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); -@@ -280,11 +278,6 @@ - iClockSleep = min(iClockSleep, DVD_MSEC_TO_TIME(500)); - iFrameSleep = min(iFrameSleep, DVD_MSEC_TO_TIME(500)); - -- if( m_stalled ) -- iSleepTime = iFrameSleep; -- else -- iSleepTime = iFrameSleep + (iClockSleep - iFrameSleep) / m_autosync; -- - // 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 ) -@@ -398,22 +391,7 @@ - else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC)) - { - CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg; -- -- if(pMsgGeneralResync->m_timestamp != DVD_NOPTS_VALUE) -- pts = pMsgGeneralResync->m_timestamp; -- -- double delay = m_FlipTimeStamp - m_av_clock->GetAbsoluteClock(); -- if( delay > frametime ) delay = frametime; -- else if( delay < 0 ) delay = 0; -- -- if(pMsgGeneralResync->m_clock) -- { -- CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 1)", pts); -- m_av_clock->Discontinuity(pts - delay); -- //m_av_clock->OMXUpdateClock(pts - delay); -- } -- else -- CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 0)", pts); -+ CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, %d)", pts, pMsgGeneralResync->m_clock); - - pMsgGeneralResync->Release(); - continue; -diff -Naur xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerVideo.h xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerVideo.h ---- xbmc-12.2.0/xbmc/cores/omxplayer/OMXPlayerVideo.h 2013-05-02 17:00:07.000000000 +0200 -+++ xbmc-12.2.0.patch/xbmc/cores/omxplayer/OMXPlayerVideo.h 2013-06-12 23:57:42.278013434 +0200 -@@ -66,7 +66,6 @@ - std::string m_codecname; - double m_droptime; - double m_dropbase; -- unsigned int m_autosync; - double m_iSubtitleDelay; - bool m_bRenderSubs; - bool m_bAllowFullscreen; diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.23-PR2861.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.23-PR2861.patch deleted file mode 100644 index 9b9c5aea7..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.23-PR2861.patch +++ /dev/null @@ -1,26 +0,0 @@ -From aa12d4ae8315ef4b14c01e3595ea984f8c605639 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Mon, 10 Jun 2013 22:20:13 +0200 -Subject: [PATCH] AE: Workaround (ugly) non existing channel maps in old ffmpeg - (workarounds: #14407) - ---- - xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp -index 985a01c..880b710 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp -@@ -319,6 +319,8 @@ void CDVDAudioCodecFFmpeg::BuildChannelMap() - { - CLog::Log(LOGINFO, "CDVDAudioCodecFFmpeg::GetChannelMap - FFmpeg reported %d channels, but the layout contains %d ignoring", m_pCodecContext->channels, bits); - layout = m_dllAvUtil.av_get_default_channel_layout(m_pCodecContext->channels); -+ while(layout == 0 && m_pCodecContext->channels > 2) -+ layout = m_dllAvUtil.av_get_default_channel_layout(--m_pCodecContext->channels); - } - - m_channelLayout.Reset(); --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.25-XB21eb522.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.25-XB21eb522.patch deleted file mode 100644 index 8581ec7d6..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-990.25-XB21eb522.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Naur xbmc-12.2.0/lib/libdvd/libdvdread/src/dvd_reader.c xbmc-12.2.0.patch/lib/libdvd/libdvdread/src/dvd_reader.c ---- xbmc-12.2.0/lib/libdvd/libdvdread/src/dvd_reader.c 2013-05-02 17:00:11.000000000 +0200 -+++ xbmc-12.2.0.patch/lib/libdvd/libdvdread/src/dvd_reader.c 2013-06-18 07:08:23.973913805 +0200 -@@ -423,6 +423,9 @@ - /* Also WIN32 does not have symlinks, so we don't need this bit of code. */ - - /* Resolve any symlinks and get the absolut dir name. */ -+#if defined(_XBMC) /* for XBMC, only do symlink resolution for (real) non-xbmc-VFS paths */ -+ if ( path[0] == '/' ) -+#endif // _XBMC - { - char *new_path; - int cdir = open( ".", O_RDONLY ); diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.01-xvba_support-cc55dcb.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.01-xvba_support-cc55dcb.patch deleted file mode 100644 index b062ccabd..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.01-xvba_support-cc55dcb.patch +++ /dev/null @@ -1,21656 +0,0 @@ -From 665a6540b13fc7d61fb114611926a289b3c33290 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:03:31 +0200 -Subject: [PATCH 01/94] 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 17eccbe..2ada954 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_renderManager.UpdateResolution(); -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; -+ 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_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" - - class CRenderCapture; -+class CDVDClock; - - namespace DXVA { class CProcessor; } - namespace VAAPI { class CSurfaceHolder; } -@@ -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); -+ 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 e5a1e71..bd55060 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -4097,3 +4097,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 ebe0ce8..2d1b163 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.8.1.6 - - -From f2149c3e0cbfcb757d6e86f94a9523783209b83f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 08:32:18 +0100 -Subject: [PATCH 02/94] 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.8.1.6 - - -From de745a5efcf48a15b3bb9349da9ab23cf4953e95 Mon Sep 17 00:00:00 2001 -From: unknown -Date: Sat, 16 Feb 2013 11:17:02 +0100 -Subject: [PATCH 03/94] 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.8.1.6 - - -From e92897a0f4c555bce6010509cca85cc904f373af Mon Sep 17 00:00:00 2001 -From: unknown -Date: Sat, 16 Feb 2013 11:17:32 +0100 -Subject: [PATCH 04/94] 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.8.1.6 - - -From 09fe446db7be21df3592d9d7fbc15756ba00eaec Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 10:49:09 +0200 -Subject: [PATCH 05/94] 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); - - // trigger update of video filters --- -1.8.1.6 - - -From 1a1699c0eb9772b51a5338a12d6f6e4b182e93f1 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:17:33 +0200 -Subject: [PATCH 06/94] 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 2ada954..ffd86a7 100644 ---- a/xbmc/Application.cpp -+++ b/xbmc/Application.cpp -@@ -419,8 +419,6 @@ - #endif - m_currentStack = new CFileItemList; - -- m_frameCount = 0; -- - m_bPresentFrame = false; - m_bPlatformDirectories = true; - -@@ -2231,28 +2229,18 @@ float CApplication::GetDimScreenSaverLevel() const - - bool CApplication::WaitFrame(unsigned int timeout) - { -- bool done = false; -- - // Wait for all other frames to be presented -- CSingleLock lock(m_frameMutex); -- //wait until event is set, but modify remaining time -+ m_frameEvent.Reset(); - -- TightConditionVariable > cv(m_frameCond, InversePredicate(m_frameCount)); -- cv.wait(lock,timeout); -- done = m_frameCount == 0; -+ if (!g_renderManager.HasFrame() && !m_frameEvent.WaitMSec(timeout)) -+ return false; - -- return done; -+ return g_renderManager.HasFrame(); - } - - void CApplication::NewFrame() - { -- // We just posted another frame. Keep track and notify. -- { -- CSingleLock lock(m_frameMutex); -- m_frameCount++; -- } -- -- m_frameCond.notifyAll(); -+ m_frameEvent.Set(); - } - - void CApplication::Render() -@@ -2272,7 +2260,6 @@ void CApplication::Render() - - int vsync_mode = g_guiSettings.GetInt("videoscreen.vsync"); - -- bool decrement = false; - bool hasRendered = false; - bool limitFrames = false; - unsigned int singleFrameTime = 10; // default limit 100 fps -@@ -2286,13 +2273,10 @@ void CApplication::Render() - m_bPresentFrame = false; - if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !IsPaused()) - { -- CSingleLock lock(m_frameMutex); -- -- TightConditionVariable cv(m_frameCond,m_frameCount); -- cv.wait(lock,100); -- -- m_bPresentFrame = m_frameCount > 0; -- decrement = m_bPresentFrame; -+ m_frameEvent.Reset(); -+ m_bPresentFrame = g_renderManager.HasFrame(); -+ if (!m_bPresentFrame && m_frameEvent.WaitMSec(100)) -+ m_bPresentFrame = g_renderManager.HasFrame(); - hasRendered = true; - } - else -@@ -2316,8 +2300,6 @@ void CApplication::Render() - else if (lowfps) - singleFrameTime = 200; // 5 fps, <=200 ms latency to wake up - } -- -- decrement = true; - } - } - -@@ -2379,13 +2361,6 @@ void CApplication::Render() - - g_renderManager.UpdateResolution(); - g_renderManager.ManageCaptures(); -- -- { -- CSingleLock lock(m_frameMutex); -- if(m_frameCount > 0 && decrement) -- m_frameCount--; -- } -- m_frameCond.notifyAll(); - } - - void CApplication::SetStandAlone(bool value) -@@ -5648,12 +5623,6 @@ bool CApplication::SwitchToFullScreen() - // See if we're playing a video, and are in GUI mode - if ( IsPlayingVideo() && g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO) - { -- // Reset frame count so that timing is FPS will be correct. -- { -- CSingleLock lock(m_frameMutex); -- m_frameCount = 0; -- } -- - // then switch to fullscreen mode - g_windowManager.ActivateWindow(WINDOW_FULLSCREEN_VIDEO); - return true; -@@ -5886,7 +5855,6 @@ bool CApplication::IsCurrentThread() const - - bool CApplication::IsPresentFrame() - { -- CSingleLock lock(m_frameMutex); - 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 - bool m_bEnableLegacyRes; - bool m_bTestMode; - bool m_bSystemScreenSaverEnable; -- -- int m_frameCount; -- CCriticalSection m_frameMutex; -- XbmcThreads::ConditionVariable m_frameCond; -+ -+ CEvent m_frameEvent; - - 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.8.1.6 - - -From cdb9f67e23389c7ae8ca3f7d78ee3e0eef2eb860 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 11:02:29 +0200 -Subject: [PATCH 07/94] 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.8.1.6 - - -From bd53253c39b79610bff5a85fa33bf8d0330f367a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 20:17:29 +0100 -Subject: [PATCH 08/94] 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.8.1.6 - - -From 53a092f6153e7848d02d50de813f5ba315ef23a9 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 18 Feb 2013 10:42:00 +0100 -Subject: [PATCH 09/94] 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.8.1.6 - - -From dd0e5f0255697d390b1c2905821b056059a9fb1c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 19 Feb 2013 09:06:22 +0100 -Subject: [PATCH 10/94] 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.8.1.6 - - -From 10a92f0e407b43648de119586f156bb279210ea2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 24 Feb 2013 09:55:00 +0100 -Subject: [PATCH 11/94] 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.8.1.6 - - -From 7dfb8e80deb4e196da0f7b9753cbffb4c0d2f84d Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 26 Feb 2013 09:00:21 +0100 -Subject: [PATCH 12/94] 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 bd55060..e5a1e71 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -4097,8 +4097,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 2d1b163..ebe0ce8 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.8.1.6 - - -From 6831c2ace51d439657bb068ff4a9176adc0563a8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 08:05:00 +0100 -Subject: [PATCH 13/94] 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.8.1.6 - - -From 8606471ef3785ee53ad1025a4af03d3b5147d22a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 08:07:07 +0100 -Subject: [PATCH 14/94] 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.8.1.6 - - -From 5abcce89d20fed5503a9bc4d441700e5274de8e7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:00:51 +0100 -Subject: [PATCH 15/94] 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.8.1.6 - - -From 39311d81fe5dc4c2b9921564de9cfa78d9512c3a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:10:17 +0100 -Subject: [PATCH 16/94] 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.8.1.6 - - -From 668e9a334b2ab22bad7196804a2a9992384c0d6e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 12:31:11 +0100 -Subject: [PATCH 17/94] 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.8.1.6 - - -From 80fc2f2b5a25d7bb987a3610c090bd79a7631480 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 10 Feb 2013 18:40:30 +0100 -Subject: [PATCH 18/94] 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 b181cbd..49e1b8c 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp -@@ -335,25 +335,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); -- 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) -+ + 2 * iFrameDuration; -+ ProcessOverlays(iGroupId, pts_overlay); - -- //m_av_clock->WaitAbsoluteClock((iCurrentClock + iSleepTime)); -+ double timestamp = (CDVDClock::GetAbsoluteClock(false) + 2 * iFrameDuration) / DVD_TIME_BASE; -+ g_renderManager.FlipPage(CThread::m_bStop, timestamp, -1, FS_NONE); - } - - void OMXPlayerVideo::Process() -@@ -794,7 +785,7 @@ void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height) - - 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; --- -1.8.1.6 - - -From cb3ed9e675b1a3cd08b2a2577d5730312af166ff Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Mar 2013 20:42:10 +0100 -Subject: [PATCH 19/94] 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.8.1.6 - - -From 14d5bef5c13d8e469464778e55c8fa3bab345290 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 20/94] 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.8.1.6 - - -From 25c9f6d91192d95167353546a40500409fa75929 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 21/94] 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.8.1.6 - - -From c5d82e4e8df8dc803dac562bfff851d9551c15f4 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Feb 2013 18:25:53 +0100 -Subject: [PATCH 22/94] 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.8.1.6 - - -From 51cdc8453dce0754b9daa78acedb1deab6810d63 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 1 Mar 2013 09:57:16 +0100 -Subject: [PATCH 23/94] 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.8.1.6 - - -From e7446046da7da7b64f2f381bfcd8decdbb9e77f4 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 24/94] 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.8.1.6 - - -From 9300e23fc0b9cc96237ec5bfc499a7880713674c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 25/94] 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.8.1.6 - - -From 633396d59bb62d952092552ea6b7619d9536ffaf Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 26/94] 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 e5a1e71..21414ab 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1552,7 +1552,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()) - { -@@ -2193,6 +2193,12 @@ void CDVDPlayer::HandleMessages() - pvrinputstream->Pause( speed == 0 ); - } - -+ // do a seek after rewind, clock is not in sync with current pts -+ if (m_playSpeed < 0 && speed >= 0) -+ { -+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ } -+ - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE - // audioplayer, stops outputing audio to audiorendere, but still tries to - // sleep an correct amount for each packet --- -1.8.1.6 - - -From 47f1c914d0e09b4692bc079e3d1692df7792b4c9 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 7 Apr 2012 09:19:00 +0200 -Subject: [PATCH 27/94] 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 0c77c30..f18f109 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5113,7 +5113,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" -@@ -6332,7 +6340,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(); -+#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 -+} - - 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 - #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; - #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; - }; - - -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 - while(*cur != PIX_FMT_NONE) - { - #ifdef HAVE_LIBVDPAU -- if(CVDPAU::IsVDPAUFormat(*cur) && g_guiSettings.GetBool("videoplayer.usevdpau")) -+ if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && g_guiSettings.GetBool("videoplayer.usevdpau")) - { - if(ctx->GetHardware()) - return *cur; - - CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height); -- CVDPAU* vdp = new CVDPAU(); -- if(vdp->Open(avctx, *cur)) -+ VDPAU::CDecoder* vdp = new VDPAU::CDecoder(); -+ if(vdp->Open(avctx, *cur, ctx->m_uSurfacesCount)) - { - ctx->SetHardware(vdp); - return *cur; -@@ -205,14 +205,27 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options - continue; - - CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Creating VDPAU(%ix%i, %d)",hints.width, hints.height, hints.codec); -- CVDPAU* vdp = new CVDPAU(); -+ -+ VDPAU::CDecoder* vdp = new VDPAU::CDecoder(); - m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec); - m_pCodecContext->codec_id = hints.codec; - m_pCodecContext->width = hints.width; - m_pCodecContext->height = hints.height; - m_pCodecContext->coded_width = hints.width; - m_pCodecContext->coded_height = hints.height; -- if(vdp->Open(m_pCodecContext, pCodec->pix_fmts ? pCodec->pix_fmts[0] : PIX_FMT_NONE)) -+ -+ // check number of surfaces used in renderer -+ unsigned int surfaces = 0; -+ for(std::vector::iterator it = options.m_keys.begin(); it != options.m_keys.end(); it++) -+ { -+ if (it->m_name == "surfaces") -+ { -+ surfaces = std::atoi(it->m_value.c_str()); -+ break; -+ } -+ } -+ -+ if(vdp->Open(m_pCodecContext, pCodec->pix_fmts ? pCodec->pix_fmts[0] : PIX_FMT_NONE, surfaces)) - { - 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 -@@ -28,7 +28,6 @@ - #include "DllSwScale.h" - #include "DllAvFilter.h" - --class CVDPAU; - 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 -@@ -32,11 +32,16 @@ - #include "settings/AdvancedSettings.h" - #include "Application.h" - #include "utils/MathUtils.h" -+#include "utils/TimeUtils.h" - #include "DVDCodecs/DVDCodecUtils.h" -+#include "cores/VideoRenderers/RenderFlags.h" -+ -+using namespace VDPAU; -+#define NUM_RENDER_PICS 9 - - #define ARSIZE(x) (sizeof(x) / sizeof((x)[0])) - --CVDPAU::Desc decoder_profiles[] = { -+CDecoder::Desc decoder_profiles[] = { - {"MPEG1", VDP_DECODER_PROFILE_MPEG1}, - {"MPEG2_SIMPLE", VDP_DECODER_PROFILE_MPEG2_SIMPLE}, - {"MPEG2_MAIN", VDP_DECODER_PROFILE_MPEG2_MAIN}, -@@ -50,14 +55,16 @@ - {"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} - - static struct SInterlaceMapping - { -@@ -68,88 +75,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} --, {VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE , VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE} -+, {VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE , VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE} - , {VS_INTERLACEMETHOD_NONE , (VdpVideoMixerFeature)-1} - }; - - //since libvdpau 0.4, vdp_device_create_x11() installs a callback on the Display*, - //if we unload libvdpau with dlclose(), we segfault on XCloseDisplay, - //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; -- surfaceNum = presentSurfaceNum = 0; -- picAge.b_age = picAge.ip_age[0] = picAge.ip_age[1] = 256*256*256*64; -- vdpauConfigured = false; -- 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; - -- m_glPixmap = 0; -- m_Pixmap = 0; -- if (!glXBindTexImageEXT) -- glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); -- if (!glXReleaseTexImageEXT) -- glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); -+ m_vdpauConfigured = false; -+ m_DisplayState = VDPAU_OPEN; -+} - -- totalAvailableOutputSurfaces = 0; -- outputSurface = presentSurface = VDP_INVALID_HANDLE; -- vdp_flip_target = VDP_INVALID_HANDLE; -- vdp_flip_queue = VDP_INVALID_HANDLE; -- vid_width = vid_height = OutWidth = OutHeight = 0; -- surface_width = surface_height = 0; -- -- memset(&decoder, 0, sizeof(decoder)); -- memset(&outRect, 0, sizeof(outRect)); -- memset(&outRectVid, 0, sizeof(outRectVid)); -- -- m_Display = NULL; -- -- tmpBrightness = 0; -- tmpContrast = 0; -- tmpDeintMode = 0; -- tmpDeintGUI = 0; -- tmpDeint = 0; -- max_references = 0; -- -- for (int i = 0; i < NUM_OUTPUT_SURFACES; i++) -- outputSurfaces[i] = VDP_INVALID_HANDLE; -- -- videoMixer = VDP_INVALID_HANDLE; -- m_BlackBar = NULL; -- -- memset(m_features, 0, sizeof(m_features)); -- m_feature_count = 0; -- m_vdpauOutputMethod = OUTPUT_NONE; -- -- upScale = g_advancedSettings.m_videoVDPAUScaling; -- -- vdp_video_mixer_set_attribute_values = NULL; -- vdp_generate_csc_matrix = NULL; -- vdp_presentation_queue_target_destroy = NULL; -- vdp_presentation_queue_create = NULL; -- vdp_presentation_queue_destroy = NULL; -- vdp_presentation_queue_display = NULL; -- vdp_presentation_queue_block_until_surface_idle = NULL; -- vdp_presentation_queue_target_create_x11 = NULL; -- vdp_presentation_queue_query_surface_status = NULL; -- vdp_presentation_queue_get_time = NULL; -- vdp_get_error_string = NULL; -- vdp_decoder_create = NULL; -- vdp_decoder_destroy = NULL; -- vdp_decoder_render = NULL; -- vdp_decoder_query_caps = NULL; -- vdp_preemption_callback_register = NULL; -- dl_vdp_device_create_x11 = NULL; -- dl_vdp_get_proc_address = NULL; -- dl_vdp_preemption_callback_register = NULL; --} -- --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 - CLog::Log(LOGWARNING,"(VDPAU) no width/height available, can't init"); - return false; - } -+ m_vdpauConfig.numRenderBuffers = surfaces; -+ m_decoderThread = CThread::GetCurrentThreadId(); - - if (!dl_handle) - { -@@ -168,8 +119,6 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su - error = "dlerror() returned NULL"; - - CLog::Log(LOGNOTICE,"(VDPAU) Unable to get handle to libvdpau: %s", error); -- //g_application.m_guiDialogKaiToast.QueueNotification(CGUIDialogKaiToast::Error, "VDPAU", error, 10000); -- - return false; - } - } -@@ -178,8 +127,9 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su - return false; - - InitVDPAUProcs(); -+ m_presentPicture = 0; - -- if (vdp_device != VDP_INVALID_HANDLE) -+ if (m_vdpauConfig.vdpDevice != VDP_INVALID_HANDLE) - { - SpewHardwareAvailable(); - -@@ -197,25 +147,23 @@ bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int su - - /* attempt to create a decoder with this width/height, some sizes are not supported by hw */ - VdpStatus vdp_st; -- vdp_st = vdp_decoder_create(vdp_device, profile, avctx->coded_width, avctx->coded_height, 5, &decoder); -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_decoder_create(m_vdpauConfig.vdpDevice, profile, avctx->coded_width, avctx->coded_height, 5, &m_vdpauConfig.vdpDecoder); - - if(vdp_st != VDP_STATUS_OK) - { -- CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) checking for decoder support\n", vdp_get_error_string(vdp_st), vdp_st); -+ CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) checking for decoder support\n", m_vdpauConfig.vdpProcs.vdp_get_error_string(vdp_st), vdp_st); - FiniVDPAUProcs(); - return false; - } - -- vdp_decoder_destroy(decoder); -+ m_vdpauConfig.vdpProcs.vdp_decoder_destroy(m_vdpauConfig.vdpDecoder); - CheckStatus(vdp_st, __LINE__); - } - -- InitCSCMatrix(avctx->coded_height); -- - /* finally setup ffmpeg */ -- avctx->get_buffer = CVDPAU::FFGetBuffer; -- avctx->release_buffer = CVDPAU::FFReleaseBuffer; -- avctx->draw_horiz_band = CVDPAU::FFDrawSlice; -+ avctx->get_buffer = CDecoder::FFGetBuffer; -+ avctx->release_buffer = CDecoder::FFReleaseBuffer; -+ avctx->draw_horiz_band = CDecoder::FFDrawSlice; - 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 - return false; - } - --CVDPAU::~CVDPAU() -+CDecoder::~CDecoder() - { - Close(); - } - --void CVDPAU::Close() -+void CDecoder::Close() - { - CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); - -+ CSingleLock lock(m_DecoderSection); -+ - FiniVDPAUOutput(); - FiniVDPAUProcs(); -+ m_vdpauOutput.Dispose(); - - while (!m_videoSurfaces.empty()) - { -@@ -250,188 +201,111 @@ void CVDPAU::Close() - m_dllAvUtil.Unload(); - } - --bool CVDPAU::MakePixmapGL() -+long CDecoder::Release() - { -- int num=0; -- int fbConfigIndex = 0; -- -- int doubleVisAttributes[] = { -- GLX_RENDER_TYPE, GLX_RGBA_BIT, -- GLX_RED_SIZE, 8, -- GLX_GREEN_SIZE, 8, -- GLX_BLUE_SIZE, 8, -- GLX_ALPHA_SIZE, 8, -- GLX_DEPTH_SIZE, 8, -- GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, -- GLX_BIND_TO_TEXTURE_RGBA_EXT, True, -- GLX_DOUBLEBUFFER, True, -- GLX_Y_INVERTED_EXT, True, -- GLX_X_RENDERABLE, True, -- None -- }; -- -- int pixmapAttribs[] = { -- GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, -- GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, -- None -- }; -- -- 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); -+ 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, -+ 2000)) -+ { -+ bool success = reply->signal == COutputControlProtocol::ACC ? true : false; -+ reply->Release(); -+ if (!success) -+ { -+ CLog::Log(LOGERROR, "VDPAU::%s - pre-cleanup returned error", __FUNCTION__); -+ m_DisplayState = VDPAU_ERROR; -+ } -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "VDPAU::%s - pre-cleanup timed out", __FUNCTION__); -+ m_DisplayState = VDPAU_ERROR; -+ } - -- if (!m_glPixmap) -- { -- CLog::Log(LOGINFO, "GLX Error: Could not create Pixmap"); -- XFree(fbConfigs); -- return false; -+ for(unsigned int i = 0; i < m_videoSurfaces.size(); ++i) -+ { -+ vdpau_render_state *render = m_videoSurfaces[i]; -+ if (render->surface != VDP_INVALID_HANDLE && !(render->state & FF_VDPAU_STATE_USED_FOR_RENDER)) -+ { -+ m_vdpauConfig.vdpProcs.vdp_video_surface_destroy(render->surface); -+ render->surface = VDP_INVALID_HANDLE; -+ } -+ } - } -- XFree(fbConfigs); -+ IHardwareDecoder::Release(); -+} - -- return true; -+long CDecoder::ReleasePicReference() -+{ -+ return IHardwareDecoder::Release(); - } - --bool CVDPAU::MakePixmap(int width, int height) -+void CDecoder::SetWidthHeight(int width, int height) - { -+ m_vdpauConfig.upscale = g_advancedSettings.m_videoVDPAUScaling; -+ - //pick the smallest dimensions, so we downscale with vdpau and upscale with opengl when appropriate - //this requires the least amount of gpu memory bandwidth -- if (g_graphicsContext.GetWidth() < width || g_graphicsContext.GetHeight() < height || upScale) -+ if (g_graphicsContext.GetWidth() < width || g_graphicsContext.GetHeight() < height || m_vdpauConfig.upscale >= 0) - { - //scale width to desktop size if the aspect ratio is the same or bigger than the desktop - if ((double)height * g_graphicsContext.GetWidth() / width <= (double)g_graphicsContext.GetHeight()) - { -- OutWidth = g_graphicsContext.GetWidth(); -- OutHeight = MathUtils::round_int((double)height * g_graphicsContext.GetWidth() / width); -+ m_vdpauConfig.outWidth = g_graphicsContext.GetWidth(); -+ m_vdpauConfig.outHeight = MathUtils::round_int((double)height * g_graphicsContext.GetWidth() / width); - } - else //scale height to the desktop size if the aspect ratio is smaller than the desktop - { -- OutHeight = g_graphicsContext.GetHeight(); -- OutWidth = MathUtils::round_int((double)width * g_graphicsContext.GetHeight() / height); -+ m_vdpauConfig.outHeight = g_graphicsContext.GetHeight(); -+ m_vdpauConfig.outWidth = MathUtils::round_int((double)width * g_graphicsContext.GetHeight() / height); - } - } - else - { //let opengl scale -- OutWidth = width; -- OutHeight = height; -- } -- -- CLog::Log(LOGNOTICE,"Creating %ix%i pixmap", OutWidth, OutHeight); -- -- // Get our window attribs. -- XWindowAttributes wndattribs; -- XGetWindowAttributes(m_Display, DefaultRootWindow(m_Display), &wndattribs); // returns a status but I don't know what success is -- -- m_Pixmap = XCreatePixmap(m_Display, -- DefaultRootWindow(m_Display), -- OutWidth, -- OutHeight, -- wndattribs.depth); -- if (!m_Pixmap) -- { -- CLog::Log(LOGERROR, "GLX Error: MakePixmap: Unable to create XPixmap"); -- return false; -- } -- -- XGCValues values = {}; -- GC xgc; -- values.foreground = BlackPixel (m_Display, DefaultScreen (m_Display)); -- xgc = XCreateGC(m_Display, m_Pixmap, GCForeground, &values); -- XFillRectangle(m_Display, m_Pixmap, xgc, 0, 0, OutWidth, OutHeight); -- XFreeGC(m_Display, xgc); -- -- if(!MakePixmapGL()) -- return false; -- -- return true; --} -- --void CVDPAU::BindPixmap() --{ -- CSharedLock lock(m_DecoderSection); -- -- { CSharedLock dLock(m_DisplaySection); -- if (m_DisplayState != VDPAU_OPEN) -- return; -- } -- -- if (m_glPixmap) -- { -- if(presentSurface != VDP_INVALID_HANDLE) -- { -- VdpPresentationQueueStatus status; -- VdpTime time; -- VdpStatus vdp_st; -- vdp_st = vdp_presentation_queue_query_surface_status( -- vdp_flip_queue, presentSurface, &status, &time); -- CheckStatus(vdp_st, __LINE__); -- while(status != VDP_PRESENTATION_QUEUE_STATUS_VISIBLE && vdp_st == VDP_STATUS_OK) -- { -- Sleep(1); -- vdp_st = vdp_presentation_queue_query_surface_status( -- vdp_flip_queue, presentSurface, &status, &time); -- CheckStatus(vdp_st, __LINE__); -- } -- } -- -- glXBindTexImageEXT(m_Display, m_glPixmap, GLX_FRONT_LEFT_EXT, NULL); -- } -- else CLog::Log(LOGERROR,"(VDPAU) BindPixmap called without valid pixmap"); --} -- --void CVDPAU::ReleasePixmap() --{ -- CSharedLock lock(m_DecoderSection); -- -- { CSharedLock dLock(m_DisplaySection); -- if (m_DisplayState != VDPAU_OPEN) -- return; -- } -- -- if (m_glPixmap) -- { -- glXReleaseTexImageEXT(m_Display, m_glPixmap, GLX_FRONT_LEFT_EXT); -+ m_vdpauConfig.outWidth = width; -+ m_vdpauConfig.outHeight = height; - } -- else CLog::Log(LOGERROR,"(VDPAU) ReleasePixmap called without valid pixmap"); -+ CLog::Log(LOGDEBUG, "CVDPAU::SetWidthHeight Setting OutWidth: %i OutHeight: %i", m_vdpauConfig.outWidth, m_vdpauConfig.outHeight); - } - --void CVDPAU::OnLostDevice() -+void CDecoder::OnLostDevice() - { - CLog::Log(LOGNOTICE,"CVDPAU::OnLostDevice event"); - -- CExclusiveLock lock(m_DecoderSection); -+ CSingleLock lock(m_DecoderSection); - FiniVDPAUOutput(); - FiniVDPAUProcs(); - - m_DisplayState = VDPAU_LOST; -+ lock.Leave(); - m_DisplayEvent.Reset(); - } - --void CVDPAU::OnResetDevice() -+void CDecoder::OnResetDevice() - { - CLog::Log(LOGNOTICE,"CVDPAU::OnResetDevice event"); - -- CExclusiveLock lock(m_DisplaySection); -+ CSingleLock lock(m_DecoderSection); - if (m_DisplayState == VDPAU_LOST) - { - m_DisplayState = VDPAU_RESET; -+ lock.Leave(); - m_DisplayEvent.Set(); - } - } - --int CVDPAU::Check(AVCodecContext* avctx) -+int CDecoder::Check(AVCodecContext* avctx) - { - EDisplayState state; - -- { CSharedLock lock(m_DisplaySection); -+ { CSingleLock lock(m_DecoderSection); - state = m_DisplayState; - } - -@@ -445,16 +319,13 @@ int CVDPAU::Check(AVCodecContext* avctx) - } - else - { -- CSharedLock lock(m_DisplaySection); -+ CSingleLock lock(m_DecoderSection); - state = m_DisplayState; - } - } - if (state == VDPAU_RESET || state == VDPAU_ERROR) - { -- CLog::Log(LOGNOTICE,"Attempting recovery"); -- -- CSingleLock gLock(g_graphicsContext); -- CExclusiveLock lock(m_DecoderSection); -+ CSingleLock lock(m_DecoderSection); - - FiniVDPAUOutput(); - FiniVDPAUProcs(); -@@ -469,7 +340,7 @@ int CVDPAU::Check(AVCodecContext* avctx) - return 0; - } - --bool CVDPAU::IsVDPAUFormat(PixelFormat format) -+bool CDecoder::IsVDPAUFormat(PixelFormat format) - { - 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) - else return false; - } - --void CVDPAU::CheckFeatures() --{ -- if (videoMixer == VDP_INVALID_HANDLE) -- { -- CLog::Log(LOGNOTICE, " (VDPAU) Creating the video mixer"); -- // Creation of VideoMixer. -- VdpVideoMixerParameter parameters[] = { -- VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, -- VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, -- VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE -- }; -- -- void const * parameter_values[] = { -- &surface_width, -- &surface_height, -- &vdp_chroma_type -- }; -- -- tmpBrightness = 0; -- tmpContrast = 0; -- tmpNoiseReduction = 0; -- tmpSharpness = 0; -- -- VdpStatus vdp_st = VDP_STATUS_ERROR; -- vdp_st = vdp_video_mixer_create(vdp_device, -- m_feature_count, -- m_features, -- ARSIZE(parameters), -- parameters, -- parameter_values, -- &videoMixer); -- CheckStatus(vdp_st, __LINE__); -- -- SetHWUpscaling(); -- } -- -- if (tmpBrightness != g_settings.m_currentVideoSettings.m_Brightness || -- tmpContrast != g_settings.m_currentVideoSettings.m_Contrast) -- { -- SetColor(); -- tmpBrightness = g_settings.m_currentVideoSettings.m_Brightness; -- tmpContrast = g_settings.m_currentVideoSettings.m_Contrast; -- } -- if (tmpNoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) -- { -- tmpNoiseReduction = g_settings.m_currentVideoSettings.m_NoiseReduction; -- SetNoiseReduction(); -- } -- if (tmpSharpness != g_settings.m_currentVideoSettings.m_Sharpness) -- { -- tmpSharpness = g_settings.m_currentVideoSettings.m_Sharpness; -- SetSharpness(); -- } -- if ( tmpDeintMode != g_settings.m_currentVideoSettings.m_DeinterlaceMode || -- tmpDeintGUI != g_settings.m_currentVideoSettings.m_InterlaceMethod || -- (tmpDeintGUI == VS_INTERLACEMETHOD_AUTO && tmpDeint != AutoInterlaceMethod())) -- { -- tmpDeintMode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -- tmpDeintGUI = g_settings.m_currentVideoSettings.m_InterlaceMethod; -- if (tmpDeintGUI == VS_INTERLACEMETHOD_AUTO) -- tmpDeint = AutoInterlaceMethod(); -- else -- tmpDeint = tmpDeintGUI; -- -- SetDeinterlacing(); -- } --} -- --bool CVDPAU::Supports(VdpVideoMixerFeature feature) -+bool CDecoder::Supports(VdpVideoMixerFeature feature) - { -- for(int i = 0; i < m_feature_count; i++) -+ for(int i = 0; i < m_vdpauConfig.featureCount; i++) - { -- if(m_features[i] == feature) -+ if(m_vdpauConfig.vdpFeatures[i] == feature) - return true; - } - return false; - } - --bool CVDPAU::Supports(EINTERLACEMETHOD method) -+bool CDecoder::Supports(EINTERLACEMETHOD method) - { - if(method == VS_INTERLACEMETHOD_VDPAU_BOB -- || method == VS_INTERLACEMETHOD_AUTO -- || method == VS_INTERLACEMETHOD_AUTO_ION) -+ || 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; - } - --EINTERLACEMETHOD CVDPAU::AutoInterlaceMethod() --{ -- return VS_INTERLACEMETHOD_VDPAU_TEMPORAL; --} -- --void CVDPAU::SetColor() --{ -- VdpStatus vdp_st; -- -- if (tmpBrightness != g_settings.m_currentVideoSettings.m_Brightness) -- m_Procamp.brightness = (float)((g_settings.m_currentVideoSettings.m_Brightness)-50) / 100; -- if (tmpContrast != g_settings.m_currentVideoSettings.m_Contrast) -- m_Procamp.contrast = (float)((g_settings.m_currentVideoSettings.m_Contrast)+50) / 100; -- -- if(vid_height >= 600 || vid_width > 1024) -- vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); -- else -- 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")) -- { -- void const * pm_CSCMatix[] = { &studioCSC }; -- vdp_st = vdp_video_mixer_set_attribute_values(videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -- else -- { -- void const * pm_CSCMatix[] = { &m_CSCMatrix }; -- vdp_st = vdp_video_mixer_set_attribute_values(videoMixer, ARSIZE(attributes), attributes, pm_CSCMatix); -- } -- CheckStatus(vdp_st, __LINE__); --} -- --void CVDPAU::SetNoiseReduction() --{ -- if(!Supports(VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION)) -- return; -- -- VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION }; -- VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL }; -- VdpStatus vdp_st; -- -- if (!g_settings.m_currentVideoSettings.m_NoiseReduction) -- { -- VdpBool enabled[]= {0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- CheckStatus(vdp_st, __LINE__); -- return; -- } -- VdpBool enabled[]={1}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- CheckStatus(vdp_st, __LINE__); -- void* nr[] = { &g_settings.m_currentVideoSettings.m_NoiseReduction }; -- CLog::Log(LOGNOTICE,"Setting Noise Reduction to %f",g_settings.m_currentVideoSettings.m_NoiseReduction); -- 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)) -- return; -- -- VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_SHARPNESS }; -- VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL }; -- VdpStatus vdp_st; -- -- if (!g_settings.m_currentVideoSettings.m_Sharpness) -- { -- VdpBool enabled[]={0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- CheckStatus(vdp_st, __LINE__); -- return; -- } -- VdpBool enabled[]={1}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- CheckStatus(vdp_st, __LINE__); -- void* sh[] = { &g_settings.m_currentVideoSettings.m_Sharpness }; -- CLog::Log(LOGNOTICE,"Setting Sharpness to %f",g_settings.m_currentVideoSettings.m_Sharpness); -- vdp_st = vdp_video_mixer_set_attribute_values(videoMixer, ARSIZE(attributes), attributes, sh); -- CheckStatus(vdp_st, __LINE__); --} -- --void CVDPAU::SetHWUpscaling() --{ --#ifdef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 -- if(!Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1) || !upScale) -- return; -- -- VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 }; -- VdpStatus vdp_st; -- VdpBool enabled[]={1}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- CheckStatus(vdp_st, __LINE__); --#endif --} -- --void CVDPAU::SetDeinterlacing() -+EINTERLACEMETHOD CDecoder::AutoInterlaceMethod() - { -- VdpStatus vdp_st; -- EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -- EINTERLACEMETHOD method = g_settings.m_currentVideoSettings.m_InterlaceMethod; -- if (method == VS_INTERLACEMETHOD_AUTO) -- method = AutoInterlaceMethod(); -- -- VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, -- VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, -- VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE }; -- if (mode == VS_DEINTERLACEMODE_OFF) -- { -- VdpBool enabled[]={0,0,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- else -- { -- if (method == VS_INTERLACEMETHOD_AUTO_ION) -- { -- if (vid_height <= 576) -- { -- VdpBool enabled[]={1,1,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- else if (vid_height > 576) -- { -- VdpBool enabled[]={1,0,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- } -- else if (method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF) -- { -- VdpBool enabled[]={1,0,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- else if (method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF) -- { -- VdpBool enabled[]={1,1,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- else if (method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE) -- { -- VdpBool enabled[]={1,0,1}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- else -- { -- VdpBool enabled[]={0,0,0}; -- vdp_st = vdp_video_mixer_set_feature_enables(videoMixer, ARSIZE(feature), feature, enabled); -- } -- } -- -- CheckStatus(vdp_st, __LINE__); -+ return VS_INTERLACEMETHOD_RENDER_BOB; - } - --void CVDPAU::InitVDPAUProcs() -+void CDecoder::InitVDPAUProcs() - { - char* error; - -@@ -736,151 +394,115 @@ void CVDPAU::InitVDPAUProcs() - if (error) - { - CLog::Log(LOGERROR,"(VDPAU) - %s in %s",error,__FUNCTION__); -- vdp_device = VDP_INVALID_HANDLE; -- -- //g_application.m_guiDialogKaiToast.QueueNotification(CGUIDialogKaiToast::Error, "VDPAU", error, 10000); -- -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; - return; - } - - if (dl_vdp_device_create_x11) - { -- CSingleLock lock(g_graphicsContext); -- m_Display = g_Windowing.GetDisplay(); -- } -- else -- { -- CLog::Log(LOGERROR,"(VDPAU) - Unable to get dl_vdp_device_create_x11 in %s", __FUNCTION__); -- vdp_device = VDP_INVALID_HANDLE; -- return; -+ m_Display = XOpenDisplay(NULL); - } - -- int mScreen = DefaultScreen(m_Display); -+ int mScreen = g_Windowing.GetCurrentScreen(); - VdpStatus vdp_st; - - // Create Device -- // tested on 64bit Ubuntu 11.10 and it deadlocked without this -- XLockDisplay(m_Display); - vdp_st = dl_vdp_device_create_x11(m_Display, //x_display, - mScreen, //x_screen, -- &vdp_device, -- &vdp_get_proc_address); -- XUnlockDisplay(m_Display); -+ &m_vdpauConfig.vdpDevice, -+ &m_vdpauConfig.vdpProcs.vdp_get_proc_address); - -- CLog::Log(LOGNOTICE,"vdp_device = 0x%08x vdp_st = 0x%08x",vdp_device,vdp_st); -+ CLog::Log(LOGNOTICE,"vdp_device = 0x%08x vdp_st = 0x%08x",m_vdpauConfig.vdpDevice,vdp_st); - if (vdp_st != VDP_STATUS_OK) - { - CLog::Log(LOGERROR,"(VDPAU) unable to init VDPAU - vdp_st = 0x%x. Falling back.",vdp_st); -- vdp_device = VDP_INVALID_HANDLE; -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; - return; - } - - #define VDP_PROC(id, proc) \ - do { \ -- vdp_st = vdp_get_proc_address(vdp_device, id, (void**)&proc); \ -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_get_proc_address(m_vdpauConfig.vdpDevice, id, (void**)&proc); \ - CheckStatus(vdp_st, __LINE__); \ - } while(0); - -- VDP_PROC(VDP_FUNC_ID_GET_ERROR_STRING , vdp_get_error_string); -- VDP_PROC(VDP_FUNC_ID_DEVICE_DESTROY , vdp_device_destroy); -- VDP_PROC(VDP_FUNC_ID_GENERATE_CSC_MATRIX , vdp_generate_csc_matrix); -- VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_CREATE , vdp_video_surface_create); -- VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY , vdp_video_surface_destroy); -- VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR , vdp_video_surface_put_bits_y_cb_cr); -- VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR , vdp_video_surface_get_bits_y_cb_cr); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR , vdp_output_surface_put_bits_y_cb_cr); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE , vdp_output_surface_put_bits_native); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE , vdp_output_surface_create); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY , vdp_output_surface_destroy); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE , vdp_output_surface_get_bits_native); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, vdp_output_surface_render_output_surface); -- VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED , vdp_output_surface_put_bits_indexed); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_CREATE , vdp_video_mixer_create); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES , vdp_video_mixer_set_feature_enables); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_DESTROY , vdp_video_mixer_destroy); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_RENDER , vdp_video_mixer_render); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES , vdp_video_mixer_set_attribute_values); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT , vdp_video_mixer_query_parameter_support); -- VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT , vdp_video_mixer_query_feature_support); -- VDP_PROC(VDP_FUNC_ID_DECODER_CREATE , vdp_decoder_create); -- VDP_PROC(VDP_FUNC_ID_DECODER_DESTROY , vdp_decoder_destroy); -- VDP_PROC(VDP_FUNC_ID_DECODER_RENDER , vdp_decoder_render); -- VDP_PROC(VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES , vdp_decoder_query_caps); -- VDP_PROC(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER , vdp_preemption_callback_register); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY , vdp_presentation_queue_target_destroy); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE , vdp_presentation_queue_create); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY , vdp_presentation_queue_destroy); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY , vdp_presentation_queue_display); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, vdp_presentation_queue_block_until_surface_idle); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11 , vdp_presentation_queue_target_create_x11); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS , vdp_presentation_queue_query_surface_status); -- VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME , vdp_presentation_queue_get_time); -- -+ VDP_PROC(VDP_FUNC_ID_GET_ERROR_STRING , m_vdpauConfig.vdpProcs.vdp_get_error_string); -+ VDP_PROC(VDP_FUNC_ID_DEVICE_DESTROY , m_vdpauConfig.vdpProcs.vdp_device_destroy); -+ VDP_PROC(VDP_FUNC_ID_GENERATE_CSC_MATRIX , m_vdpauConfig.vdpProcs.vdp_generate_csc_matrix); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_CREATE , m_vdpauConfig.vdpProcs.vdp_video_surface_create); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY , m_vdpauConfig.vdpProcs.vdp_video_surface_destroy); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR , m_vdpauConfig.vdpProcs.vdp_video_surface_put_bits_y_cb_cr); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR , m_vdpauConfig.vdpProcs.vdp_video_surface_get_bits_y_cb_cr); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR , m_vdpauConfig.vdpProcs.vdp_output_surface_put_bits_y_cb_cr); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE , m_vdpauConfig.vdpProcs.vdp_output_surface_put_bits_native); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE , m_vdpauConfig.vdpProcs.vdp_output_surface_create); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY , m_vdpauConfig.vdpProcs.vdp_output_surface_destroy); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE , m_vdpauConfig.vdpProcs.vdp_output_surface_get_bits_native); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, m_vdpauConfig.vdpProcs.vdp_output_surface_render_output_surface); -+ VDP_PROC(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED , m_vdpauConfig.vdpProcs.vdp_output_surface_put_bits_indexed); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_CREATE , m_vdpauConfig.vdpProcs.vdp_video_mixer_create); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES , m_vdpauConfig.vdpProcs.vdp_video_mixer_set_feature_enables); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_DESTROY , m_vdpauConfig.vdpProcs.vdp_video_mixer_destroy); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_RENDER , m_vdpauConfig.vdpProcs.vdp_video_mixer_render); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES , m_vdpauConfig.vdpProcs.vdp_video_mixer_set_attribute_values); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT , m_vdpauConfig.vdpProcs.vdp_video_mixer_query_parameter_support); -+ VDP_PROC(VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT , m_vdpauConfig.vdpProcs.vdp_video_mixer_query_feature_support); -+ VDP_PROC(VDP_FUNC_ID_DECODER_CREATE , m_vdpauConfig.vdpProcs.vdp_decoder_create); -+ VDP_PROC(VDP_FUNC_ID_DECODER_DESTROY , m_vdpauConfig.vdpProcs.vdp_decoder_destroy); -+ VDP_PROC(VDP_FUNC_ID_DECODER_RENDER , m_vdpauConfig.vdpProcs.vdp_decoder_render); -+ VDP_PROC(VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES , m_vdpauConfig.vdpProcs.vdp_decoder_query_caps); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY , m_vdpauConfig.vdpProcs.vdp_presentation_queue_target_destroy); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE , m_vdpauConfig.vdpProcs.vdp_presentation_queue_create); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY , m_vdpauConfig.vdpProcs.vdp_presentation_queue_destroy); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY , m_vdpauConfig.vdpProcs.vdp_presentation_queue_display); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, m_vdpauConfig.vdpProcs.vdp_presentation_queue_block_until_surface_idle); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11 , m_vdpauConfig.vdpProcs.vdp_presentation_queue_target_create_x11); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS , m_vdpauConfig.vdpProcs.vdp_presentation_queue_query_surface_status); -+ VDP_PROC(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME , m_vdpauConfig.vdpProcs.vdp_presentation_queue_get_time); -+ - #undef VDP_PROC - - // set all vdpau resources to invalid -- vdp_flip_target = VDP_INVALID_HANDLE; -- vdp_flip_queue = VDP_INVALID_HANDLE; -- videoMixer = VDP_INVALID_HANDLE; -- totalAvailableOutputSurfaces = 0; -- presentSurface = VDP_INVALID_HANDLE; -- outputSurface = VDP_INVALID_HANDLE; -- for (int i = 0; i < NUM_OUTPUT_SURFACES; i++) -- outputSurfaces[i] = VDP_INVALID_HANDLE; -- -- m_vdpauOutputMethod = OUTPUT_NONE; -- -- CExclusiveLock lock(m_DisplaySection); - m_DisplayState = VDPAU_OPEN; -- vdpauConfigured = false; -+ m_vdpauConfigured = false; - } - --void CVDPAU::FiniVDPAUProcs() -+void CDecoder::FiniVDPAUProcs() - { -- if (vdp_device == VDP_INVALID_HANDLE) return; -+ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE) return; - - 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__); -- vdp_device = VDP_INVALID_HANDLE; -- vdpauConfigured = false; -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; - } - --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; -- m_Procamp.contrast = 1.0; -- m_Procamp.saturation = 1.0; -- m_Procamp.hue = 0; -- 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(); - -- if (vdp_device == VDP_INVALID_HANDLE || !vdpauConfigured) return; -- -- CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); -- -- 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__)) - return; -- decoder = VDP_INVALID_HANDLE; -+ m_vdpauConfig.vdpDecoder = VDP_INVALID_HANDLE; -+ -+ CSingleLock lock(m_videoSurfaceSec); -+ CLog::Log(LOGDEBUG, "CVDPAU::FiniVDPAUOutput destroying %d video surfaces", (int)m_videoSurfaces.size()); - -- for (unsigned int i = 0; i < m_videoSurfaces.size(); ++i) -+ for(unsigned int i = 0; i < m_videoSurfaces.size(); ++i) - { - vdpau_render_state *render = m_videoSurfaces[i]; - if (render->surface != VDP_INVALID_HANDLE) - { -- vdp_st = vdp_video_surface_destroy(render->surface); -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_video_surface_destroy(render->surface); - render->surface = VDP_INVALID_HANDLE; - } - if (CheckStatus(vdp_st, __LINE__)) -@@ -888,8 +510,7 @@ void CVDPAU::FiniVDPAUOutput() - } - } - -- --void CVDPAU::ReadFormatOf( PixelFormat fmt -+void CDecoder::ReadFormatOf( PixelFormat fmt - , VdpDecoderProfile &vdp_decoder_profile - , VdpChromaType &vdp_chroma_type) - { -@@ -916,9 +537,9 @@ void CVDPAU::ReadFormatOf( PixelFormat fmt - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; - #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_chroma_type = VDP_CHROMA_TYPE_420; - break; - #endif -@@ -929,170 +550,78 @@ void CVDPAU::ReadFormatOf( PixelFormat fmt - } - } - -- --bool CVDPAU::ConfigVDPAU(AVCodecContext* avctx, int ref_frames) -+bool CDecoder::ConfigVDPAU(AVCodecContext* avctx, int ref_frames) - { - FiniVDPAUOutput(); - - VdpStatus vdp_st; - VdpDecoderProfile vdp_decoder_profile; -- vid_width = avctx->width; -- 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; -+ m_vdpauConfig.surfaceHeight = avctx->coded_height; -+ -+ SetWidthHeight(avctx->width,avctx->height); -+ -+ CLog::Log(LOGNOTICE, " (VDPAU) screenWidth:%i vidWidth:%i surfaceWidth:%i",m_vdpauConfig.outWidth,m_vdpauConfig.vidWidth,m_vdpauConfig.surfaceWidth); -+ CLog::Log(LOGNOTICE, " (VDPAU) screenHeight:%i vidHeight:%i surfaceHeight:%i",m_vdpauConfig.outHeight,m_vdpauConfig.vidHeight,m_vdpauConfig.surfaceHeight); -+ -+ ReadFormatOf(avctx->pix_fmt, vdp_decoder_profile, m_vdpauConfig.vdpChromaType); - - if(avctx->pix_fmt == PIX_FMT_VDPAU_H264) - { -- max_references = ref_frames; -- if (max_references > 16) max_references = 16; -- if (max_references < 5) max_references = 5; -+ m_vdpauConfig.maxReferences = ref_frames; -+ if (m_vdpauConfig.maxReferences > 16) m_vdpauConfig.maxReferences = 16; -+ if (m_vdpauConfig.maxReferences < 5) m_vdpauConfig.maxReferences = 5; - } - else -- max_references = 2; -+ m_vdpauConfig.maxReferences = 2; - -- vdp_st = vdp_decoder_create(vdp_device, -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_decoder_create(m_vdpauConfig.vdpDevice, - vdp_decoder_profile, -- surface_width, -- surface_height, -- max_references, -- &decoder); -- if (CheckStatus(vdp_st, __LINE__)) -- return false; -- -- m_vdpauOutputMethod = OUTPUT_NONE; -- -- vdpauConfigured = true; -- return true; --} -- --bool CVDPAU::ConfigOutputMethod(AVCodecContext *avctx, AVFrame *pFrame) --{ -- VdpStatus vdp_st; -- -- if (m_vdpauOutputMethod == OUTPUT_PIXMAP) -- return true; -- -- FiniOutputMethod(); -- -- MakePixmap(avctx->width,avctx->height); -- -- vdp_st = vdp_presentation_queue_target_create_x11(vdp_device, -- m_Pixmap, //x_window, -- &vdp_flip_target); -- if (CheckStatus(vdp_st, __LINE__)) -- return false; -- -- vdp_st = vdp_presentation_queue_create(vdp_device, -- vdp_flip_target, -- &vdp_flip_queue); -+ m_vdpauConfig.surfaceWidth, -+ m_vdpauConfig.surfaceHeight, -+ m_vdpauConfig.maxReferences, -+ &m_vdpauConfig.vdpDecoder); - if (CheckStatus(vdp_st, __LINE__)) - return false; - -- totalAvailableOutputSurfaces = 0; -- -- int tmpMaxOutputSurfaces = NUM_OUTPUT_SURFACES; -- if (vid_width == FULLHD_WIDTH) -- tmpMaxOutputSurfaces = NUM_OUTPUT_SURFACES_FOR_FULLHD; -- -- // Creation of outputSurfaces -- for (int i = 0; i < NUM_OUTPUT_SURFACES && i < tmpMaxOutputSurfaces; i++) -- { -- vdp_st = vdp_output_surface_create(vdp_device, -- VDP_RGBA_FORMAT_B8G8R8A8, -- OutWidth, -- OutHeight, -- &outputSurfaces[i]); -- if (CheckStatus(vdp_st, __LINE__)) -+ // initialize output -+ CSingleLock lock(g_graphicsContext); -+ m_vdpauConfig.stats = &m_bufferStats; -+ m_vdpauConfig.vdpau = this; -+ m_bufferStats.Reset(); -+ m_vdpauOutput.Start(); -+ Message *reply; -+ if (m_vdpauOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::INIT, -+ &reply, -+ 2000, -+ &m_vdpauConfig, -+ sizeof(m_vdpauConfig))) -+ { -+ bool success = reply->signal == COutputControlProtocol::ACC ? true : false; -+ reply->Release(); -+ if (!success) -+ { -+ CLog::Log(LOGERROR, "VDPAU::%s - vdpau output returned error", __FUNCTION__); -+ m_vdpauOutput.Dispose(); - return false; -- totalAvailableOutputSurfaces++; -- } -- CLog::Log(LOGNOTICE, " (VDPAU) Total Output Surfaces Available: %i of a max (tmp: %i const: %i)", -- totalAvailableOutputSurfaces, -- tmpMaxOutputSurfaces, -- NUM_OUTPUT_SURFACES); -- -- // create 3 pitches of black lines needed for clipping top -- // and bottom lines when de-interlacing -- m_BlackBar = new uint32_t[3*OutWidth]; -- memset(m_BlackBar, 0, 3*OutWidth*sizeof(uint32_t)); -- -- surfaceNum = presentSurfaceNum = 0; -- outputSurface = presentSurface = VDP_INVALID_HANDLE; -- videoMixer = VDP_INVALID_HANDLE; -- -- m_vdpauOutputMethod = OUTPUT_PIXMAP; -- -- return true; --} -- --bool CVDPAU::FiniOutputMethod() --{ -- VdpStatus vdp_st; -- -- if (vdp_flip_queue != VDP_INVALID_HANDLE) -- { -- vdp_st = vdp_presentation_queue_destroy(vdp_flip_queue); -- vdp_flip_queue = VDP_INVALID_HANDLE; -- CheckStatus(vdp_st, __LINE__); -- } -- -- if (vdp_flip_target != VDP_INVALID_HANDLE) -- { -- vdp_st = vdp_presentation_queue_target_destroy(vdp_flip_target); -- vdp_flip_target = VDP_INVALID_HANDLE; -- CheckStatus(vdp_st, __LINE__); -- } -- -- if (m_glPixmap) -- { -- CLog::Log(LOGDEBUG, "GLX: Destroying glPixmap"); -- glXDestroyPixmap(m_Display, m_glPixmap); -- m_glPixmap = None; -- } -- -- if (m_Pixmap) -- { -- CLog::Log(LOGDEBUG, "GLX: Destroying XPixmap"); -- XFreePixmap(m_Display, m_Pixmap); -- m_Pixmap = None; -- } -- -- outputSurface = presentSurface = VDP_INVALID_HANDLE; -- -- for (int i = 0; i < totalAvailableOutputSurfaces; i++) -- { -- if (outputSurfaces[i] == VDP_INVALID_HANDLE) -- continue; -- vdp_st = vdp_output_surface_destroy(outputSurfaces[i]); -- outputSurfaces[i] = VDP_INVALID_HANDLE; -- CheckStatus(vdp_st, __LINE__); -- } -- -- if (videoMixer != VDP_INVALID_HANDLE) -- { -- vdp_st = vdp_video_mixer_destroy(videoMixer); -- videoMixer = VDP_INVALID_HANDLE; -- CheckStatus(vdp_st, __LINE__); -+ } - } -- -- if (m_BlackBar) -+ else - { -- delete [] m_BlackBar; -- m_BlackBar = NULL; -+ CLog::Log(LOGERROR, "VDPAU::%s - failed to init output", __FUNCTION__); -+ m_vdpauOutput.Dispose(); -+ return false; - } - -- while (!m_DVDVideoPics.empty()) -- m_DVDVideoPics.pop(); -- -+ m_inMsgEvent.Reset(); -+ m_vdpauConfigured = true; - return true; - } - --void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der Laan -- VDPInfo -+void CDecoder::SpewHardwareAvailable() //CopyrighVDPAUt (c) 2008 Wladimir J. van der Laan -- VDPInfo - { - VdpStatus rv; - CLog::Log(LOGNOTICE,"VDPAU Decoder capabilities:"); -@@ -1102,7 +631,7 @@ void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der L - { - VdpBool is_supported = false; - uint32_t max_level, max_macroblocks, max_width, max_height; -- rv = vdp_decoder_query_caps(vdp_device, decoder_profiles[x].id, -+ rv = m_vdpauConfig.vdpProcs.vdp_decoder_query_caps(m_vdpauConfig.vdpDevice, decoder_profiles[x].id, - &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 - } - } - CLog::Log(LOGNOTICE,"------------------------------------"); -- m_feature_count = 0; -+ m_vdpauConfig.featureCount = 0; - #define CHECK_SUPPORT(feature) \ - do { \ - VdpBool supported; \ -- if(vdp_video_mixer_query_feature_support(vdp_device, feature, &supported) == VDP_STATUS_OK && supported) { \ -+ if(m_vdpauConfig.vdpProcs.vdp_video_mixer_query_feature_support(m_vdpauConfig.vdpDevice, feature, &supported) == VDP_STATUS_OK && supported) { \ - CLog::Log(LOGNOTICE, "Mixer feature: "#feature); \ -- m_features[m_feature_count++] = feature; \ -+ m_vdpauConfig.vdpFeatures[m_vdpauConfig.featureCount++] = feature; \ - } \ - } while(false) - -@@ -1141,7 +670,7 @@ void CVDPAU::SpewHardwareAvailable() //Copyright (c) 2008 Wladimir J. van der L - - } - --bool CVDPAU::IsSurfaceValid(vdpau_render_state *render) -+bool CDecoder::IsSurfaceValid(vdpau_render_state *render) - { - // find render state in queue - bool found(false); -@@ -1168,34 +697,33 @@ bool CVDPAU::IsSurfaceValid(vdpau_render_state *render) - return true; - } - --int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) -+int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) - { - //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); - CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; -- CVDPAU* vdp = (CVDPAU*)ctx->GetHardware(); -- struct pictureAge* pA = &vdp->picAge; -+ CDecoder* vdp = (CDecoder*)ctx->GetHardware(); - - // while we are waiting to recover we can't do anything -- CSharedLock lock(vdp->m_DecoderSection); -+ CSingleLock lock(vdp->m_DecoderSection); - -- { CSharedLock dLock(vdp->m_DisplaySection); -- if(vdp->m_DisplayState != VDPAU_OPEN) -- { -- CLog::Log(LOGWARNING, "CVDPAU::FFGetBuffer - returning due to awaiting recovery"); -- return -1; -- } -+ if(vdp->m_DisplayState != VDPAU_OPEN) -+ { -+ CLog::Log(LOGWARNING, "CVDPAU::FFGetBuffer - returning due to awaiting recovery"); -+ return -1; - } - - vdpau_render_state * render = NULL; - - // find unused surface -- for(unsigned int i = 0; i < vdp->m_videoSurfaces.size(); i++) -- { -- if(!(vdp->m_videoSurfaces[i]->state & (FF_VDPAU_STATE_USED_FOR_REFERENCE | FF_VDPAU_STATE_USED_FOR_RENDER))) -+ { CSingleLock lock(vdp->m_videoSurfaceSec); -+ for(unsigned int i = 0; i < vdp->m_videoSurfaces.size(); i++) - { -- render = vdp->m_videoSurfaces[i]; -- render->state = 0; -- break; -+ if(!(vdp->m_videoSurfaces[i]->state & (FF_VDPAU_STATE_USED_FOR_REFERENCE | FF_VDPAU_STATE_USED_FOR_RENDER))) -+ { -+ render = vdp->m_videoSurfaces[i]; -+ render->state = 0; -+ break; -+ } - } - } - -@@ -1204,21 +732,22 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) - { - // create a new surface - VdpDecoderProfile profile; -- ReadFormatOf(avctx->pix_fmt, profile, vdp->vdp_chroma_type); -+ ReadFormatOf(avctx->pix_fmt, profile, vdp->m_vdpauConfig.vdpChromaType); - render = (vdpau_render_state*)calloc(sizeof(vdpau_render_state), 1); - if (render == NULL) - { - CLog::Log(LOGWARNING, "CVDPAU::FFGetBuffer - calloc failed"); - return -1; - } -+ CSingleLock lock(vdp->m_videoSurfaceSec); - render->surface = VDP_INVALID_HANDLE; - vdp->m_videoSurfaces.push_back(render); - } - - if (render->surface == VDP_INVALID_HANDLE) - { -- vdp_st = vdp->vdp_video_surface_create(vdp->vdp_device, -- vdp->vdp_chroma_type, -+ vdp_st = vdp->m_vdpauConfig.vdpProcs.vdp_video_surface_create(vdp->m_vdpauConfig.vdpDevice, -+ vdp->m_vdpauConfig.vdpChromaType, - avctx->coded_width, - avctx->coded_height, - &render->surface); -@@ -1239,18 +768,6 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) - - pic->linesize[0] = pic->linesize[1] = pic->linesize[2] = 0; - -- if(pic->reference) -- { -- pA->ip_age[0]= pA->ip_age[1]+1; -- pA->ip_age[1]= 1; -- pA->b_age++; -- } -- else -- { -- pA->ip_age[0]++; -- pA->ip_age[1]++; -- pA->b_age = 1; -- } - 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) - return 0; - } - --void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) -+void CDecoder::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) - { - //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); - CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; -- CVDPAU* vdp = (CVDPAU*)ctx->GetHardware(); -+ CDecoder* vdp = (CDecoder*)ctx->GetHardware(); -+ - vdpau_render_state * render; - unsigned int i; - -- CSharedLock lock(vdp->m_DecoderSection); -+ CSingleLock lock(vdp->m_DecoderSection); - - render=(vdpau_render_state*)pic->data[0]; - if(!render) -@@ -1275,6 +793,8 @@ void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) - return; - } - -+ CSingleLock vLock(vdp->m_videoSurfaceSec); -+ render->state &= ~FF_VDPAU_STATE_USED_FOR_REFERENCE; - for(i=0; i<4; i++) - pic->data[i]= NULL; - -@@ -1289,21 +809,18 @@ void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) - } - - --void CVDPAU::FFDrawSlice(struct AVCodecContext *s, -+void CDecoder::FFDrawSlice(struct AVCodecContext *s, - const AVFrame *src, int offset[4], - int y, int type, int height) - { - CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)s->opaque; -- CVDPAU* vdp = (CVDPAU*)ctx->GetHardware(); -+ CDecoder* vdp = (CDecoder*)ctx->GetHardware(); - - // while we are waiting to recover we can't do anything -- CSharedLock lock(vdp->m_DecoderSection); -- -- { CSharedLock dLock(vdp->m_DisplaySection); -- if(vdp->m_DisplayState != VDPAU_OPEN) -- return; -- } -+ CSingleLock lock(vdp->m_DecoderSection); - -+ if(vdp->m_DisplayState != VDPAU_OPEN) -+ return; - - 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, - if(s->pix_fmt == PIX_FMT_VDPAU_H264) - max_refs = render->info.h264.num_ref_frames; - -- if(vdp->decoder == VDP_INVALID_HANDLE -- || vdp->vdpauConfigured == false -- || vdp->max_references < max_refs) -+ if(vdp->m_vdpauConfig.vdpDecoder == VDP_INVALID_HANDLE -+ || vdp->m_vdpauConfigured == false -+ || vdp->m_vdpauConfig.maxReferences < max_refs) - { - if(!vdp->ConfigVDPAU(s, max_refs)) - return; - } - -- vdp_st = vdp->vdp_decoder_render(vdp->decoder, -+ uint64_t startTime = CurrentHostCounter(); -+ uint16_t decoded, processed, rend; -+ vdp->m_bufferStats.Get(decoded, processed, rend); -+ vdp_st = vdp->m_vdpauConfig.vdpProcs.vdp_decoder_render(vdp->m_vdpauConfig.vdpDecoder, - render->surface, - (VdpPictureInfo const *)&(render->info), - render->bitstream_buffers_used, - render->bitstream_buffers); - vdp->CheckStatus(vdp_st, __LINE__); -+ uint64_t diff = CurrentHostCounter() - startTime; -+ if (diff*1000/CurrentHostFrequency() > 30) -+ CLog::Log(LOGWARNING,"CVDPAU::DrawSlice - VdpDecoderRender long decoding: %d ms, dec: %d, proc: %d, rend: %d", (int)((diff*1000)/CurrentHostFrequency()), decoded, processed, rend); -+ - } - --int CVDPAU::Decode(AVCodecContext *avctx, AVFrame *pFrame) --{ -- //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); -- VdpStatus vdp_st; -- VdpTime time; - -+int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) -+{ - int result = Check(avctx); - if (result) - return result; - -- CSharedLock lock(m_DecoderSection); -+ CSingleLock lock(m_DecoderSection); - -- if (!vdpauConfigured) -+ if (!m_vdpauConfigured) - return VC_ERROR; - -- // configure vdpau output -- if (!ConfigOutputMethod(avctx, pFrame)) -- return VC_FLUSHED; -- -- outputSurface = outputSurfaces[surfaceNum]; -- -- CheckFeatures(); -- -- if (( (int)outRectVid.x1 != OutWidth ) || -- ( (int)outRectVid.y1 != OutHeight )) -- { -- outRectVid.x0 = 0; -- outRectVid.y0 = 0; -- outRectVid.x1 = OutWidth; -- outRectVid.y1 = OutHeight; -- } -- -- EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -- EINTERLACEMETHOD method = g_settings.m_currentVideoSettings.m_InterlaceMethod; -- if (method == VS_INTERLACEMETHOD_AUTO) -- method = AutoInterlaceMethod(); -- - if(pFrame) - { // we have a new frame from decoder - -@@ -1393,7 +892,10 @@ int CVDPAU::Decode(AVCodecContext *avctx, AVFrame *pFrame) - if(!render) // old style ffmpeg gave data on plane 0 - render = (vdpau_render_state*)pFrame->data[0]; - if(!render) -+ { -+ CLog::Log(LOGERROR, "CVDPAU::Decode: no valid frame"); - return VC_ERROR; -+ } - - // 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) - return VC_BUFFER; - } - -+ CSingleLock lock(m_videoSurfaceSec); - render->state |= FF_VDPAU_STATE_USED_FOR_RENDER; -+ lock.Leave(); - -- 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) -+ 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(); -+ } - -- 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) -+ { -+ if (m_vdpauOutput.m_dataPort.ReceiveInMessage(&msg)) - { -- if((method == VS_INTERLACEMETHOD_AUTO_ION -- || method == VS_INTERLACEMETHOD_VDPAU_BOB -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF -- || method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE )) -+ if (msg->signal == COutputDataProtocol::PICTURE) - { -- if((method == VS_INTERLACEMETHOD_AUTO_ION && vid_height > 576) -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF -- || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF -- || avctx->skip_frame == AVDISCARD_NONREF) -- m_mixerstep = 0; -- else -- m_mixerstep = 1; -- -- if(m_DVDVideoPics.front().iFlags & DVP_FLAG_TOP_FIELD_FIRST) -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; -- else -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; -+ if (m_presentPicture) -+ { -+ m_presentPicture->ReturnUnused(); -+ m_presentPicture = 0; -+ } -+ -+ m_presentPicture = *(CVdpauRenderPicture**)msg->data; -+ m_presentPicture->vdpau = this; -+ m_bufferStats.DecRender(); -+ m_bufferStats.Get(decoded, processed, render); -+ retval |= VC_PICTURE; -+ msg->Release(); -+ break; -+ } -+ msg->Release(); -+ } -+ else if (m_vdpauOutput.m_controlPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputControlProtocol::STATS) -+ { -+ m_bufferStats.Get(decoded, processed, render); - } - else - { -- m_mixerstep = 0; -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; -+ m_DisplayState = VDPAU_ERROR; -+ retval |= VC_ERROR; - } -+ msg->Release(); - } -- else -+ -+ if ((m_codecControl & DVP_FLAG_DRAIN)) - { -- m_mixerstep = 0; -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; -+ if (decoded + processed + render < 4) -+ { -+ retval |= VC_BUFFER; -+ } - } -- -- } -- else if(m_mixerstep == 1) -- { // no new frame given, output second field of old frame -- -- if(avctx->skip_frame == AVDISCARD_NONREF) -+ else - { -- ClearUsedForRender(&past[1]); -- m_DVDVideoPics.pop(); -- return VC_BUFFER; -+ if (decoded < 4 && (processed + render) < 3) -+ { -+ retval |= VC_BUFFER; -+ } - } - -- m_mixerstep = 2; -- if(m_mixerfield == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD) -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; -- else -- m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; -+ if (!retval && !m_inMsgEvent.WaitMSec(2000)) -+ break; - } -- else -+ uint64_t diff = CurrentHostCounter() - startTime; -+ if (retval & VC_PICTURE) - { -- CLog::Log(LOGERROR, "CVDPAU::Decode - invalid mixer state reached"); -- return VC_BUFFER; -+ m_bufferStats.SetParams(diff, m_codecControl); - } -+ if (diff*1000/CurrentHostFrequency() > 50) -+ CLog::Log(LOGDEBUG,"CVDPAU::Decode long wait: %d", (int)((diff*1000)/CurrentHostFrequency())); - -- VdpVideoSurface past_surfaces[2] = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE }; -- 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(m_mixerstep == 1) -- { // first field -- if (past[1]) -- { -- past_surfaces[1] = past[1]->surface; -- past_surfaces[0] = past[1]->surface; -- } -- futu_surfaces[0] = current->surface; -- } -- else -- { // second field -- if (past[1]) -- past_surfaces[1] = past[1]->surface; -- past_surfaces[0] = current->surface; -- futu_surfaces[0] = future->surface; -- } -- } -- -- vdp_st = vdp_presentation_queue_block_until_surface_idle(vdp_flip_queue,outputSurface,&time); -- -- VdpRect sourceRect = {0,0,vid_width, vid_height}; -- -- vdp_st = vdp_video_mixer_render(videoMixer, -- VDP_INVALID_HANDLE, -- 0, -- m_mixerfield, -- 2, -- past_surfaces, -- current->surface, -- 1, -- futu_surfaces, -- &sourceRect, -- outputSurface, -- &(outRectVid), -- &(outRectVid), -- 0, -- NULL); -- CheckStatus(vdp_st, __LINE__); - -- surfaceNum++; -- if (surfaceNum >= totalAvailableOutputSurfaces) surfaceNum = 0; -+ return retval; -+} - -- if(m_mixerfield == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME) -- { -- ClearUsedForRender(&past[0]); -- return VC_BUFFER | VC_PICTURE; -- } -- else -- { -- // in order to clip top and bottom lines when de-interlacing -- // we black those lines as a work around for not working -- // background colour using the mixer -- // pixel perfect is preferred over overscanning or zooming -+bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) -+{ -+ CSingleLock lock(m_DecoderSection); - -- VdpRect clipRect = outRectVid; -- clipRect.y1 = clipRect.y0 + 2; -- uint32_t *data[] = {m_BlackBar}; -- uint32_t pitches[] = {outRectVid.x1}; -- vdp_st = vdp_output_surface_put_bits_native(outputSurface, -- (void**)data, -- pitches, -- &clipRect); -- CheckStatus(vdp_st, __LINE__); -+ if (m_DisplayState != VDPAU_OPEN) -+ return false; - -- clipRect = outRectVid; -- clipRect.y0 = clipRect.y1 - 2; -- vdp_st = vdp_output_surface_put_bits_native(outputSurface, -- (void**)data, -- pitches, -- &clipRect); -- CheckStatus(vdp_st, __LINE__); -+ *picture = m_presentPicture->DVDPic; -+ picture->vdpau = m_presentPicture; - -- if(m_mixerstep == 1) -- return VC_PICTURE; -- else -- { -- ClearUsedForRender(&past[1]); -- return VC_BUFFER | VC_PICTURE; -- } -- } -+ return true; - } - --bool CVDPAU::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) -+void CDecoder::Reset() - { -- CSharedLock lock(m_DecoderSection); -- -- { CSharedLock dLock(m_DisplaySection); -- if (m_DisplayState != VDPAU_OPEN) -- return false; -- } -- -- *picture = m_DVDVideoPics.front(); -- // if this is the first field of an interlaced frame, we'll need -- // 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; -- picture->iHeight = OutHeight; -- picture->vdpau = this; -+ if (!m_vdpauConfigured) -+ return; - -- if(m_mixerstep) -+ 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) - { -- picture->dts = DVD_NOPTS_VALUE; -- picture->pts = DVD_NOPTS_VALUE; -+ CLog::Log(LOGERROR, "VDPAU::%s - flush returned error", __FUNCTION__); -+ m_DisplayState = VDPAU_ERROR; - } -+ else -+ m_bufferStats.Reset(); -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "VDPAU::%s - flush timed out", __FUNCTION__); -+ m_DisplayState = VDPAU_ERROR; - } -- return true; - } - --void CVDPAU::Reset() -+bool CDecoder::CanSkipDeint() - { -- // invalidate surfaces and picture queue when seeking -- ClearUsedForRender(&past[0]); -- ClearUsedForRender(&past[1]); -- ClearUsedForRender(¤t); -- ClearUsedForRender(&future); -- -- while (!m_DVDVideoPics.empty()) -- m_DVDVideoPics.pop(); -+ return m_bufferStats.CanSkipDeint(); - } - --void CVDPAU::Present() -+void CDecoder::ReturnRenderPicture(CVdpauRenderPicture *renderPic) - { -- //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); -- VdpStatus vdp_st; -- -- CSharedLock lock(m_DecoderSection); -- -- { CSharedLock dLock(m_DisplaySection); -- if (m_DisplayState != VDPAU_OPEN) -- return; -- } -- -- presentSurface = outputSurface; -- -- vdp_st = vdp_presentation_queue_display(vdp_flip_queue, -- presentSurface, -- 0, -- 0, -- 0); -- CheckStatus(vdp_st, __LINE__); -+ m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPIC, &renderPic, sizeof(renderPic)); - } - --bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line) -+bool CDecoder::CheckStatus(VdpStatus vdp_st, int line) - { - if (vdp_st != VDP_STATUS_OK) - { -- CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) at %s:%d\n", vdp_get_error_string(vdp_st), vdp_st, __FILE__, line); -- -- CExclusiveLock lock(m_DisplaySection); -+ CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) at %s:%d\n", m_vdpauConfig.vdpProcs.vdp_get_error_string(vdp_st), vdp_st, __FILE__, line); - - if(m_DisplayState == VDPAU_OPEN) - { -@@ -1671,4 +1081,2424 @@ bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line) - return false; - } - -+//----------------------------------------------------------------------------- -+// RenderPicture -+//----------------------------------------------------------------------------- -+ -+CVdpauRenderPicture* CVdpauRenderPicture::Acquire() -+{ -+ CSingleLock lock(*renderPicSection); -+ -+ if (refCount == 0) -+ vdpau->Acquire(); -+ -+ refCount++; -+ return this; -+} -+ -+long CVdpauRenderPicture::Release() -+{ -+ CSingleLock lock(*renderPicSection); -+ -+ refCount--; -+ if (refCount > 0) -+ return refCount; -+ -+ lock.Leave(); -+ vdpau->ReturnRenderPicture(this); -+ vdpau->ReleasePicReference(); -+ -+ return refCount; -+} -+ -+void CVdpauRenderPicture::ReturnUnused() -+{ -+ { CSingleLock lock(*renderPicSection); -+ if (refCount > 0) -+ return; -+ } -+ if (vdpau) -+ vdpau->ReturnRenderPicture(this); -+} -+//----------------------------------------------------------------------------- -+// Mixer -+//----------------------------------------------------------------------------- -+CMixer::CMixer(CEvent *inMsgEvent) : -+ CThread("Vdpau Mixer Thread"), -+ m_controlPort("ControlPort", inMsgEvent, &m_outMsgEvent), -+ m_dataPort("DataPort", inMsgEvent, &m_outMsgEvent) -+{ -+ m_inMsgEvent = inMsgEvent; -+} -+ -+CMixer::~CMixer() -+{ -+ Dispose(); -+} -+ -+void CMixer::Start() -+{ -+ Create(); -+} -+ -+void CMixer::Dispose() -+{ -+ m_bStop = true; -+ m_outMsgEvent.Set(); -+ StopThread(); -+ -+ m_controlPort.Purge(); -+ m_dataPort.Purge(); -+} -+ -+void CMixer::OnStartup() -+{ -+ CLog::Log(LOGNOTICE, "CMixer::OnStartup: Output Thread created"); -+} -+ -+void CMixer::OnExit() -+{ -+ CLog::Log(LOGNOTICE, "CMixer::OnExit: Output Thread terminated"); -+} -+ -+enum MIXER_STATES -+{ -+ M_TOP = 0, // 0 -+ M_TOP_ERROR, // 1 -+ M_TOP_UNCONFIGURED, // 2 -+ M_TOP_CONFIGURED, // 3 -+ M_TOP_CONFIGURED_WAIT1, // 4 -+ M_TOP_CONFIGURED_STEP1, // 5 -+ M_TOP_CONFIGURED_WAIT2, // 6 -+ M_TOP_CONFIGURED_STEP2, // 7 -+}; -+ -+int MIXER_parentStates[] = { -+ -1, -+ 0, //TOP_ERROR -+ 0, //TOP_UNCONFIGURED -+ 0, //TOP_CONFIGURED -+ 3, //TOP_CONFIGURED_WAIT1 -+ 3, //TOP_CONFIGURED_STEP1 -+ 3, //TOP_CONFIGURED_WAIT2 -+ 3, //TOP_CONFIGURED_STEP2 -+}; -+ -+void CMixer::StateMachine(int signal, Protocol *port, Message *msg) -+{ -+ for (int state = m_state; ; state = MIXER_parentStates[state]) -+ { -+ switch (state) -+ { -+ case M_TOP: // TOP -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::FLUSH: -+ Flush(); -+ msg->Reply(CMixerControlProtocol::ACC); -+ return; -+ default: -+ break; -+ } -+ } -+ { -+ std::string portName = port == NULL ? "timer" : port->portName; -+ CLog::Log(LOGWARNING, "CMixer::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state); -+ } -+ return; -+ -+ case M_TOP_ERROR: // TOP -+ break; -+ -+ case M_TOP_UNCONFIGURED: -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::INIT: -+ CVdpauConfig *data; -+ data = (CVdpauConfig*)msg->data; -+ if (data) -+ { -+ m_config = *data; -+ } -+ Init(); -+ if (!m_vdpError) -+ { -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ msg->Reply(CMixerControlProtocol::ACC); -+ } -+ else -+ { -+ msg->Reply(CMixerControlProtocol::ERROR); -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case M_TOP_CONFIGURED: -+ if (port == &m_dataPort) -+ { -+ switch (signal) -+ { -+ case CMixerDataProtocol::FRAME: -+ CVdpauDecodedPicture *frame; -+ frame = (CVdpauDecodedPicture*)msg->data; -+ if (frame) -+ { -+ m_decodedPics.push(*frame); -+ } -+ m_extTimeout = 0; -+ return; -+ case CMixerDataProtocol::BUFFER: -+ VdpOutputSurface *surf; -+ surf = (VdpOutputSurface*)msg->data; -+ if (surf) -+ { -+ m_outputSurfaces.push(*surf); -+ } -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case M_TOP_CONFIGURED_WAIT1: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::TIMEOUT: -+ if (!m_decodedPics.empty() && !m_outputSurfaces.empty()) -+ { -+ m_state = M_TOP_CONFIGURED_STEP1; -+ m_bStateMachineSelfTrigger = true; -+ } -+ else -+ { -+// if (m_extTimeout != 0) -+// { -+// SetPostProcFeatures(false); -+// CLog::Log(LOGWARNING,"CVDPAU::Mixer timeout - decoded: %d, outputSurf: %d", (int)m_decodedPics.size(), (int)m_outputSurfaces.size()); -+// } -+ m_extTimeout = 100; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case M_TOP_CONFIGURED_STEP1: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::TIMEOUT: -+ m_mixerInput.push_front(m_decodedPics.front()); -+ m_decodedPics.pop(); -+ if (m_mixerInput.size() < 2) -+ { -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ m_extTimeout = 0; -+ return; -+ } -+ InitCycle(); -+ ProcessPicture(); -+ if (m_vdpError) -+ { -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ m_extTimeout = 1000; -+ return; -+ } -+ if (m_processPicture.DVDPic.format != RENDER_FMT_VDPAU_420) -+ m_outputSurfaces.pop(); -+ m_config.stats->IncProcessed(); -+ m_config.stats->DecDecoded(); -+ m_dataPort.SendInMessage(CMixerDataProtocol::PICTURE,&m_processPicture,sizeof(m_processPicture)); -+ if (m_mixersteps > 1) -+ { -+ m_state = M_TOP_CONFIGURED_WAIT2; -+ m_extTimeout = 0; -+ } -+ else -+ { -+ FiniCycle(); -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ m_extTimeout = 0; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case M_TOP_CONFIGURED_WAIT2: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::TIMEOUT: -+ if (!m_outputSurfaces.empty()) -+ { -+ m_state = M_TOP_CONFIGURED_STEP2; -+ m_bStateMachineSelfTrigger = true; -+ } -+ else -+ { -+// if (m_extTimeout != 0) -+// { -+// SetPostProcFeatures(false); -+// CLog::Log(LOGNOTICE,"---mixer wait2 decoded: %d, outputSurf: %d", (int)m_decodedPics.size(), (int)m_outputSurfaces.size()); -+// } -+ m_extTimeout = 100; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case M_TOP_CONFIGURED_STEP2: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case CMixerControlProtocol::TIMEOUT: -+ m_processPicture.outputSurface = m_outputSurfaces.front(); -+ m_mixerstep = 1; -+ ProcessPicture(); -+ if (m_vdpError) -+ { -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ m_extTimeout = 1000; -+ return; -+ } -+ if (m_processPicture.DVDPic.format != RENDER_FMT_VDPAU_420) -+ m_outputSurfaces.pop(); -+ m_config.stats->IncProcessed(); -+ m_dataPort.SendInMessage(CMixerDataProtocol::PICTURE,&m_processPicture,sizeof(m_processPicture)); -+ FiniCycle(); -+ m_state = M_TOP_CONFIGURED_WAIT1; -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: // we are in no state, should not happen -+ CLog::Log(LOGERROR, "CMixer::%s - no valid state: %d", __FUNCTION__, m_state); -+ return; -+ } -+ } // for -+} -+ -+void CMixer::Process() -+{ -+ Message *msg; -+ Protocol *port; -+ bool gotMsg; -+ -+ m_state = M_TOP_UNCONFIGURED; -+ m_extTimeout = 1000; -+ m_bStateMachineSelfTrigger = false; -+ -+ while (!m_bStop) -+ { -+ gotMsg = false; -+ -+ if (m_bStateMachineSelfTrigger) -+ { -+ m_bStateMachineSelfTrigger = false; -+ // self trigger state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ // check control port -+ else if (m_controlPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_controlPort; -+ } -+ // check data port -+ else if (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_dataPort; -+ } -+ -+ if (gotMsg) -+ { -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ -+ // wait for message -+ else if (m_outMsgEvent.WaitMSec(m_extTimeout)) -+ { -+ continue; -+ } -+ // time out -+ else -+ { -+ msg = m_controlPort.GetMessage(); -+ msg->signal = CMixerControlProtocol::TIMEOUT; -+ port = 0; -+ // signal timeout to state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ } -+ } -+ Uninit(); -+} -+ -+void CMixer::CreateVdpauMixer() -+{ -+ CLog::Log(LOGNOTICE, " (VDPAU) Creating the video mixer"); -+ -+ InitCSCMatrix(m_config.vidWidth); -+ -+ VdpVideoMixerParameter parameters[] = { -+ VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, -+ VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, -+ VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE}; -+ -+ void const * parameter_values[] = { -+ &m_config.surfaceWidth, -+ &m_config.surfaceHeight, -+ &m_config.vdpChromaType}; -+ -+ VdpStatus vdp_st = VDP_STATUS_ERROR; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_create(m_config.vdpDevice, -+ m_config.featureCount, -+ m_config.vdpFeatures, -+ ARSIZE(parameters), -+ parameters, -+ parameter_values, -+ &m_videoMixer); -+ CheckStatus(vdp_st, __LINE__); -+ -+ // create 3 pitches of black lines needed for clipping top -+ // and bottom lines when de-interlacing -+ m_BlackBar = new uint32_t[3*m_config.outWidth]; -+ memset(m_BlackBar, 0, 3*m_config.outWidth*sizeof(uint32_t)); -+ -+} -+ -+void CMixer::InitCSCMatrix(int Width) -+{ -+ VdpStatus vdp_st; -+ m_Procamp.struct_version = VDP_PROCAMP_VERSION; -+ m_Procamp.brightness = 0.0; -+ 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() -+{ -+ if (m_Upscale != m_config.upscale) -+ { -+ SetHWUpscaling(); -+ m_Upscale = m_config.upscale; -+ } -+ if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness || -+ m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) -+ { -+ SetColor(); -+ m_Brightness = g_settings.m_currentVideoSettings.m_Brightness; -+ m_Contrast = g_settings.m_currentVideoSettings.m_Contrast; -+ } -+ if (m_NoiseReduction != g_settings.m_currentVideoSettings.m_NoiseReduction) -+ { -+ m_NoiseReduction = g_settings.m_currentVideoSettings.m_NoiseReduction; -+ SetNoiseReduction(); -+ } -+ if (m_Sharpness != g_settings.m_currentVideoSettings.m_Sharpness) -+ { -+ m_Sharpness = g_settings.m_currentVideoSettings.m_Sharpness; -+ SetSharpness(); -+ } -+ if (m_DeintMode != g_settings.m_currentVideoSettings.m_DeinterlaceMode || -+ m_Deint != g_settings.m_currentVideoSettings.m_InterlaceMethod) -+ { -+ m_DeintMode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -+ m_Deint = g_settings.m_currentVideoSettings.m_InterlaceMethod; -+ SetDeinterlacing(); -+ } -+} -+ -+void CMixer::SetPostProcFeatures(bool postProcEnabled) -+{ -+ if (m_PostProc != postProcEnabled) -+ { -+ if (postProcEnabled) -+ { -+ SetNoiseReduction(); -+ SetSharpness(); -+ SetDeinterlacing(); -+ SetHWUpscaling(); -+ } -+ else -+ PostProcOff(); -+ m_PostProc = postProcEnabled; -+ } -+} -+ -+void CMixer::PostProcOff() -+{ -+ VdpStatus vdp_st; -+ -+ if (m_videoMixer == VDP_INVALID_HANDLE) -+ return; -+ -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, -+ VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, -+ VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE}; -+ -+ VdpBool enabled[]={0,0,0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION}; -+ -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_SHARPNESS)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_SHARPNESS}; -+ -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ 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; -+ -+ if (m_Brightness != g_settings.m_currentVideoSettings.m_Brightness) -+ m_Procamp.brightness = (float)((g_settings.m_currentVideoSettings.m_Brightness)-50) / 100; -+ if (m_Contrast != g_settings.m_currentVideoSettings.m_Contrast) -+ 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); -+ -+ 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); -+ } -+ CheckStatus(vdp_st, __LINE__); -+} -+ -+void CMixer::SetNoiseReduction() -+{ -+ if(!m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION)) -+ return; -+ -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION }; -+ VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL }; -+ VdpStatus vdp_st; -+ -+ if (!g_settings.m_currentVideoSettings.m_NoiseReduction) -+ { -+ VdpBool enabled[]= {0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ return; -+ } -+ VdpBool enabled[]={1}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ void* nr[] = { &g_settings.m_currentVideoSettings.m_NoiseReduction }; -+ CLog::Log(LOGNOTICE,"Setting Noise Reduction to %f",g_settings.m_currentVideoSettings.m_NoiseReduction); -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, nr); -+ CheckStatus(vdp_st, __LINE__); -+} -+ -+void CMixer::SetSharpness() -+{ -+ if(!m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_SHARPNESS)) -+ return; -+ -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_SHARPNESS }; -+ VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL }; -+ VdpStatus vdp_st; -+ -+ if (!g_settings.m_currentVideoSettings.m_Sharpness) -+ { -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ return; -+ } -+ VdpBool enabled[]={1}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ void* sh[] = { &g_settings.m_currentVideoSettings.m_Sharpness }; -+ CLog::Log(LOGNOTICE,"Setting Sharpness to %f",g_settings.m_currentVideoSettings.m_Sharpness); -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attributes), attributes, sh); -+ CheckStatus(vdp_st, __LINE__); -+} -+ -+EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) -+{ -+ EINTERLACEMETHOD method = g_settings.m_currentVideoSettings.m_InterlaceMethod; -+ 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 (deint != -1) -+ { -+ if (m_config.vdpau->Supports(EINTERLACEMETHOD(deint))) -+ { -+ method = EINTERLACEMETHOD(deint); -+ if (log) -+ CLog::Log(LOGNOTICE, "CVDPAU::GetDeinterlacingMethod: set de-interlacing to %d", deint); -+ } -+ else -+ { -+ if (log) -+ CLog::Log(LOGWARNING, "CVDPAU::GetDeinterlacingMethod: method for de-interlacing (advanced settings) not supported"); -+ } -+ } -+ } -+ return method; -+} -+ -+void CMixer::SetDeinterlacing() -+{ -+ VdpStatus vdp_st; -+ -+ if (m_videoMixer == VDP_INVALID_HANDLE) -+ return; -+ -+ EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -+ EINTERLACEMETHOD method = GetDeinterlacingMethod(true); -+ -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, -+ VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, -+ VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE }; -+ -+ if (mode == VS_DEINTERLACEMODE_OFF) -+ { -+ VdpBool enabled[] = {0,0,0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ } -+ else -+ { -+ if (method == VS_INTERLACEMETHOD_AUTO) -+ { -+ VdpBool enabled[] = {1,0,0}; -+ if (g_advancedSettings.m_videoVDPAUtelecine) -+ enabled[2] = 1; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ } -+ else if (method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF) -+ { -+ VdpBool enabled[] = {1,0,0}; -+ if (g_advancedSettings.m_videoVDPAUtelecine) -+ enabled[2] = 1; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ } -+ else if (method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF) -+ { -+ VdpBool enabled[] = {1,1,0}; -+ if (g_advancedSettings.m_videoVDPAUtelecine) -+ enabled[2] = 1; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ } -+ else -+ { -+ VdpBool enabled[]={0,0,0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ } -+ } -+ CheckStatus(vdp_st, __LINE__); -+ -+ SetDeintSkipChroma(); -+ -+ m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+} -+ -+void CMixer::SetDeintSkipChroma() -+{ -+ VdpVideoMixerAttribute attribute[] = { VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE}; -+ VdpStatus vdp_st; -+ -+ uint8_t val; -+ if (g_advancedSettings.m_videoVDPAUdeintSkipChromaHD && m_config.outHeight >= 720) -+ val = 1; -+ else -+ val = 0; -+ -+ void const *values[]={&val}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_attribute_values(m_videoMixer, ARSIZE(attribute), attribute, values); -+ -+ CheckStatus(vdp_st, __LINE__); -+} -+ -+void CMixer::SetHWUpscaling() -+{ -+#ifdef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 -+ -+ VdpStatus vdp_st; -+ VdpBool enabled[]={1}; -+ switch (m_config.upscale) -+ { -+ case 9: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 8: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 7: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 6: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 5: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 4: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 3: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 2: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ case 1: -+ if (m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 }; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ break; -+ } -+ default: -+ DisableHQScaling(); -+ return; -+ } -+ CheckStatus(vdp_st, __LINE__); -+#endif -+} -+ -+void CMixer::DisableHQScaling() -+{ -+ VdpStatus vdp_st; -+ -+ if (m_videoMixer == VDP_INVALID_HANDLE) -+ return; -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L2 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L3 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L4 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L5 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L6 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L7 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L8 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ -+ if(m_config.vdpau->Supports(VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9)) -+ { -+ VdpVideoMixerFeature feature[] = { VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L9 }; -+ VdpBool enabled[]={0}; -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_set_feature_enables(m_videoMixer, ARSIZE(feature), feature, enabled); -+ CheckStatus(vdp_st, __LINE__); -+ } -+} -+ -+ -+void CMixer::Init() -+{ -+ m_Brightness = 0.0; -+ m_Contrast = 0.0; -+ m_NoiseReduction = 0.0; -+ m_Sharpness = 0.0; -+ m_DeintMode = 0; -+ m_Deint = 0; -+ m_PostProc = false; -+ m_vdpError = false; -+ -+ m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; -+ m_config.useInteropYuv = g_guiSettings.GetBool("videoplayer.usevdpauinteropyuv"); -+ -+ CreateVdpauMixer(); -+} -+ -+void CMixer::Uninit() -+{ -+ Flush(); -+ while (!m_outputSurfaces.empty()) -+ { -+ m_outputSurfaces.pop(); -+ } -+ m_config.vdpProcs.vdp_video_mixer_destroy(m_videoMixer); -+ -+ delete [] m_BlackBar; -+} -+ -+void CMixer::Flush() -+{ -+ while (!m_mixerInput.empty()) -+ { -+ CVdpauDecodedPicture pic = m_mixerInput.back(); -+ m_mixerInput.pop_back(); -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ while (!m_decodedPics.empty()) -+ { -+ CVdpauDecodedPicture pic = m_decodedPics.front(); -+ m_decodedPics.pop(); -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ Message *msg; -+ while (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ if (msg->signal == CMixerDataProtocol::FRAME) -+ { -+ CVdpauDecodedPicture pic = *(CVdpauDecodedPicture*)msg->data; -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ else if (msg->signal == CMixerDataProtocol::BUFFER) -+ { -+ VdpOutputSurface *surf; -+ surf = (VdpOutputSurface*)msg->data; -+ m_outputSurfaces.push(*surf); -+ } -+ msg->Release(); -+ } -+} -+ -+void CMixer::InitCycle() -+{ -+ CheckFeatures(); -+ uint64_t latency; -+ int flags; -+ m_config.stats->GetParams(latency, flags); -+ latency = (latency*1000)/CurrentHostFrequency(); -+ if (flags & DVP_FLAG_NO_POSTPROC) -+ SetPostProcFeatures(false); -+ else -+ SetPostProcFeatures(true); -+ -+ m_config.stats->SetCanSkipDeint(false); -+ -+ EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -+ EINTERLACEMETHOD method = GetDeinterlacingMethod(); -+ bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; -+ -+ if (mode == VS_DEINTERLACEMODE_FORCE || -+ (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) -+ { -+ if((method == VS_INTERLACEMETHOD_AUTO && interlaced) -+ || method == VS_INTERLACEMETHOD_VDPAU_BOB -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF -+ || method == VS_INTERLACEMETHOD_VDPAU_INVERSE_TELECINE ) -+ { -+ if(method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_HALF -+ || method == VS_INTERLACEMETHOD_VDPAU_TEMPORAL_SPATIAL_HALF -+ || !g_graphicsContext.IsFullScreenVideo()) -+ m_mixersteps = 1; -+ else -+ { -+ m_mixersteps = 2; -+ m_config.stats->SetCanSkipDeint(true); -+ } -+ -+ if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) -+ { -+ m_mixersteps = 1; -+ } -+ -+ if(m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_TOP_FIELD_FIRST) -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; -+ else -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; -+ -+ 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); -+ m_config.useInteropYuv = false; -+ } -+ else if (method == VS_INTERLACEMETHOD_RENDER_BOB && m_config.useInteropYuv) -+ { -+ m_mixersteps = 1; -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; -+ m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "CMixer::%s - interlace method not supported", __FUNCTION__); -+ 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); -+ } -+ } -+ else -+ { -+ m_mixersteps = 1; -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; -+ -+ if (m_config.useInteropYuv) -+ m_mixerInput[1].DVDPic.format = RENDER_FMT_VDPAU_420; -+ else -+ { -+ 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); -+ } -+ } -+ m_mixerstep = 0; -+ -+ if (m_mixerInput[1].DVDPic.format == RENDER_FMT_VDPAU) -+ { -+ m_processPicture.outputSurface = m_outputSurfaces.front(); -+ m_mixerInput[1].DVDPic.iWidth = m_config.outWidth; -+ m_mixerInput[1].DVDPic.iHeight = m_config.outHeight; -+ } -+ else -+ { -+ m_mixerInput[1].DVDPic.iWidth = m_config.vidWidth; -+ m_mixerInput[1].DVDPic.iHeight = m_config.vidHeight; -+ } -+ -+ m_processPicture.DVDPic = m_mixerInput[1].DVDPic; -+ m_processPicture.render = m_mixerInput[1].render; -+} -+ -+void CMixer::FiniCycle() -+{ -+ while (m_mixerInput.size() > 3) -+ { -+ CVdpauDecodedPicture &tmp = m_mixerInput.back(); -+ if (tmp.render && m_processPicture.DVDPic.format != RENDER_FMT_VDPAU_420) -+ { -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ tmp.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ m_mixerInput.pop_back(); -+// m_config.stats->DecDecoded(); -+ } -+} -+ -+void CMixer::ProcessPicture() -+{ -+ if (m_processPicture.DVDPic.format == RENDER_FMT_VDPAU_420) -+ return; -+ -+ VdpStatus vdp_st; -+ -+ if (m_mixerstep == 1) -+ { -+ if(m_mixerfield == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD) -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; -+ else -+ m_mixerfield = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; -+ } -+ -+ VdpVideoSurface past_surfaces[4] = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE, VDP_INVALID_HANDLE, VDP_INVALID_HANDLE }; -+ VdpVideoSurface futu_surfaces[2] = { VDP_INVALID_HANDLE, VDP_INVALID_HANDLE }; -+ uint32_t pastCount = 4; -+ uint32_t futuCount = 2; -+ -+ if(m_mixerfield == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME) -+ { -+ // use only 2 past 1 future for progressive/weave -+ // (only used for postproc anyway eg noise reduction) -+ if (m_mixerInput.size() > 3) -+ past_surfaces[1] = m_mixerInput[3].render->surface; -+ if (m_mixerInput.size() > 2) -+ past_surfaces[0] = m_mixerInput[2].render->surface; -+ futu_surfaces[0] = m_mixerInput[0].render->surface; -+ pastCount = 2; -+ futuCount = 1; -+ } -+ else -+ { -+ if(m_mixerstep == 0) -+ { // first field -+ if (m_mixerInput.size() > 3) -+ { -+ past_surfaces[3] = m_mixerInput[3].render->surface; -+ past_surfaces[2] = m_mixerInput[3].render->surface; -+ } -+ if (m_mixerInput.size() > 2) -+ { -+ past_surfaces[1] = m_mixerInput[2].render->surface; -+ past_surfaces[0] = m_mixerInput[2].render->surface; -+ } -+ futu_surfaces[0] = m_mixerInput[1].render->surface; -+ futu_surfaces[1] = m_mixerInput[0].render->surface;; -+ } -+ else -+ { // second field -+ if (m_mixerInput.size() > 3) -+ { -+ past_surfaces[3] = m_mixerInput[3].render->surface; -+ } -+ if (m_mixerInput.size() > 2) -+ { -+ past_surfaces[2] = m_mixerInput[2].render->surface; -+ past_surfaces[1] = m_mixerInput[2].render->surface; -+ } -+ past_surfaces[0] = m_mixerInput[1].render->surface; -+ futu_surfaces[0] = m_mixerInput[1].render->surface; -+ futu_surfaces[1] = m_mixerInput[1].render->surface; -+ -+ m_processPicture.DVDPic.pts = DVD_NOPTS_VALUE; -+ m_processPicture.DVDPic.dts = DVD_NOPTS_VALUE; -+ } -+ m_processPicture.DVDPic.iRepeatPicture = 0.0; -+ } // interlaced -+ -+ VdpRect sourceRect; -+ sourceRect.x0 = 0; -+ sourceRect.y0 = 0; -+ sourceRect.x1 = m_config.vidWidth; -+ sourceRect.y1 = m_config.vidHeight; -+ -+ VdpRect destRect; -+ destRect.x0 = 0; -+ destRect.y0 = 0; -+ destRect.x1 = m_config.outWidth; -+ destRect.y1 = m_config.outHeight; -+ -+ // start vdpau video mixer -+ vdp_st = m_config.vdpProcs.vdp_video_mixer_render(m_videoMixer, -+ VDP_INVALID_HANDLE, -+ 0, -+ m_mixerfield, -+ pastCount, -+ past_surfaces, -+ m_mixerInput[1].render->surface, -+ futuCount, -+ futu_surfaces, -+ &sourceRect, -+ m_processPicture.outputSurface, -+ &destRect, -+ &destRect, -+ 0, -+ NULL); -+ CheckStatus(vdp_st, __LINE__); -+ -+ if (m_mixerfield != VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME) -+ { -+ // in order to clip top and bottom lines when de-interlacing -+ // we black those lines as a work around for not working -+ // background colour using the mixer -+ // pixel perfect is preferred over overscanning or zooming -+ -+ VdpRect clipRect = destRect; -+ clipRect.y1 = clipRect.y0 + 2; -+ uint32_t *data[] = {m_BlackBar}; -+ uint32_t pitches[] = {destRect.x1}; -+ vdp_st = m_config.vdpProcs.vdp_output_surface_put_bits_native(m_processPicture.outputSurface, -+ (void**)data, -+ pitches, -+ &clipRect); -+ CheckStatus(vdp_st, __LINE__); -+ -+ clipRect = destRect; -+ clipRect.y0 = clipRect.y1 - 2; -+ vdp_st = m_config.vdpProcs.vdp_output_surface_put_bits_native(m_processPicture.outputSurface, -+ (void**)data, -+ pitches, -+ &clipRect); -+ CheckStatus(vdp_st, __LINE__); -+ } -+} -+ -+ -+bool CMixer::CheckStatus(VdpStatus vdp_st, int line) -+{ -+ if (vdp_st != VDP_STATUS_OK) -+ { -+ CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) at %s:%d\n", m_config.vdpProcs.vdp_get_error_string(vdp_st), vdp_st, __FILE__, line); -+ m_vdpError = true; -+ return true; -+ } -+ return false; -+} -+ -+//----------------------------------------------------------------------------- -+// Output -+//----------------------------------------------------------------------------- -+COutput::COutput(CEvent *inMsgEvent) : -+ CThread("Vdpau Output Thread"), -+ m_controlPort("OutputControlPort", inMsgEvent, &m_outMsgEvent), -+ m_dataPort("OutputDataPort", inMsgEvent, &m_outMsgEvent), -+ m_mixer(&m_outMsgEvent) -+{ -+ m_inMsgEvent = inMsgEvent; -+ -+ CVdpauRenderPicture pic; -+ pic.renderPicSection = &m_bufferPool.renderPicSec; -+ pic.refCount = 0; -+ for (unsigned int i = 0; i < NUM_RENDER_PICS; i++) -+ { -+ m_bufferPool.allRenderPics.push_back(pic); -+ } -+ for (unsigned int i = 0; i < m_bufferPool.allRenderPics.size(); ++i) -+ { -+ m_bufferPool.freeRenderPics.push_back(&m_bufferPool.allRenderPics[i]); -+ } -+} -+ -+void COutput::Start() -+{ -+ Create(); -+} -+ -+COutput::~COutput() -+{ -+ Dispose(); -+ -+ m_bufferPool.freeRenderPics.clear(); -+ m_bufferPool.usedRenderPics.clear(); -+ m_bufferPool.allRenderPics.clear(); -+} -+ -+void COutput::Dispose() -+{ -+ CSingleLock lock(g_graphicsContext); -+ m_bStop = true; -+ m_outMsgEvent.Set(); -+ StopThread(); -+ m_controlPort.Purge(); -+ m_dataPort.Purge(); -+} -+ -+void COutput::OnStartup() -+{ -+ CLog::Log(LOGNOTICE, "COutput::OnStartup: Output Thread created"); -+} -+ -+void COutput::OnExit() -+{ -+ CLog::Log(LOGNOTICE, "COutput::OnExit: Output Thread terminated"); -+} -+ -+enum OUTPUT_STATES -+{ -+ O_TOP = 0, // 0 -+ O_TOP_ERROR, // 1 -+ O_TOP_UNCONFIGURED, // 2 -+ O_TOP_CONFIGURED, // 3 -+ O_TOP_CONFIGURED_IDLE, // 4 -+ O_TOP_CONFIGURED_WORK, // 5 -+}; -+ -+int VDPAU_OUTPUT_parentStates[] = { -+ -1, -+ 0, //TOP_ERROR -+ 0, //TOP_UNCONFIGURED -+ 0, //TOP_CONFIGURED -+ 3, //TOP_CONFIGURED_IDLE -+ 3, //TOP_CONFIGURED_WORK -+}; -+ -+void COutput::StateMachine(int signal, Protocol *port, Message *msg) -+{ -+ for (int state = m_state; ; state = VDPAU_OUTPUT_parentStates[state]) -+ { -+ switch (state) -+ { -+ case O_TOP: // TOP -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::FLUSH: -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ case COutputControlProtocol::PRECLEANUP: -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ default: -+ break; -+ } -+ } -+ else if (port == &m_dataPort) -+ { -+ switch (signal) -+ { -+ case COutputDataProtocol::RETURNPIC: -+ CVdpauRenderPicture *pic; -+ pic = *((CVdpauRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ return; -+ default: -+ break; -+ } -+ } -+ { -+ std::string portName = port == NULL ? "timer" : port->portName; -+ CLog::Log(LOGWARNING, "COutput::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state); -+ } -+ return; -+ -+ case O_TOP_ERROR: -+ break; -+ -+ case O_TOP_UNCONFIGURED: -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::INIT: -+ CVdpauConfig *data; -+ data = (CVdpauConfig*)msg->data; -+ if (data) -+ { -+ m_config = *data; -+ } -+ Init(); -+ Message *reply; -+ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::INIT, -+ &reply, 1000, &m_config, sizeof(m_config))) -+ { -+ if (reply->signal != CMixerControlProtocol::ACC) -+ m_vdpError = true; -+ reply->Release(); -+ } -+ -+ // set initial number of -+ m_bufferPool.numOutputSurfaces = 4; -+ EnsureBufferPool(); -+ if (!m_vdpError) -+ { -+ m_state = O_TOP_CONFIGURED_IDLE; -+ msg->Reply(COutputControlProtocol::ACC); -+ } -+ else -+ { -+ m_state = O_TOP_ERROR; -+ msg->Reply(COutputControlProtocol::ERROR); -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED: -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::FLUSH: -+ Flush(); -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ case COutputControlProtocol::PRECLEANUP: -+ Flush(); -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ default: -+ break; -+ } -+ } -+ else if (port == &m_dataPort) -+ { -+ switch (signal) -+ { -+ case COutputDataProtocol::NEWFRAME: -+ CVdpauDecodedPicture *frame; -+ frame = (CVdpauDecodedPicture*)msg->data; -+ if (frame) -+ { -+ m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::FRAME, -+ frame,sizeof(CVdpauDecodedPicture)); -+ } -+ return; -+ case COutputDataProtocol::RETURNPIC: -+ CVdpauRenderPicture *pic; -+ pic = *((CVdpauRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ m_controlPort.SendInMessage(COutputControlProtocol::STATS); -+ m_state = O_TOP_CONFIGURED_WORK; -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ else if (port == &m_mixer.m_dataPort) -+ { -+ switch (signal) -+ { -+ case CMixerDataProtocol::PICTURE: -+ CVdpauProcessedPicture *pic; -+ pic = (CVdpauProcessedPicture*)msg->data; -+ m_bufferPool.processedPics.push(*pic); -+ m_state = O_TOP_CONFIGURED_WORK; -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_IDLE: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+// uint16_t decoded, processed, render; -+// m_config.stats->Get(decoded, processed, render); -+// CLog::Log(LOGDEBUG, "CVDPAU::COutput - timeout idle: decoded: %d, proc: %d, render: %d", decoded, processed, render); -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_WORK: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ if (HasWork()) -+ { -+ CVdpauRenderPicture *pic; -+ pic = ProcessMixerPicture(); -+ if (pic) -+ { -+ m_config.stats->DecProcessed(); -+ m_config.stats->IncRender(); -+ m_dataPort.SendInMessage(COutputDataProtocol::PICTURE, &pic, sizeof(pic)); -+ } -+ m_extTimeout = 1; -+ } -+ else -+ { -+ m_state = O_TOP_CONFIGURED_IDLE; -+ m_extTimeout = 100; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: // we are in no state, should not happen -+ CLog::Log(LOGERROR, "COutput::%s - no valid state: %d", __FUNCTION__, m_state); -+ return; -+ } -+ } // for -+} -+ -+void COutput::Process() -+{ -+ Message *msg; -+ Protocol *port; -+ bool gotMsg; -+ -+ m_state = O_TOP_UNCONFIGURED; -+ m_extTimeout = 1000; -+ m_bStateMachineSelfTrigger = false; -+ -+ while (!m_bStop) -+ { -+ gotMsg = false; -+ -+ if (m_bStateMachineSelfTrigger) -+ { -+ m_bStateMachineSelfTrigger = false; -+ // self trigger state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ // check control port -+ else if (m_controlPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_controlPort; -+ } -+ // check data port -+ else if (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_dataPort; -+ } -+ // check mixer data port -+ else if (m_mixer.m_dataPort.ReceiveInMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_mixer.m_dataPort; -+ } -+ if (gotMsg) -+ { -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ -+ // wait for message -+ else if (m_outMsgEvent.WaitMSec(m_extTimeout)) -+ { -+ continue; -+ } -+ // time out -+ else -+ { -+ msg = m_controlPort.GetMessage(); -+ msg->signal = COutputControlProtocol::TIMEOUT; -+ port = 0; -+ // signal timeout to state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ } -+ } -+ Flush(); -+ Uninit(); -+} -+ -+bool COutput::Init() -+{ -+ if (!CreateGlxContext()) -+ return false; -+ -+ if (!GLInit()) -+ return false; -+ -+ m_mixer.Start(); -+ m_vdpError = false; -+ -+ return true; -+} -+ -+bool COutput::Uninit() -+{ -+ m_mixer.Dispose(); -+ GLUnmapSurfaces(); -+ GLUnbindPixmaps(); -+ ReleaseBufferPool(); -+ DestroyGlxContext(); -+ return true; -+} -+ -+void COutput::Flush() -+{ -+ Message *reply; -+ if (m_mixer.m_controlPort.SendOutMessageSync(CMixerControlProtocol::FLUSH, -+ &reply, -+ 2000)) -+ { -+ reply->Release(); -+ } -+ else -+ CLog::Log(LOGERROR, "Coutput::%s - failed to flush mixer", __FUNCTION__); -+ -+ Message *msg; -+ while (m_mixer.m_dataPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == CMixerDataProtocol::PICTURE) -+ { -+ CVdpauProcessedPicture pic = *(CVdpauProcessedPicture*)msg->data; -+ if (pic.DVDPic.format == RENDER_FMT_VDPAU_420) -+ { -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ } -+ msg->Release(); -+ } -+ -+ while (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ if (msg->signal == COutputDataProtocol::NEWFRAME) -+ { -+ CVdpauDecodedPicture pic = *(CVdpauDecodedPicture*)msg->data; -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ else if (msg->signal == COutputDataProtocol::RETURNPIC) -+ { -+ CVdpauRenderPicture *pic; -+ pic = *((CVdpauRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ } -+ msg->Release(); -+ } -+ -+ while (m_dataPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputDataProtocol::PICTURE) -+ { -+ CVdpauRenderPicture *pic; -+ pic = *((CVdpauRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ } -+ } -+ -+ // reset used render flag which was cleared on mixer flush -+ std::deque::iterator it; -+ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) -+ { -+ if ((*it)->DVDPic.format == RENDER_FMT_VDPAU_420) -+ { -+ std::map::iterator it2; -+ it2 = m_bufferPool.glVideoSurfaceMap.find((*it)->sourceIdx); -+ if (it2 == m_bufferPool.glVideoSurfaceMap.end()) -+ { -+ CLog::Log(LOGDEBUG, "COutput::Flush - gl surface not found"); -+ continue; -+ } -+ vdpau_render_state *render = it2->second.sourceVuv; -+ if (render) -+ render->state |= FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ } -+} -+ -+bool COutput::HasWork() -+{ -+ if (m_config.usePixmaps) -+ { -+ if (!m_bufferPool.processedPics.empty() && FindFreePixmap() >= 0) -+ return true; -+ if (!m_bufferPool.notVisiblePixmaps.empty() && !m_bufferPool.freeRenderPics.empty()) -+ return true; -+ return false; -+ } -+ else -+ { -+ if (!m_bufferPool.processedPics.empty() && !m_bufferPool.freeRenderPics.empty()) -+ return true; -+ return false; -+ } -+} -+ -+CVdpauRenderPicture* COutput::ProcessMixerPicture() -+{ -+ CVdpauRenderPicture *retPic = 0; -+ -+ if (m_config.usePixmaps) -+ { -+ if (!m_bufferPool.processedPics.empty() && FindFreePixmap() >= 0) -+ { -+ unsigned int i = FindFreePixmap(); -+ VdpauBufferPool::Pixmaps *pixmap = &m_bufferPool.pixmaps[i]; -+ pixmap->used = true; -+ CVdpauProcessedPicture pic = m_bufferPool.processedPics.front(); -+ m_bufferPool.processedPics.pop(); -+ pixmap->surface = pic.outputSurface; -+ pixmap->DVDPic = pic.DVDPic; -+ pixmap->id = i; -+ m_bufferPool.notVisiblePixmaps.push_back(pixmap); -+ VdpStatus vdp_st; -+ m_config.vdpProcs.vdp_presentation_queue_display(pixmap->vdp_flip_queue, -+ pixmap->surface,0,0,0); -+ } -+ if (!m_bufferPool.notVisiblePixmaps.empty() && !m_bufferPool.freeRenderPics.empty()) -+ { -+ VdpStatus vdp_st; -+ VdpTime time; -+ VdpPresentationQueueStatus status; -+ VdpauBufferPool::Pixmaps *pixmap = m_bufferPool.notVisiblePixmaps.front(); -+ vdp_st = m_config.vdpProcs.vdp_presentation_queue_query_surface_status( -+ pixmap->vdp_flip_queue, pixmap->surface, &status, &time); -+ -+ if (vdp_st == VDP_STATUS_OK && status == VDP_PRESENTATION_QUEUE_STATUS_VISIBLE) -+ { -+ retPic = m_bufferPool.freeRenderPics.front(); -+ m_bufferPool.freeRenderPics.pop_front(); -+ m_bufferPool.usedRenderPics.push_back(retPic); -+ retPic->sourceIdx = pixmap->id; -+ retPic->DVDPic = pixmap->DVDPic; -+ retPic->valid = true; -+ retPic->texture[0] = pixmap->texture; -+ retPic->crop = CRect(0,0,0,0); -+ m_bufferPool.notVisiblePixmaps.pop_front(); -+ m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, &pixmap->surface, sizeof(pixmap->surface)); -+ } -+ } -+ } // pixmap -+ else if (!m_bufferPool.processedPics.empty() && !m_bufferPool.freeRenderPics.empty()) -+ { -+ retPic = m_bufferPool.freeRenderPics.front(); -+ m_bufferPool.freeRenderPics.pop_front(); -+ m_bufferPool.usedRenderPics.push_back(retPic); -+ CVdpauProcessedPicture procPic = m_bufferPool.processedPics.front(); -+ m_bufferPool.processedPics.pop(); -+ -+ retPic->DVDPic = procPic.DVDPic; -+ retPic->valid = true; -+ if (retPic->DVDPic.format == RENDER_FMT_VDPAU) -+ { -+ m_config.useInteropYuv = false; -+ m_bufferPool.numOutputSurfaces = NUM_RENDER_PICS; -+ EnsureBufferPool(); -+ GLMapSurfaces(); -+ retPic->sourceIdx = procPic.outputSurface; -+ retPic->texture[0] = m_bufferPool.glOutputSurfaceMap[procPic.outputSurface].texture[0]; -+ retPic->crop = CRect(0,0,0,0); -+ } -+ else -+ { -+ m_config.useInteropYuv = true; -+ GLMapSurfaces(); -+ retPic->sourceIdx = procPic.render->surface; -+ for (unsigned int i=0; i<4; ++i) -+ retPic->texture[i] = m_bufferPool.glVideoSurfaceMap[procPic.render->surface].texture[i]; -+ retPic->texWidth = m_config.surfaceWidth; -+ retPic->texHeight = m_config.surfaceHeight; -+ retPic->crop.x1 = 0; -+ retPic->crop.y1 = 0; -+ retPic->crop.x2 = m_config.surfaceWidth - m_config.vidWidth; -+ retPic->crop.y2 = m_config.surfaceHeight - m_config.vidHeight; -+ } -+ } -+ return retPic; -+} -+ -+void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) -+{ -+ std::deque::iterator it; -+ it = std::find(m_bufferPool.usedRenderPics.begin(), m_bufferPool.usedRenderPics.end(), pic); -+ if (it == m_bufferPool.usedRenderPics.end()) -+ { -+ CLog::Log(LOGWARNING, "COutput::ProcessReturnPicture - pic not found"); -+ return; -+ } -+ m_bufferPool.usedRenderPics.erase(it); -+ m_bufferPool.freeRenderPics.push_back(pic); -+ if (!pic->valid) -+ { -+ CLog::Log(LOGDEBUG, "COutput::%s - return of invalid render pic", __FUNCTION__); -+ return; -+ } -+ -+ if (m_config.usePixmaps) -+ { -+ m_bufferPool.pixmaps[pic->sourceIdx].used = false; -+ return; -+ } -+ else if (pic->DVDPic.format == RENDER_FMT_VDPAU_420) -+ { -+ std::map::iterator it; -+ it = m_bufferPool.glVideoSurfaceMap.find(pic->sourceIdx); -+ if (it == m_bufferPool.glVideoSurfaceMap.end()) -+ { -+ CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); -+ return; -+ } -+ vdpau_render_state *render = it->second.sourceVuv; -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -+ } -+ else if (pic->DVDPic.format == RENDER_FMT_VDPAU) -+ { -+ std::map::iterator it; -+ it = m_bufferPool.glOutputSurfaceMap.find(pic->sourceIdx); -+ if (it == m_bufferPool.glOutputSurfaceMap.end()) -+ { -+ CLog::Log(LOGDEBUG, "COutput::ProcessReturnPicture - gl surface not found"); -+ return; -+ } -+ VdpOutputSurface outSurf = it->second.sourceRgb; -+ m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, &outSurf, sizeof(outSurf)); -+ } -+} -+ -+int COutput::FindFreePixmap() -+{ -+ // find free pixmap -+ unsigned int i; -+ for (i = 0; i < m_bufferPool.pixmaps.size(); ++i) -+ { -+ if (!m_bufferPool.pixmaps[i].used) -+ break; -+ } -+ if (i == m_bufferPool.pixmaps.size()) -+ return -1; -+ else -+ return i; -+} -+ -+bool COutput::EnsureBufferPool() -+{ -+ VdpStatus vdp_st; -+ -+ // Creation of outputSurfaces -+ VdpOutputSurface outputSurface; -+ for (int i = m_bufferPool.outputSurfaces.size(); i < m_bufferPool.numOutputSurfaces; i++) -+ { -+ vdp_st = m_config.vdpProcs.vdp_output_surface_create(m_config.vdpDevice, -+ VDP_RGBA_FORMAT_B8G8R8A8, -+ m_config.outWidth, -+ m_config.outHeight, -+ &outputSurface); -+ if (CheckStatus(vdp_st, __LINE__)) -+ return false; -+ m_bufferPool.outputSurfaces.push_back(outputSurface); -+ -+ m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, -+ &outputSurface, -+ sizeof(VdpOutputSurface)); -+ CLog::Log(LOGNOTICE, "VDPAU::COutput::InitBufferPool - Output Surface created"); -+ } -+ -+ -+ if (m_config.usePixmaps && m_bufferPool.pixmaps.empty()) -+ { -+ // create pixmpas -+ VdpauBufferPool::Pixmaps pixmap; -+ int numPixmaps = NUM_RENDER_PICS; -+ for (unsigned int i = 0; i < numPixmaps; i++) -+ { -+ pixmap.pixmap = None; -+ pixmap.glPixmap = None; -+ pixmap.vdp_flip_queue = VDP_INVALID_HANDLE; -+ pixmap.vdp_flip_target = VDP_INVALID_HANDLE; -+ MakePixmap(pixmap); -+ glXMakeCurrent(m_Display, None, NULL); -+ vdp_st = m_config.vdpProcs.vdp_presentation_queue_target_create_x11(m_config.vdpDevice, -+ pixmap.pixmap, //x_window, -+ &pixmap.vdp_flip_target); -+ -+ CheckStatus(vdp_st, __LINE__); -+ -+ vdp_st = m_config.vdpProcs.vdp_presentation_queue_create(m_config.vdpDevice, -+ pixmap.vdp_flip_target, -+ &pixmap.vdp_flip_queue); -+ CheckStatus(vdp_st, __LINE__); -+ glXMakeCurrent(m_Display, m_glPixmap, m_glContext); -+ -+ pixmap.id = i; -+ pixmap.used = false; -+ m_bufferPool.pixmaps.push_back(pixmap); -+ } -+ GLBindPixmaps(); -+ } -+ -+ return true; -+} -+ -+void COutput::ReleaseBufferPool() -+{ -+ VdpStatus vdp_st; -+ -+ CSingleLock lock(m_bufferPool.renderPicSec); -+ -+ if (m_config.usePixmaps) -+ { -+ for (unsigned int i = 0; i < m_bufferPool.pixmaps.size(); ++i) -+ { -+ if (m_bufferPool.pixmaps[i].vdp_flip_queue != VDP_INVALID_HANDLE) -+ { -+ vdp_st = m_config.vdpProcs.vdp_presentation_queue_destroy(m_bufferPool.pixmaps[i].vdp_flip_queue); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ if (m_bufferPool.pixmaps[i].vdp_flip_target != VDP_INVALID_HANDLE) -+ { -+ vdp_st = m_config.vdpProcs.vdp_presentation_queue_target_destroy(m_bufferPool.pixmaps[i].vdp_flip_target); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ if (m_bufferPool.pixmaps[i].glPixmap) -+ { -+ glXDestroyPixmap(m_Display, m_bufferPool.pixmaps[i].glPixmap); -+ } -+ if (m_bufferPool.pixmaps[i].pixmap) -+ { -+ XFreePixmap(m_Display, m_bufferPool.pixmaps[i].pixmap); -+ } -+ } -+ m_bufferPool.pixmaps.clear(); -+ } -+ -+ // release all output surfaces -+ for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) -+ { -+ if (m_bufferPool.outputSurfaces[i] == VDP_INVALID_HANDLE) -+ continue; -+ vdp_st = m_config.vdpProcs.vdp_output_surface_destroy(m_bufferPool.outputSurfaces[i]); -+ CheckStatus(vdp_st, __LINE__); -+ } -+ m_bufferPool.outputSurfaces.clear(); -+ -+ // invalidate all used render pictures -+ for (unsigned int i = 0; i < m_bufferPool.usedRenderPics.size(); ++i) -+ { -+ m_bufferPool.usedRenderPics[i]->valid = false; -+ } -+} -+ -+void COutput::InitMixer() -+{ -+ for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) -+ { -+ m_mixer.m_dataPort.SendOutMessage(CMixerDataProtocol::BUFFER, -+ &m_bufferPool.outputSurfaces[i], -+ sizeof(VdpOutputSurface)); -+ } -+} -+ -+bool COutput::MakePixmap(VdpauBufferPool::Pixmaps &pixmap) -+{ -+ CLog::Log(LOGNOTICE,"Creating %ix%i pixmap", m_config.outWidth, m_config.outHeight); -+ -+ // Get our window attribs. -+ XWindowAttributes wndattribs; -+ XGetWindowAttributes(m_Display, g_Windowing.GetWindow(), &wndattribs); -+ -+ pixmap.pixmap = XCreatePixmap(m_Display, -+ g_Windowing.GetWindow(), -+ m_config.outWidth, -+ m_config.outHeight, -+ wndattribs.depth); -+ if (!pixmap.pixmap) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COUtput::MakePixmap - GLX Error: MakePixmap: Unable to create XPixmap"); -+ return false; -+ } -+ -+// XGCValues values = {}; -+// GC xgc; -+// values.foreground = BlackPixel (m_Display, DefaultScreen (m_Display)); -+// xgc = XCreateGC(m_Display, pixmap.pixmap, GCForeground, &values); -+// XFillRectangle(m_Display, pixmap.pixmap, xgc, 0, 0, m_config.outWidth, m_config.outHeight); -+// XFreeGC(m_Display, xgc); -+ -+ if(!MakePixmapGL(pixmap)) -+ return false; -+ -+ return true; -+} -+ -+bool COutput::MakePixmapGL(VdpauBufferPool::Pixmaps &pixmap) -+{ -+ int num=0; -+ int fbConfigIndex = 0; -+ -+ int doubleVisAttributes[] = { -+ GLX_RENDER_TYPE, GLX_RGBA_BIT, -+ GLX_RED_SIZE, 8, -+ GLX_GREEN_SIZE, 8, -+ GLX_BLUE_SIZE, 8, -+ GLX_ALPHA_SIZE, 8, -+ GLX_DEPTH_SIZE, 8, -+ GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, -+ GLX_BIND_TO_TEXTURE_RGBA_EXT, True, -+ GLX_DOUBLEBUFFER, False, -+ GLX_Y_INVERTED_EXT, True, -+ GLX_X_RENDERABLE, True, -+ None -+ }; -+ -+ int pixmapAttribs[] = { -+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, -+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, -+ None -+ }; -+ -+ GLXFBConfig *fbConfigs; -+ fbConfigs = glXChooseFBConfig(m_Display, g_Windowing.GetCurrentScreen(), doubleVisAttributes, &num); -+ if (fbConfigs==NULL) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput::MakPixmapGL - No compatible framebuffers found"); -+ return false; -+ } -+ fbConfigIndex = 0; -+ -+ pixmap.glPixmap = glXCreatePixmap(m_Display, fbConfigs[fbConfigIndex], pixmap.pixmap, pixmapAttribs); -+ -+ if (!pixmap.glPixmap) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput::MakPixmapGL - Could not create Pixmap"); -+ XFree(fbConfigs); -+ return false; -+ } -+ XFree(fbConfigs); -+ return true; -+} -+ -+bool COutput::GLInit() -+{ -+ glXBindTexImageEXT = NULL; -+ glXReleaseTexImageEXT = NULL; -+#ifdef GL_NV_vdpau_interop -+ glVDPAUInitNV = NULL; -+ glVDPAUFiniNV = NULL; -+ glVDPAURegisterOutputSurfaceNV = NULL; -+ glVDPAURegisterVideoSurfaceNV = NULL; -+ glVDPAUIsSurfaceNV = NULL; -+ glVDPAUUnregisterSurfaceNV = NULL; -+ glVDPAUSurfaceAccessNV = NULL; -+ glVDPAUMapSurfacesNV = NULL; -+ glVDPAUUnmapSurfacesNV = NULL; -+ glVDPAUGetSurfaceivNV = NULL; -+#endif -+ -+ m_config.usePixmaps = !g_guiSettings.GetBool("videoplayer.usevdpauinterop"); -+ -+#ifdef GL_NV_vdpau_interop -+ if (glewIsSupported("GL_NV_vdpau_interop")) -+ { -+ if (!glVDPAUInitNV) -+ glVDPAUInitNV = (PFNGLVDPAUINITNVPROC)glXGetProcAddress((GLubyte *) "glVDPAUInitNV"); -+ if (!glVDPAUFiniNV) -+ glVDPAUFiniNV = (PFNGLVDPAUFININVPROC)glXGetProcAddress((GLubyte *) "glVDPAUFiniNV"); -+ if (!glVDPAURegisterOutputSurfaceNV) -+ glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)glXGetProcAddress((GLubyte *) "glVDPAURegisterOutputSurfaceNV"); -+ if (!glVDPAURegisterVideoSurfaceNV) -+ glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)glXGetProcAddress((GLubyte *) "glVDPAURegisterVideoSurfaceNV"); -+ if (!glVDPAUIsSurfaceNV) -+ glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC)glXGetProcAddress((GLubyte *) "glVDPAUIsSurfaceNV"); -+ if (!glVDPAUUnregisterSurfaceNV) -+ glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC)glXGetProcAddress((GLubyte *) "glVDPAUUnregisterSurfaceNV"); -+ if (!glVDPAUSurfaceAccessNV) -+ glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC)glXGetProcAddress((GLubyte *) "glVDPAUSurfaceAccessNV"); -+ if (!glVDPAUMapSurfacesNV) -+ glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC)glXGetProcAddress((GLubyte *) "glVDPAUMapSurfacesNV"); -+ if (!glVDPAUUnmapSurfacesNV) -+ glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC)glXGetProcAddress((GLubyte *) "glVDPAUUnmapSurfacesNV"); -+ if (!glVDPAUGetSurfaceivNV) -+ glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC)glXGetProcAddress((GLubyte *) "glVDPAUGetSurfaceivNV"); -+ -+ CLog::Log(LOGNOTICE, "VDPAU::COutput GL interop supported"); -+ } -+ else -+#endif -+ { -+ m_config.usePixmaps = true; -+ g_guiSettings.SetBool("videoplayer.usevdpauinterop",false); -+ g_guiSettings.SetBool("videoplayer.usevdpauinteropyuv",false); -+ } -+ if (!glXBindTexImageEXT) -+ glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); -+ if (!glXReleaseTexImageEXT) -+ glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); -+ -+#ifdef GL_NV_vdpau_interop -+ if (!m_config.usePixmaps) -+ { -+ while (glGetError() != GL_NO_ERROR); -+ glVDPAUInitNV(reinterpret_cast(m_config.vdpDevice), reinterpret_cast(m_config.vdpProcs.vdp_get_proc_address)); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput - GLInitInterop glVDPAUInitNV failed"); -+ m_vdpError = true; -+ return false; -+ } -+ CLog::Log(LOGNOTICE, "VDPAU::COutput: vdpau gl interop initialized"); -+ } -+#endif -+ return true; -+} -+ -+void COutput::GLMapSurfaces() -+{ -+#ifdef GL_NV_vdpau_interop -+ if (m_config.usePixmaps) -+ return; -+ -+ if (m_config.useInteropYuv) -+ { -+ VdpauBufferPool::GLVideoSurface glSurface; -+ if (m_config.videoSurfaces->size() != m_bufferPool.glVideoSurfaceMap.size()) -+ { -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ for (int i = 0; i < m_config.videoSurfaces->size(); i++) -+ { -+ if ((*m_config.videoSurfaces)[i]->surface == VDP_INVALID_HANDLE) -+ continue; -+ -+ if (m_bufferPool.glVideoSurfaceMap.find((*m_config.videoSurfaces)[i]->surface) == m_bufferPool.glVideoSurfaceMap.end()) -+ { -+ glSurface.sourceVuv = (*m_config.videoSurfaces)[i]; -+ while (glGetError() != GL_NO_ERROR) ; -+ glGenTextures(4, glSurface.texture); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); -+ m_vdpError = true; -+ } -+ glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast((*m_config.videoSurfaces)[i]->surface), -+ GL_TEXTURE_2D, 4, glSurface.texture); -+ -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error register video surface"); -+ m_vdpError = true; -+ } -+ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -+ m_vdpError = true; -+ } -+ glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -+ m_vdpError = true; -+ } -+ m_bufferPool.glVideoSurfaceMap[(*m_config.videoSurfaces)[i]->surface] = glSurface; -+ if (m_vdpError) -+ return; -+ CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); -+ } -+ } -+ } -+ } -+ else -+ { -+ if (m_bufferPool.glOutputSurfaceMap.size() != m_bufferPool.numOutputSurfaces) -+ { -+ VdpauBufferPool::GLVideoSurface glSurface; -+ for (int i=m_bufferPool.glOutputSurfaceMap.size(); i(m_bufferPool.outputSurfaces[i]), -+ GL_TEXTURE_2D, 1, glSurface.texture); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error register output surface"); -+ m_vdpError = true; -+ } -+ glVDPAUSurfaceAccessNV(glSurface.glVdpauSurface, GL_READ_ONLY); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error setting access"); -+ m_vdpError = true; -+ } -+ glVDPAUMapSurfacesNV(1, &glSurface.glVdpauSurface); -+ if (glGetError() != GL_NO_ERROR) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); -+ m_vdpError = true; -+ } -+ m_bufferPool.glOutputSurfaceMap[m_bufferPool.outputSurfaces[i]] = glSurface; -+ if (m_vdpError) -+ return; -+ } -+ CLog::Log(LOGNOTICE, "VDPAU::COutput registered output surfaces"); -+ } -+ } -+#endif -+} -+ -+void COutput::GLUnmapSurfaces() -+{ -+#ifdef GL_NV_vdpau_interop -+ if (m_config.usePixmaps) -+ return; -+ -+ { CSingleLock lock(*m_config.videoSurfaceSec); -+ std::map::iterator it; -+ for (it = m_bufferPool.glVideoSurfaceMap.begin(); it != m_bufferPool.glVideoSurfaceMap.end(); ++it) -+ { -+ glVDPAUUnregisterSurfaceNV(it->second.glVdpauSurface); -+ glDeleteTextures(4, it->second.texture); -+ } -+ m_bufferPool.glVideoSurfaceMap.clear(); -+ } -+ -+ std::map::iterator it; -+ for (it = m_bufferPool.glOutputSurfaceMap.begin(); it != m_bufferPool.glOutputSurfaceMap.end(); ++it) -+ { -+ glVDPAUUnregisterSurfaceNV(it->second.glVdpauSurface); -+ glDeleteTextures(1, it->second.texture); -+ } -+ m_bufferPool.glOutputSurfaceMap.clear(); -+ -+ glVDPAUFiniNV(); -+ -+ CLog::Log(LOGNOTICE, "VDPAU::COutput: vdpau gl interop finished"); -+ -+#endif -+} -+ -+void COutput::GLBindPixmaps() -+{ -+ if (!m_config.usePixmaps) -+ return; -+ -+ for (unsigned int i = 0; i < m_bufferPool.pixmaps.size(); i++) -+ { -+ // create texture -+ glGenTextures(1, &m_bufferPool.pixmaps[i].texture); -+ -+ //bind texture -+ glBindTexture(GL_TEXTURE_2D, m_bufferPool.pixmaps[i].texture); -+ -+ // bind pixmap -+ glXBindTexImageEXT(m_Display, m_bufferPool.pixmaps[i].glPixmap, GLX_FRONT_LEFT_EXT, NULL); -+ -+ glBindTexture(GL_TEXTURE_2D, 0); -+ } -+ -+ CLog::Log(LOGNOTICE, "VDPAU::COutput: bound pixmaps"); -+} -+ -+void COutput::GLUnbindPixmaps() -+{ -+ if (!m_config.usePixmaps) -+ return; -+ -+ for (unsigned int i = 0; i < m_bufferPool.pixmaps.size(); i++) -+ { -+ // create texture -+ if (!glIsTexture(m_bufferPool.pixmaps[i].texture)) -+ continue; -+ -+ //bind texture -+ glBindTexture(GL_TEXTURE_2D, m_bufferPool.pixmaps[i].texture); -+ -+ // release pixmap -+ glXReleaseTexImageEXT(m_Display, m_bufferPool.pixmaps[i].glPixmap, GLX_FRONT_LEFT_EXT); -+ -+ glBindTexture(GL_TEXTURE_2D, 0); -+ -+ glDeleteTextures(1, &m_bufferPool.pixmaps[i].texture); -+ } -+ CLog::Log(LOGNOTICE, "VDPAU::COutput: unbound pixmaps"); -+} -+ -+bool COutput::CheckStatus(VdpStatus vdp_st, int line) -+{ -+ if (vdp_st != VDP_STATUS_OK) -+ { -+ CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) at %s:%d\n", m_config.vdpProcs.vdp_get_error_string(vdp_st), vdp_st, __FILE__, line); -+ m_vdpError = true; -+ return true; -+ } -+ return false; -+} -+ -+bool COutput::CreateGlxContext() -+{ -+ GLXContext glContext; -+ Window window; -+ -+ m_Display = g_Windowing.GetDisplay(); -+ glContext = g_Windowing.GetGlxContext(); -+ m_Window = g_Windowing.GetWindow(); -+ -+ // Get our window attribs. -+ XWindowAttributes wndattribs; -+ XGetWindowAttributes(m_Display, m_Window, &wndattribs); -+ -+ // Get visual Info -+ XVisualInfo visInfo; -+ visInfo.visualid = wndattribs.visual->visualid; -+ int nvisuals = 0; -+ XVisualInfo* visuals = XGetVisualInfo(m_Display, VisualIDMask, &visInfo, &nvisuals); -+ if (nvisuals != 1) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput::CreateGlxContext - could not find visual"); -+ return false; -+ } -+ visInfo = visuals[0]; -+ XFree(visuals); -+ -+ m_pixmap = XCreatePixmap(m_Display, -+ m_Window, -+ 192, -+ 108, -+ visInfo.depth); -+ if (!m_pixmap) -+ { -+ CLog::Log(LOGERROR, "VDPAU::COutput::CreateGlxContext - Unable to create XPixmap"); -+ return false; -+ } -+ -+ // create gl pixmap -+ m_glPixmap = glXCreateGLXPixmap(m_Display, &visInfo, m_pixmap); -+ -+ if (!m_glPixmap) -+ { -+ CLog::Log(LOGINFO, "VDPAU::COutput::CreateGlxContext - Could not create glPixmap"); -+ return false; -+ } -+ -+ m_glContext = glXCreateContext(m_Display, &visInfo, glContext, True); -+ -+ if (!glXMakeCurrent(m_Display, m_glPixmap, m_glContext)) -+ { -+ CLog::Log(LOGINFO, "VDPAU::COutput::CreateGlxContext - Could not make Pixmap current"); -+ return false; -+ } -+ -+ CLog::Log(LOGNOTICE, "VDPAU::COutput::CreateGlxContext - created context"); -+ return true; -+} -+ -+bool COutput::DestroyGlxContext() -+{ -+ if (m_glContext) -+ { -+ glXMakeCurrent(m_Display, None, NULL); -+ glXDestroyContext(m_Display, m_glContext); -+ } -+ m_glContext = 0; -+ -+ if (m_glPixmap) -+ glXDestroyPixmap(m_Display, m_glPixmap); -+ m_glPixmap = 0; -+ -+ if (m_pixmap) -+ XFreePixmap(m_Display, m_pixmap); -+ m_pixmap = 0; -+ -+ return true; -+} -+ - #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 -@@ -1,5 +1,3 @@ -- --#pragma once - /* - * Copyright (C) 2005-2012 Team XBMC - * http://www.xbmc.org -@@ -20,9 +18,32 @@ - * - */ - -+/** -+ * design goals: -+ * - improve performance -+ * max out hw resources: e.g. make 1080p60 play on ION2 -+ * allow advanced de-interlacing on ION -+ * -+ * - add vdpau/opengl interop -+ * -+ * - remove tight dependency to render thread -+ * prior design needed to hijack render thread in order to do -+ * gl interop functions. In particular this was a problem for -+ * init and clear down. Introduction of GL_NV_vdpau_interop -+ * increased the need to be independent from render thread -+ * -+ * - move to an actor based design in order to reduce the number -+ * of locks needed. -+ */ -+ -+#pragma once -+ - #include "system_gl.h" - --#include -+#include "DllAvUtil.h" -+#include "DVDVideoCodec.h" -+#include "DVDVideoCodecFFmpeg.h" -+#include "libavcodec/vdpau.h" - #include - #include - #define GLX_GLXEXT_PROTOTYPES -@@ -37,118 +58,31 @@ - #include "settings/VideoSettings.h" - #include "guilib/DispResource.h" - #include "threads/Event.h" --namespace Surface { class CSurface; } -- --#define NUM_OUTPUT_SURFACES 4 --#define NUM_VIDEO_SURFACES_MPEG2 10 // (1 frame being decoded, 2 reference) --#define NUM_VIDEO_SURFACES_H264 32 // (1 frame being decoded, up to 16 references) --#define NUM_VIDEO_SURFACES_VC1 10 // (same as MPEG-2) --#define NUM_OUTPUT_SURFACES_FOR_FULLHD 2 --#define FULLHD_WIDTH 1920 -- --class CVDPAU -- : public CDVDVideoCodecFFmpeg::IHardwareDecoder -- , public IDispResource --{ --public: -- -- struct pictureAge -- { -- int b_age; -- int ip_age[2]; -- }; -- -- struct Desc -- { -- const char *name; -- uint32_t id; -- uint32_t aux; /* optional extra parameter... */ -- }; -- -- CVDPAU(); -- virtual ~CVDPAU(); -- -- virtual bool Open (AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces = 0); -- virtual int Decode (AVCodecContext* avctx, AVFrame* frame); -- virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); -- virtual void Reset(); -- virtual void Close(); -- -- virtual int Check(AVCodecContext* avctx); -- -- virtual const std::string Name() { return "vdpau"; } -- -- bool MakePixmap(int width, int height); -- bool MakePixmapGL(); -- -- void ReleasePixmap(); -- void BindPixmap(); -- -- PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; -- PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; -- GLXPixmap m_glPixmap; -- Pixmap m_Pixmap; -- -- static void FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic); -- static void FFDrawSlice(struct AVCodecContext *s, -- const AVFrame *src, int offset[4], -- int y, int type, int height); -- static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic); -- -- void Present(); -- bool ConfigVDPAU(AVCodecContext *avctx, int ref_frames); -- void SpewHardwareAvailable(); -- 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; - -- pictureAge picAge; -- vdpau_render_state *past[2], *current, *future; -- int tmpDeintMode, tmpDeintGUI, tmpDeint; -- float tmpNoiseReduction, tmpSharpness; -- float tmpBrightness, tmpContrast; -- int OutWidth, OutHeight; -- bool upScale; -- std::queue m_DVDVideoPics; - -- static inline void ClearUsedForRender(vdpau_render_state **st) -- { -- if (*st) { -- (*st)->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; -- *st = NULL; -- } -- } -- -- 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 - -+namespace VDPAU -+{ - -- // protected: -- void InitVDPAUProcs(); -- void FiniVDPAUProcs(); -- 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; -- VdpVideoSurfaceGetBitsYCbCr * vdp_video_surface_get_bits_y_cb_cr; -+ VdpVideoSurfaceCreate * vdp_video_surface_create; -+ VdpVideoSurfaceDestroy * vdp_video_surface_destroy; -+ VdpVideoSurfacePutBitsYCbCr * vdp_video_surface_put_bits_y_cb_cr; -+ VdpVideoSurfaceGetBitsYCbCr * vdp_video_surface_get_bits_y_cb_cr; - - VdpOutputSurfacePutBitsYCbCr * vdp_output_surface_put_bits_y_cb_cr; - VdpOutputSurfacePutBitsNative * vdp_output_surface_put_bits_native; -@@ -158,15 +92,15 @@ class CVDPAU - VdpOutputSurfaceRenderOutputSurface * vdp_output_surface_render_output_surface; - VdpOutputSurfacePutBitsIndexed * vdp_output_surface_put_bits_indexed; - -- VdpVideoMixerCreate * vdp_video_mixer_create; -- VdpVideoMixerSetFeatureEnables * vdp_video_mixer_set_feature_enables; -- VdpVideoMixerQueryParameterSupport * vdp_video_mixer_query_parameter_support; -- VdpVideoMixerQueryFeatureSupport * vdp_video_mixer_query_feature_support; -- VdpVideoMixerDestroy * vdp_video_mixer_destroy; -- VdpVideoMixerRender * vdp_video_mixer_render; -- VdpVideoMixerSetAttributeValues * vdp_video_mixer_set_attribute_values; -+ VdpVideoMixerCreate * vdp_video_mixer_create; -+ VdpVideoMixerSetFeatureEnables * vdp_video_mixer_set_feature_enables; -+ VdpVideoMixerQueryParameterSupport * vdp_video_mixer_query_parameter_support; -+ VdpVideoMixerQueryFeatureSupport * vdp_video_mixer_query_feature_support; -+ VdpVideoMixerDestroy * vdp_video_mixer_destroy; -+ VdpVideoMixerRender * vdp_video_mixer_render; -+ VdpVideoMixerSetAttributeValues * vdp_video_mixer_set_attribute_values; - -- VdpGenerateCSCMatrix * vdp_generate_csc_matrix; -+ VdpGenerateCSCMatrix * vdp_generate_csc_matrix; - - VdpPresentationQueueTargetDestroy * vdp_presentation_queue_target_destroy; - VdpPresentationQueueCreate * vdp_presentation_queue_create; -@@ -179,64 +113,459 @@ class CVDPAU - - VdpGetErrorString * vdp_get_error_string; - -- VdpDecoderCreate * vdp_decoder_create; -- VdpDecoderDestroy * vdp_decoder_destroy; -- VdpDecoderRender * vdp_decoder_render; -- VdpDecoderQueryCapabilities * vdp_decoder_query_caps; -+ VdpDecoderCreate * vdp_decoder_create; -+ VdpDecoderDestroy * vdp_decoder_destroy; -+ VdpDecoderRender * vdp_decoder_render; -+ VdpDecoderQueryCapabilities * vdp_decoder_query_caps; - - VdpPreemptionCallbackRegister * vdp_preemption_callback_register; - -- 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; - -- int surfaceNum; -- int presentSurfaceNum; -- int totalAvailableOutputSurfaces; -- uint32_t vid_width, vid_height; -- int surface_width, surface_height; -- uint32_t max_references; -- Display* m_Display; -- bool vdpauConfigured; -- uint32_t *m_BlackBar; -+/** -+ * Buffer statistics used to control number of frames in queue -+ */ - -+class CVdpauBufferStats -+{ -+public: -+ uint16_t decodedPics; -+ uint16_t processedPics; -+ uint16_t renderPics; -+ uint64_t latency; // time decoder has waited for a frame, ideally there is no latency -+ int playSpeed; -+ bool canSkipDeint; -+ int processCmd; -+ -+ void IncDecoded() { CSingleLock l(m_sec); decodedPics++;} -+ void DecDecoded() { CSingleLock l(m_sec); decodedPics--;} -+ void IncProcessed() { CSingleLock l(m_sec); processedPics++;} -+ void DecProcessed() { CSingleLock l(m_sec); processedPics--;} -+ void IncRender() { CSingleLock l(m_sec); renderPics++;} -+ void DecRender() { CSingleLock l(m_sec); renderPics--;} -+ void Reset() { CSingleLock l(m_sec); decodedPics=0; processedPics=0;renderPics=0;latency=0;} -+ void Get(uint16_t &decoded, uint16_t &processed, uint16_t &render) {CSingleLock l(m_sec); decoded = decodedPics, processed=processedPics, render=renderPics;} -+ void SetParams(uint64_t time, int speed) { CSingleLock l(m_sec); latency = time; playSpeed = speed; } -+ void GetParams(uint64_t &lat, int &speed) { CSingleLock l(m_sec); lat = latency; speed = playSpeed; } -+ void SetCmd(int cmd) { CSingleLock l(m_sec); processCmd = cmd; } -+ void GetCmd(int &cmd) { CSingleLock l(m_sec); cmd = processCmd; processCmd = 0; } -+ void SetCanSkipDeint(bool canSkip) { CSingleLock l(m_sec); canSkipDeint = canSkip; } -+ bool CanSkipDeint() { CSingleLock l(m_sec); if (canSkipDeint) return true; else return false;} -+private: -+ CCriticalSection m_sec; -+}; -+ -+/** -+ * CVdpauConfig holds all configuration parameters needed by vdpau -+ * The structure is sent to the internal classes CMixer and COutput -+ * for init. -+ */ - -+struct CVdpauConfig -+{ -+ int surfaceWidth; -+ int surfaceHeight; -+ int vidWidth; -+ int vidHeight; -+ int outWidth; -+ int outHeight; -+ VDPAU_procs vdpProcs; -+ VdpDevice vdpDevice; -+ VdpDecoder vdpDecoder; -+ VdpChromaType vdpChromaType; -+ CVdpauBufferStats *stats; -+ CDecoder *vdpau; -+ int featureCount; -+ int upscale; -+ VdpVideoMixerFeature vdpFeatures[14]; -+ std::vector *videoSurfaces; -+ CCriticalSection *videoSurfaceSec; -+ bool usePixmaps; -+ int numRenderBuffers; -+ uint32_t maxReferences; -+ bool useInteropYuv; -+}; -+ -+/** -+ * Holds a decoded frame -+ * Input to COutput for further processing -+ */ -+struct CVdpauDecodedPicture -+{ -+ DVDVideoPicture DVDPic; -+ vdpau_render_state *render; -+}; -+ -+/** -+ * Frame after having been processed by vdpau mixer -+ */ -+struct CVdpauProcessedPicture -+{ -+ DVDVideoPicture DVDPic; -+ vdpau_render_state *render; -+ VdpOutputSurface outputSurface; -+}; -+ -+/** -+ * Ready to render textures -+ * Sent from COutput back to CDecoder -+ * Objects are referenced by DVDVideoPicture and are sent -+ * to renderer -+ */ -+class CVdpauRenderPicture -+{ -+ friend class CDecoder; -+ friend class COutput; -+public: -+ DVDVideoPicture DVDPic; -+ int texWidth, texHeight; -+ CRect crop; -+ GLuint texture[4]; -+ uint32_t sourceIdx; -+ bool valid; -+ CDecoder *vdpau; -+ CVdpauRenderPicture* Acquire(); -+ long Release(); -+private: -+ void ReturnUnused(); -+ int refCount; -+ CCriticalSection *renderPicSection; -+}; -+ -+//----------------------------------------------------------------------------- -+// Mixer -+//----------------------------------------------------------------------------- -+ -+class CMixerControlProtocol : public Protocol -+{ -+public: -+ CMixerControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ INIT = 0, -+ FLUSH, -+ TIMEOUT, -+ }; -+ enum InSignal -+ { -+ ACC, -+ ERROR, -+ }; -+}; -+ -+class CMixerDataProtocol : public Protocol -+{ -+public: -+ CMixerDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ FRAME, -+ BUFFER, -+ }; -+ enum InSignal -+ { -+ PICTURE, -+ }; -+}; -+ -+/** -+ * Embeds the vdpau video mixer -+ * Embedded by COutput class, gets decoded frames from COutput, processes -+ * them in mixer ands sends processed frames back to COutput -+ */ -+class CMixer : private CThread -+{ -+public: -+ CMixer(CEvent *inMsgEvent); -+ virtual ~CMixer(); -+ void Start(); -+ void Dispose(); -+ CMixerControlProtocol m_controlPort; -+ CMixerDataProtocol m_dataPort; -+protected: -+ void OnStartup(); -+ void OnExit(); -+ void Process(); -+ void StateMachine(int signal, Protocol *port, Message *msg); -+ void Init(); -+ void Uninit(); -+ void Flush(); -+ void CreateVdpauMixer(); -+ void ProcessPicture(); -+ void InitCycle(); -+ void FiniCycle(); -+ void CheckFeatures(); -+ void SetPostProcFeatures(bool postProcEnabled); -+ void PostProcOff(); -+ void InitCSCMatrix(int Width); -+ bool GenerateStudioCSCMatrix(VdpColorStandard colorStandard, VdpCSCMatrix &studioCSCMatrix); -+ void SetColor(); -+ void SetNoiseReduction(); -+ void SetSharpness(); -+ void SetDeintSkipChroma(); -+ void SetDeinterlacing(); -+ void SetHWUpscaling(); -+ void DisableHQScaling(); -+ EINTERLACEMETHOD GetDeinterlacingMethod(bool log = false); -+ bool CheckStatus(VdpStatus vdp_st, int line); -+ CEvent m_outMsgEvent; -+ CEvent *m_inMsgEvent; -+ int m_state; -+ bool m_bStateMachineSelfTrigger; -+ -+ // extended state variables for state machine -+ int m_extTimeout; -+ bool m_vdpError; -+ CVdpauConfig m_config; -+ VdpVideoMixer m_videoMixer; -+ VdpProcamp m_Procamp; -+ VdpCSCMatrix m_CSCMatrix; -+ bool m_PostProc; -+ float m_Brightness; -+ float m_Contrast; -+ float m_NoiseReduction; -+ float m_Sharpness; -+ int m_DeintMode; -+ int m_Deint; -+ int m_Upscale; -+ uint32_t *m_BlackBar; - VdpVideoMixerPictureStructure m_mixerfield; -- int m_mixerstep; -+ int m_mixerstep; -+ int m_mixersteps; -+ CVdpauProcessedPicture m_processPicture; -+ std::queue m_outputSurfaces; -+ std::queue m_decodedPics; -+ std::deque m_mixerInput; -+}; -+ -+//----------------------------------------------------------------------------- -+// Output -+//----------------------------------------------------------------------------- -+ -+/** -+ * Buffer pool holds allocated vdpau and gl resources -+ * Embedded in COutput -+ */ -+struct VdpauBufferPool -+{ -+ struct Pixmaps -+ { -+ unsigned short id; -+ bool used; -+ DVDVideoPicture DVDPic; -+ GLuint texture; -+ Pixmap pixmap; -+ GLXPixmap glPixmap; -+ VdpPresentationQueueTarget vdp_flip_target; -+ VdpPresentationQueue vdp_flip_queue; -+ VdpOutputSurface surface; -+ }; -+ struct GLVideoSurface -+ { -+ GLuint texture[4]; -+#ifdef GL_NV_vdpau_interop -+ GLvdpauSurfaceNV glVdpauSurface; -+#endif -+ vdpau_render_state *sourceVuv; -+ VdpOutputSurface sourceRgb; -+ }; -+ unsigned short numOutputSurfaces; -+ std::vector pixmaps; -+ std::vector outputSurfaces; -+ std::deque notVisiblePixmaps; -+ std::vector allRenderPics; -+ std::map glVideoSurfaceMap; -+ std::map glOutputSurfaceMap; -+ std::queue processedPics; -+ std::deque usedRenderPics; -+ std::deque freeRenderPics; -+ CCriticalSection renderPicSec; -+}; -+ -+class COutputControlProtocol : public Protocol -+{ -+public: -+ COutputControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ INIT, -+ FLUSH, -+ PRECLEANUP, -+ TIMEOUT, -+ }; -+ enum InSignal -+ { -+ ACC, -+ ERROR, -+ STATS, -+ }; -+}; -+ -+class COutputDataProtocol : public Protocol -+{ -+public: -+ COutputDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ NEWFRAME = 0, -+ RETURNPIC, -+ }; -+ enum InSignal -+ { -+ PICTURE, -+ }; -+}; -+ -+/** -+ * COutput is embedded in CDecoder and embeds CMixer -+ * The class has its own OpenGl context which is shared with render thread -+ * COuput generated ready to render textures and passes them back to -+ * CDecoder -+ */ -+class COutput : private CThread -+{ -+public: -+ COutput(CEvent *inMsgEvent); -+ virtual ~COutput(); -+ void Start(); -+ void Dispose(); -+ COutputControlProtocol m_controlPort; -+ COutputDataProtocol m_dataPort; -+protected: -+ void OnStartup(); -+ void OnExit(); -+ void Process(); -+ void StateMachine(int signal, Protocol *port, Message *msg); -+ bool HasWork(); -+ CVdpauRenderPicture *ProcessMixerPicture(); -+ void ProcessReturnPicture(CVdpauRenderPicture *pic); -+ int FindFreePixmap(); -+ bool Init(); -+ bool Uninit(); -+ void Flush(); -+ bool CreateGlxContext(); -+ bool DestroyGlxContext(); -+ bool EnsureBufferPool(); -+ void ReleaseBufferPool(); -+ void InitMixer(); -+ bool GLInit(); -+ void GLMapSurfaces(); -+ void GLUnmapSurfaces(); -+ void GLBindPixmaps(); -+ void GLUnbindPixmaps(); -+ bool MakePixmap(VdpauBufferPool::Pixmaps &pixmap); -+ bool MakePixmapGL(VdpauBufferPool::Pixmaps &pixmap); -+ bool CheckStatus(VdpStatus vdp_st, int line); -+ CEvent m_outMsgEvent; -+ CEvent *m_inMsgEvent; -+ int m_state; -+ bool m_bStateMachineSelfTrigger; -+ -+ // extended state variables for state machine -+ int m_extTimeout; -+ bool m_vdpError; -+ CVdpauConfig m_config; -+ VdpauBufferPool m_bufferPool; -+ CMixer m_mixer; -+ Display *m_Display; -+ Window m_Window; -+ GLXContext m_glContext; -+ GLXWindow m_glWindow; -+ Pixmap m_pixmap; -+ GLXPixmap m_glPixmap; -+ -+ // gl functions -+ PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT; -+ PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT; -+#ifdef GL_NV_vdpau_interop -+ PFNGLVDPAUINITNVPROC glVDPAUInitNV; -+ PFNGLVDPAUFININVPROC glVDPAUFiniNV; -+ PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glVDPAURegisterOutputSurfaceNV; -+ PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glVDPAURegisterVideoSurfaceNV; -+ PFNGLVDPAUISSURFACENVPROC glVDPAUIsSurfaceNV; -+ PFNGLVDPAUUNREGISTERSURFACENVPROC glVDPAUUnregisterSurfaceNV; -+ PFNGLVDPAUSURFACEACCESSNVPROC glVDPAUSurfaceAccessNV; -+ PFNGLVDPAUMAPSURFACESNVPROC glVDPAUMapSurfacesNV; -+ PFNGLVDPAUUNMAPSURFACESNVPROC glVDPAUUnmapSurfacesNV; -+ PFNGLVDPAUGETSURFACEIVNVPROC glVDPAUGetSurfaceivNV; -+#endif -+}; -+ -+//----------------------------------------------------------------------------- -+// VDPAU decoder -+//----------------------------------------------------------------------------- -+ -+/** -+ * VDPAU main class -+ */ -+class CDecoder -+ : public CDVDVideoCodecFFmpeg::IHardwareDecoder -+ , public IDispResource -+{ -+ friend class CVdpauRenderPicture; -+ -+public: -+ -+ struct Desc -+ { -+ const char *name; -+ uint32_t id; -+ uint32_t aux; /* optional extra parameter... */ -+ }; -+ -+ CDecoder(); -+ virtual ~CDecoder(); -+ -+ virtual bool Open (AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces = 0); -+ virtual int Decode (AVCodecContext* avctx, AVFrame* frame); -+ virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); -+ virtual void Reset(); -+ virtual void Close(); -+ virtual long Release(); -+ virtual bool CanSkipDeint(); -+ -+ virtual int Check(AVCodecContext* avctx); -+ virtual const std::string Name() { return "vdpau"; } - - bool Supports(VdpVideoMixerFeature feature); - bool Supports(EINTERLACEMETHOD method); - EINTERLACEMETHOD AutoInterlaceMethod(); -+ static bool IsVDPAUFormat(PixelFormat fmt); - -- VdpVideoMixerFeature m_features[14]; -- int m_feature_count; -+ static void FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic); -+ static void FFDrawSlice(struct AVCodecContext *s, -+ const AVFrame *src, int offset[4], -+ int y, int type, int height); -+ static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic); -+ -+ virtual void OnLostDevice(); -+ virtual void OnResetDevice(); -+ -+protected: -+ void SetWidthHeight(int width, int height); -+ bool ConfigVDPAU(AVCodecContext *avctx, int ref_frames); -+ void SpewHardwareAvailable(); -+ bool CheckStatus(VdpStatus vdp_st, int line); -+ bool IsSurfaceValid(vdpau_render_state *render); -+ void InitVDPAUProcs(); -+ void FiniVDPAUProcs(); -+ void FiniVDPAUOutput(); -+ void ReturnRenderPicture(CVdpauRenderPicture *renderPic); -+ long ReleasePicReference(); - -- static bool IsVDPAUFormat(PixelFormat fmt); - static void ReadFormatOf( PixelFormat fmt - , VdpDecoderProfile &decoder_profile - , VdpChromaType &chroma_type); - -- std::vector m_videoSurfaces; -- DllAvUtil m_dllAvUtil; -- -- enum VDPAUOutputMethod -- { -- OUTPUT_NONE, -- OUTPUT_PIXMAP, -- OUTPUT_GL_INTEROP_RGB, -- OUTPUT_GL_INTEROP_YUV -- }; -- VDPAUOutputMethod m_vdpauOutputMethod; -+ 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); - - // OnLostDevice triggers transition from all states to LOST - // internal errors trigger transition from OPEN to RESET -@@ -247,9 +576,24 @@ class CVDPAU - , VDPAU_LOST - , VDPAU_ERROR - } m_DisplayState; -- CSharedSection m_DecoderSection; -- CSharedSection m_DisplaySection; -+ CCriticalSection m_DecoderSection; - CEvent m_DisplayEvent; -- virtual void OnLostDevice(); -- virtual void OnResetDevice(); -+ -+ static void* dl_handle; -+ DllAvUtil m_dllAvUtil; -+ Display* m_Display; -+ ThreadIdentifier m_decoderThread; -+ bool m_vdpauConfigured; -+ CVdpauConfig m_vdpauConfig; -+ std::vector m_videoSurfaces; -+ CCriticalSection m_videoSurfaceSec; -+ -+ COutput m_vdpauOutput; -+ CVdpauBufferStats m_bufferStats; -+ CEvent m_inMsgEvent; -+ CVdpauRenderPicture *m_presentPicture; -+ -+ int m_codecControl; - }; -+ -+} -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.8.1.6 - - -From 5467f4b81a86ce4cd77039b6cfe151df0facafd7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 09:52:17 +0100 -Subject: [PATCH 28/94] 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 f18f109..7c534a6 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5118,7 +5118,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.8.1.6 - - -From 5bc4483a6acd3e0fe6f72d96b4ad17b2d2ced0f0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 18:34:47 +0100 -Subject: [PATCH 29/94] 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 7c534a6..41e32a6 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -4368,11 +4368,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.8.1.6 - - -From f9581c0dd5fb9e63eaa0c2aa38fbaa48794cf2c2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 20:28:49 +0100 -Subject: [PATCH 30/94] 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.8.1.6 - - -From 0a520997eddf638c60924ba81f338b1223de35a6 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 27 Jan 2013 12:10:19 +0100 -Subject: [PATCH 31/94] 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.8.1.6 - - -From 2e9f0f7ddcf0935d061b9acda5259f5265932898 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 2 Feb 2013 13:17:09 +0100 -Subject: [PATCH 32/94] 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.8.1.6 - - -From 65f26cb37d53b5bcaef1c2b3f22c63c9601e5428 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 12:14:15 +0200 -Subject: [PATCH 33/94] 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.8.1.6 - - -From ec43b4a3d63ddf789bdb49f3aadaf0c0497eec2b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 13:20:47 +0200 -Subject: [PATCH 34/94] 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.8.1.6 - - -From 3cf3d02810620738ed653e3a54f3c747e8975a5c Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 35/94] 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 ffd86a7..7e3de37 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.8.1.6 - - -From e771f1b96d6f77358720b58362ed525cc9b9f01f Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 36/94] 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.8.1.6 - - -From 2a6b9a273a99c30cef58e083b6afd61c5cb4d20c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 37/94] 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.8.1.6 - - -From 1fb4ee276dee8b7aad61bb8be2c8debac050ca07 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 38/94] 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.8.1.6 - - -From d0268b4a14addd0564c6e1c3090ac844d12a3f31 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 39/94] 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.8.1.6 - - -From 2a5d2c53118b7bf1cf7636f6d9aa95b835364832 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 40/94] 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.8.1.6 - - -From a9567d6413d1c2fd1f8fdbc51f0cb6ca3c19dc5d Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 41/94] 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.8.1.6 - - -From d3c2af7c408efbf313db86d43b0959b03f5bbb0f Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 42/94] 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.8.1.6 - - -From f8d8a2625e65c1e925a19153c742d2356bcede98 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 43/94] 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 41e32a6..6cefd26 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -894,7 +894,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.8.1.6 - - -From 72f4bcfafc19d89b23339537c5f019a9f065db94 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 44/94] 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.8.1.6 - - -From e787a6adc6f3959c1e2292b6ebf0248e2c677bfd Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 45/94] 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.8.1.6 - - -From a76601dd7f1ebbe3e753192152457f41c1951f36 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 46/94] 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.8.1.6 - - -From 6d48cbaa3fc53e646cc86da83534eaa6fc8cb449 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 47/94] 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.8.1.6 - - -From 1636c5e745fc2a37ad6bb735628342a6251bf9ad Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 48/94] 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.8.1.6 - - -From 83dbf0a3c154fd544a53a26399e659ed6f88bcd4 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 49/94] 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.8.1.6 - - -From c0123c262e1b251bc4c9f05e9bb13b67be4341a5 Mon Sep 17 00:00:00 2001 -From: FernetMenta -Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 50/94] 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.8.1.6 - - -From 779f1492b78e0784c44abcc52baf1574f416a411 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 51/94] 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.8.1.6 - - -From 09f5f756e289e497f26b8bf389b816ce1061fc4a Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 52/94] 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.8.1.6 - - -From dc954e75c70003fb6cfa29965f525a8addb69052 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 53/94] 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.8.1.6 - - -From b64d1ae858587c3b62f19ee08517956ceebf77a9 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 54/94] 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.8.1.6 - - -From 39406f7e4f0a5a338109941303fd7afefc5e85b5 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 55/94] 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.8.1.6 - - -From 7810f1067b553e70f08df4bdb67c9bb9b8e83f83 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 56/94] 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.8.1.6 - - -From 36fcc0c608b65e7ff2a63ff752656eda9e45179b Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 57/94] 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.8.1.6 - - -From 18ae547a1813f27053d13195fc2c513da1f98f47 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 58/94] 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.8.1.6 - - -From 3ba526d4c50a2ab5f80f71b2627a3affb03e02e3 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 59/94] 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.8.1.6 - - -From 474ca94e03b3f2c8875799054c058df5fd7631f8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 60/94] 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.8.1.6 - - -From 28537693e86087cb858924447743a092e9d0dd02 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 61/94] 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.8.1.6 - - -From 722894437d4fac824e3e136c970a5b74e4d235bd Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 8 Oct 2011 16:45:13 +0200 -Subject: [PATCH 62/94] 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.8.1.6 - - -From 3a35525b8fc4180312c55b6956955cbb405ba272 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 12 Apr 2012 12:09:31 +0200 -Subject: [PATCH 63/94] 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 e98cc95..f3c1d23 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. ==" -@@ -245,6 +247,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], -@@ -1727,6 +1735,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 -@@ -1938,6 +1978,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 -@@ -2406,6 +2452,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) -@@ -2588,6 +2635,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 6cefd26..6437aba 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5119,7 +5119,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" -@@ -6341,7 +6345,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 -@@ -0,0 +1,2367 @@ -+/* -+ * Copyright (C) 2005-2011 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 HAVE_LIBXVBA -+ -+#include "system_gl.h" -+#include -+#include -+#include "XVBA.h" -+#include "windowing/WindowingFactory.h" -+#include "guilib/GraphicContext.h" -+#include "settings/GUISettings.h" -+#include "settings/Settings.h" -+#include "utils/TimeUtils.h" -+#include "cores/dvdplayer/DVDClock.h" -+ -+using namespace XVBA; -+ -+// XVBA interface -+ -+#define XVBA_LIBRARY "libXvBAW.so.1" -+ -+typedef Bool (*XVBAQueryExtensionProc) (Display *dpy, int *vers); -+typedef Status (*XVBACreateContextProc) (void *input, void *output); -+typedef Status (*XVBADestroyContextProc) (void *context); -+typedef Bool (*XVBAGetSessionInfoProc) (void *input, void *output); -+typedef Status (*XVBACreateSurfaceProc) (void *input, void *output); -+typedef Status (*XVBACreateGLSharedSurfaceProc)(void *input, void *output); -+typedef Status (*XVBADestroySurfaceProc) (void *surface); -+typedef Status (*XVBACreateDecodeBuffersProc) (void *input, void *output); -+typedef Status (*XVBADestroyDecodeBuffersProc) (void *input); -+typedef Status (*XVBAGetCapDecodeProc) (void *input, void *output); -+typedef Status (*XVBACreateDecodeProc) (void *input, void *output); -+typedef Status (*XVBADestroyDecodeProc) (void *session); -+typedef Status (*XVBAStartDecodePictureProc) (void *input); -+typedef Status (*XVBADecodePictureProc) (void *input); -+typedef Status (*XVBAEndDecodePictureProc) (void *input); -+typedef Status (*XVBASyncSurfaceProc) (void *input, void *output); -+typedef Status (*XVBAGetSurfaceProc) (void *input); -+typedef Status (*XVBATransferSurfaceProc) (void *input); -+ -+static struct -+{ -+ XVBAQueryExtensionProc QueryExtension; -+ XVBACreateContextProc CreateContext; -+ XVBADestroyContextProc DestroyContext; -+ XVBAGetSessionInfoProc GetSessionInfo; -+ XVBACreateSurfaceProc CreateSurface; -+ XVBACreateGLSharedSurfaceProc CreateGLSharedSurface; -+ XVBADestroySurfaceProc DestroySurface; -+ XVBACreateDecodeBuffersProc CreateDecodeBuffers; -+ XVBADestroyDecodeBuffersProc DestroyDecodeBuffers; -+ XVBAGetCapDecodeProc GetCapDecode; -+ XVBACreateDecodeProc CreateDecode; -+ XVBADestroyDecodeProc DestroyDecode; -+ XVBAStartDecodePictureProc StartDecodePicture; -+ XVBADecodePictureProc DecodePicture; -+ XVBAEndDecodePictureProc EndDecodePicture; -+ XVBASyncSurfaceProc SyncSurface; -+ XVBAGetSurfaceProc GetSurface; -+ XVBATransferSurfaceProc TransferSurface; -+}g_XVBA_vtable; -+ -+//----------------------------------------------------------------------------- -+//----------------------------------------------------------------------------- -+ -+CXVBAContext *CXVBAContext::m_context = 0; -+CCriticalSection CXVBAContext::m_section; -+Display *CXVBAContext::m_display = 0; -+void *CXVBAContext::m_dlHandle = 0; -+ -+CXVBAContext::CXVBAContext() -+{ -+ m_context = 0; -+// m_dlHandle = 0; -+ m_xvbaContext = 0; -+ m_refCount = 0; -+} -+ -+void CXVBAContext::Release() -+{ -+ CSingleLock lock(m_section); -+ -+ m_refCount--; -+ if (m_refCount <= 0) -+ { -+ Close(); -+ delete this; -+ m_context = 0; -+ } -+} -+ -+void CXVBAContext::Close() -+{ -+ CLog::Log(LOGNOTICE, "XVBA::Close - closing decoder context"); -+ -+ DestroyContext(); -+// if (m_dlHandle) -+// { -+// dlclose(m_dlHandle); -+// m_dlHandle = 0; -+// } -+} -+ -+bool CXVBAContext::EnsureContext(CXVBAContext **ctx) -+{ -+ CSingleLock lock(m_section); -+ -+ if (m_context) -+ { -+ m_context->m_refCount++; -+ *ctx = m_context; -+ return true; -+ } -+ -+ m_context = new CXVBAContext(); -+ *ctx = m_context; -+ { -+ CSingleLock gLock(g_graphicsContext); -+ if (!m_context->LoadSymbols() || !m_context->CreateContext()) -+ { -+ delete m_context; -+ m_context = 0; -+ return false; -+ } -+ } -+ -+ m_context->m_refCount++; -+ -+ *ctx = m_context; -+ return true; -+} -+ -+bool CXVBAContext::LoadSymbols() -+{ -+ if (!m_dlHandle) -+ { -+ m_dlHandle = dlopen(XVBA_LIBRARY, RTLD_LAZY); -+ if (!m_dlHandle) -+ { -+ const char* error = dlerror(); -+ if (!error) -+ error = "dlerror() returned NULL"; -+ -+ CLog::Log(LOGERROR,"XVBA::LoadSymbols: Unable to get handle to lib: %s", error); -+ return false; -+ } -+ } -+ else -+ return true; -+ -+#define INIT_PROC(PREFIX, PROC) do { \ -+ g_##PREFIX##_vtable.PROC = (PREFIX##PROC##Proc) \ -+ dlsym(m_dlHandle, #PREFIX #PROC); \ -+ } while (0) -+ -+#define INIT_PROC_CHECK(PREFIX, PROC) do { \ -+ dlerror(); \ -+ INIT_PROC(PREFIX, PROC); \ -+ if (dlerror()) { \ -+ dlclose(m_dlHandle); \ -+ m_dlHandle = NULL; \ -+ return false; \ -+ } \ -+ } while (0) -+ -+#define XVBA_INIT_PROC(PROC) INIT_PROC_CHECK(XVBA, PROC) -+ -+ XVBA_INIT_PROC(QueryExtension); -+ XVBA_INIT_PROC(CreateContext); -+ XVBA_INIT_PROC(DestroyContext); -+ XVBA_INIT_PROC(GetSessionInfo); -+ XVBA_INIT_PROC(CreateSurface); -+ XVBA_INIT_PROC(CreateGLSharedSurface); -+ XVBA_INIT_PROC(DestroySurface); -+ XVBA_INIT_PROC(CreateDecodeBuffers); -+ XVBA_INIT_PROC(DestroyDecodeBuffers); -+ XVBA_INIT_PROC(GetCapDecode); -+ XVBA_INIT_PROC(CreateDecode); -+ XVBA_INIT_PROC(DestroyDecode); -+ XVBA_INIT_PROC(StartDecodePicture); -+ XVBA_INIT_PROC(DecodePicture); -+ XVBA_INIT_PROC(EndDecodePicture); -+ XVBA_INIT_PROC(SyncSurface); -+ XVBA_INIT_PROC(GetSurface); -+ XVBA_INIT_PROC(TransferSurface); -+ -+#undef XVBA_INIT_PROC -+#undef INIT_PROC -+ -+ return true; -+} -+ -+bool CXVBAContext::CreateContext() -+{ -+ if (m_xvbaContext) -+ return true; -+ -+ CLog::Log(LOGNOTICE,"XVBA::CreateContext - creating decoder context"); -+ -+ Drawable window; -+ { CSingleLock lock(g_graphicsContext); -+ if (!m_display) -+ m_display = XOpenDisplay(NULL); -+ window = 0; -+ } -+ -+ int version; -+ if (!g_XVBA_vtable.QueryExtension(m_display, &version)) -+ return false; -+ CLog::Log(LOGNOTICE,"XVBA::CreateContext - opening xvba version: %i", version); -+ -+ // create XVBA Context -+ XVBA_Create_Context_Input contextInput; -+ XVBA_Create_Context_Output contextOutput; -+ contextInput.size = sizeof(contextInput); -+ contextInput.display = m_display; -+ contextInput.draw = window; -+ contextOutput.size = sizeof(contextOutput); -+ if(Success != g_XVBA_vtable.CreateContext(&contextInput, &contextOutput)) -+ { -+ CLog::Log(LOGERROR,"XVBA::CreateContext - failed to create context"); -+ return false; -+ } -+ m_xvbaContext = contextOutput.context; -+ -+ return true; -+} -+ -+void CXVBAContext::DestroyContext() -+{ -+ if (!m_xvbaContext) -+ return; -+ -+ g_XVBA_vtable.DestroyContext(m_xvbaContext); -+ m_xvbaContext = 0; -+// XCloseDisplay(m_display); -+} -+ -+void *CXVBAContext::GetContext() -+{ -+ return m_xvbaContext; -+} -+ -+//----------------------------------------------------------------------------- -+//----------------------------------------------------------------------------- -+ -+static unsigned int decoderId = 0; -+ -+CDecoder::CDecoder() : m_xvbaOutput(&m_inMsgEvent) -+{ -+ m_xvbaConfig.context = 0; -+ m_xvbaConfig.xvbaSession = 0; -+ m_xvbaConfig.videoSurfaces = &m_videoSurfaces; -+ m_xvbaConfig.videoSurfaceSec = &m_videoSurfaceSec; -+ m_xvbaConfig.apiSec = &m_apiSec; -+ -+ m_displayState = XVBA_OPEN; -+} -+ -+CDecoder::~CDecoder() -+{ -+ Close(); -+} -+ -+typedef struct { -+ unsigned int size; -+ unsigned int num_of_decodecaps; -+ XVBADecodeCap decode_caps_list[]; -+} XVBA_GetCapDecode_Output_Base; -+ -+void CDecoder::OnLostDevice() -+{ -+ CLog::Log(LOGNOTICE,"XVBA::OnLostDevice event"); -+ -+ CSingleLock lock(m_decoderSection); -+ DestroySession(); -+ if (m_xvbaConfig.context) -+ m_xvbaConfig.context->Release(); -+ m_xvbaConfig.context = 0; -+ -+ m_displayState = XVBA_LOST; -+ m_displayEvent.Reset(); -+} -+ -+void CDecoder::OnResetDevice() -+{ -+ CLog::Log(LOGNOTICE,"XVBA::OnResetDevice event"); -+ -+ CSingleLock lock(m_decoderSection); -+ if (m_displayState == XVBA_LOST) -+ { -+ m_displayState = XVBA_RESET; -+ lock.Leave(); -+ m_displayEvent.Set(); -+ } -+} -+ -+bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned int surfaces) -+{ -+ std::string Vendor = g_Windowing.GetRenderVendor(); -+ std::transform(Vendor.begin(), Vendor.end(), Vendor.begin(), ::tolower); -+ if (Vendor.compare(0, 3, "ati") != 0) -+ { -+ return false; -+ } -+ -+ m_decoderId = decoderId++; -+ -+ CLog::Log(LOGNOTICE,"(XVBA::Open) opening xvba decoder, id: %d", m_decoderId); -+ -+ if(avctx->coded_width == 0 -+ || avctx->coded_height == 0) -+ { -+ CLog::Log(LOGWARNING,"(XVBA) no width/height available, can't init"); -+ 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; -+ -+ if (!CXVBAContext::EnsureContext(&m_xvbaConfig.context)) -+ return false; -+ -+ // xvba get session info -+ XVBA_GetSessionInfo_Input sessionInput; -+ XVBA_GetSessionInfo_Output sessionOutput; -+ sessionInput.size = sizeof(sessionInput); -+ sessionInput.context = m_xvbaConfig.context->GetContext(); -+ sessionOutput.size = sizeof(sessionOutput); -+ if (Success != g_XVBA_vtable.GetSessionInfo(&sessionInput, &sessionOutput)) -+ { -+ CLog::Log(LOGERROR,"(XVBA) can't get session info"); -+ return false; -+ } -+ if (sessionOutput.getcapdecode_output_size == 0) -+ { -+ CLog::Log(LOGERROR,"(XVBA) session decode not supported"); -+ return false; -+ } -+ -+ // get decoder capabilities -+ XVBA_GetCapDecode_Input capInput; -+ XVBA_GetCapDecode_Output *capOutput; -+ capInput.size = sizeof(capInput); -+ capInput.context = m_xvbaConfig.context->GetContext(); -+ capOutput = (XVBA_GetCapDecode_Output *)calloc(sessionOutput.getcapdecode_output_size, 1); -+ capOutput->size = sessionOutput.getcapdecode_output_size; -+ if (Success != g_XVBA_vtable.GetCapDecode(&capInput, capOutput)) -+ { -+ CLog::Log(LOGERROR,"(XVBA) can't get decode capabilities"); -+ return false; -+ } -+ -+ int match = -1; -+ if (avctx->codec_id == CODEC_ID_H264) -+ { -+ // search for profile high -+ for (unsigned int i = 0; i < capOutput->num_of_decodecaps; ++i) -+ { -+ if (capOutput->decode_caps_list[i].capability_id == XVBA_H264 && -+ capOutput->decode_caps_list[i].flags == XVBA_H264_HIGH) -+ { -+ match = (int) i; -+ break; -+ } -+ } -+ if (match < 0) -+ { -+ CLog::Log(LOGNOTICE, "(XVBA::Open) - profile XVBA_H264_HIGH not found"); -+ } -+ } -+ else if (avctx->codec_id == CODEC_ID_VC1) -+ { -+ // search for profile advanced -+ for (unsigned int i = 0; i < capOutput->num_of_decodecaps; ++i) -+ { -+ if (capOutput->decode_caps_list[i].capability_id == XVBA_VC1 && -+ capOutput->decode_caps_list[i].flags == XVBA_VC1_ADVANCED) -+ { -+ match = (int) i; -+ break; -+ } -+ } -+ if (match < 0) -+ { -+ CLog::Log(LOGNOTICE, "(XVBA::Open) - profile XVBA_VC1_ADVANCED not found"); -+ } -+ } -+ else if (avctx->codec_id == CODEC_ID_MPEG2VIDEO) -+ { -+ // search for profile high -+ for (unsigned int i = 0; i < capOutput->num_of_decodecaps; ++i) -+ { -+ if (capOutput->decode_caps_list[i].capability_id == XVBA_MPEG2_VLD) -+ { -+ // XXX: uncomment when implemented -+ // match = (int) i; -+ // break; -+ } -+ } -+ if (match < 0) -+ { -+ CLog::Log(LOGNOTICE, "(XVBA::Open) - profile XVBA_MPEG2_VLD not found"); -+ } -+ } -+ else if (avctx->codec_id == CODEC_ID_WMV3) -+ { -+ // search for profile high -+ for (unsigned int i = 0; i < capOutput->num_of_decodecaps; ++i) -+ { -+ if (capOutput->decode_caps_list[i].capability_id == XVBA_VC1 && -+ capOutput->decode_caps_list[i].flags == XVBA_VC1_MAIN) -+ { -+ match = (int) i; -+ break; -+ } -+ } -+ if (match < 0) -+ { -+ CLog::Log(LOGNOTICE, "(XVBA::Open) - profile XVBA_VC1_MAIN not found"); -+ } -+ } -+ -+ if (match < 0) -+ { -+ free(capOutput); -+ return false; -+ } -+ -+ CLog::Log(LOGNOTICE,"(XVBA) using decoder capability id: %i flags: %i", -+ capOutput->decode_caps_list[match].capability_id, -+ capOutput->decode_caps_list[match].flags); -+ CLog::Log(LOGNOTICE,"(XVBA) using surface type: %x", -+ capOutput->decode_caps_list[match].surface_type); -+ -+ m_xvbaConfig.decoderCap = capOutput->decode_caps_list[match]; -+ -+ free(capOutput); -+ -+ // set some varables -+ m_xvbaConfig.xvbaSession = 0; -+ m_xvbaBufferPool.data_buffer = 0; -+ m_xvbaBufferPool.iq_matrix_buffer = 0; -+ m_xvbaBufferPool.picture_descriptor_buffer = 0; -+ m_presentPicture = 0; -+ m_xvbaConfig.numRenderBuffers = surfaces; -+ m_decoderThread = CThread::GetCurrentThreadId(); -+ m_speed = DVD_PLAYSPEED_NORMAL; -+ -+ if (1) //g_guiSettings.GetBool("videoplayer.usexvbasharedsurface")) -+ m_xvbaConfig.useSharedSurfaces = true; -+ else -+ m_xvbaConfig.useSharedSurfaces = false; -+ -+ m_displayState = XVBA_OPEN; -+ -+ // setup ffmpeg -+ avctx->thread_count = 1; -+ avctx->get_buffer = CDecoder::FFGetBuffer; -+ avctx->release_buffer = CDecoder::FFReleaseBuffer; -+ avctx->draw_horiz_band = CDecoder::FFDrawSlice; -+ avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; -+ -+ g_Windowing.Register(this); -+ return true; -+} -+ -+void CDecoder::Close() -+{ -+ CLog::Log(LOGNOTICE, "XVBA::Close - closing decoder, id: %d", m_decoderId); -+ -+ if (!m_xvbaConfig.context) -+ return; -+ -+ DestroySession(); -+ if (m_xvbaConfig.context) -+ m_xvbaConfig.context->Release(); -+ m_xvbaConfig.context = 0; -+ -+ while (!m_videoSurfaces.empty()) -+ { -+ xvba_render_state *render = m_videoSurfaces.back(); -+ if(render->buffers_alllocated > 0) -+ m_dllAvUtil.av_free(render->buffers); -+ m_videoSurfaces.pop_back(); -+ free(render); -+ } -+ -+ g_Windowing.Unregister(this); -+ m_dllAvUtil.Unload(); -+} -+ -+long CDecoder::Release() -+{ -+ // check if we should do some pre-cleanup here -+ // a second decoder might need resources -+ if (m_xvbaConfig.xvbaSession) -+ { -+ CSingleLock lock(m_decoderSection); -+ CLog::Log(LOGNOTICE,"XVBA::Release pre-cleanup"); -+ DestroySession(true); -+ } -+ return IHardwareDecoder::Release(); -+} -+ -+long CDecoder::ReleasePicReference() -+{ -+ return IHardwareDecoder::Release(); -+} -+ -+bool CDecoder::Supports(EINTERLACEMETHOD method) -+{ -+ if(method == VS_INTERLACEMETHOD_AUTO) -+ return true; -+ -+ if (1) //g_guiSettings.GetBool("videoplayer.usexvbasharedsurface")) -+ { -+ if (method == VS_INTERLACEMETHOD_XVBA) -+ return true; -+ } -+ -+ return false; -+} -+ -+void CDecoder::ResetState() -+{ -+ m_displayState = XVBA_OPEN; -+} -+ -+int CDecoder::Check(AVCodecContext* avctx) -+{ -+ EDisplayState state; -+ -+ { CSingleLock lock(m_decoderSection); -+ state = m_displayState; -+ } -+ -+ if (state == XVBA_LOST) -+ { -+ CLog::Log(LOGNOTICE,"XVBA::Check waiting for display reset event"); -+ if (!m_displayEvent.WaitMSec(2000)) -+ { -+ CLog::Log(LOGERROR, "XVBA::Check - device didn't reset in reasonable time"); -+ state = XVBA_RESET;; -+ } -+ else -+ { CSingleLock lock(m_decoderSection); -+ state = m_displayState; -+ } -+ } -+ if (state == XVBA_RESET || state == XVBA_ERROR) -+ { -+ CLog::Log(LOGNOTICE,"XVBA::Check - Attempting recovery"); -+ -+ CSingleLock gLock(g_graphicsContext); -+ CSingleLock lock(m_decoderSection); -+ -+ DestroySession(); -+ ResetState(); -+ CXVBAContext::EnsureContext(&m_xvbaConfig.context); -+ -+ if (state == XVBA_RESET) -+ return VC_FLUSHED; -+ else -+ return VC_ERROR; -+ } -+ return 0; -+} -+ -+void CDecoder::SetError(const char* function, const char* msg, int line) -+{ -+ CLog::Log(LOGERROR, "XVBA::%s - %s, line %d", function, msg, line); -+ CSingleLock lock(m_decoderSection); -+ m_displayState = XVBA_ERROR; -+} -+ -+bool CDecoder::CreateSession(AVCodecContext* avctx) -+{ -+ m_xvbaConfig.surfaceWidth = (avctx->coded_width+15) & ~15; -+ m_xvbaConfig.surfaceHeight = (avctx->coded_height+15) & ~15; -+ -+ m_xvbaConfig.vidWidth = avctx->width; -+ m_xvbaConfig.vidHeight = avctx->height; -+ -+ XVBA_Create_Decode_Session_Input sessionInput; -+ XVBA_Create_Decode_Session_Output sessionOutput; -+ -+ sessionInput.size = sizeof(sessionInput); -+ sessionInput.width = m_xvbaConfig.surfaceWidth; -+ sessionInput.height = m_xvbaConfig.surfaceHeight; -+ sessionInput.context = m_xvbaConfig.context->GetContext(); -+ sessionInput.decode_cap = &m_xvbaConfig.decoderCap; -+ sessionOutput.size = sizeof(sessionOutput); -+ -+ if (Success != g_XVBA_vtable.CreateDecode(&sessionInput, &sessionOutput)) -+ { -+ SetError(__FUNCTION__, "failed to create decoder session", __LINE__); -+ CLog::Log(LOGERROR, "Decoder failed with following stats: m_surfaceWidth %u, m_surfaceHeight %u," -+ " m_vidWidth %u, m_vidHeight %u, coded_width %d, coded_height %d", -+ m_xvbaConfig.surfaceWidth, -+ m_xvbaConfig.surfaceHeight, -+ m_xvbaConfig.vidWidth, -+ m_xvbaConfig.vidHeight, -+ avctx->coded_width, -+ avctx->coded_height); -+ return false; -+ } -+ m_xvbaConfig.xvbaSession = sessionOutput.session; -+ -+ // create decode buffers -+ XVBA_Create_DecodeBuff_Input bufferInput; -+ XVBA_Create_DecodeBuff_Output bufferOutput; -+ -+ bufferInput.size = sizeof(bufferInput); -+ bufferInput.session = m_xvbaConfig.xvbaSession; -+ bufferInput.buffer_type = XVBA_PICTURE_DESCRIPTION_BUFFER; -+ bufferInput.num_of_buffers = 1; -+ bufferOutput.size = sizeof(bufferOutput); -+ if (Success != g_XVBA_vtable.CreateDecodeBuffers(&bufferInput, &bufferOutput) -+ || bufferOutput.num_of_buffers_in_list != 1) -+ { -+ SetError(__FUNCTION__, "failed to create picture buffer", __LINE__); -+ return false; -+ } -+ m_xvbaBufferPool.picture_descriptor_buffer = bufferOutput.buffer_list; -+ -+ // data buffer -+ bufferInput.buffer_type = XVBA_DATA_BUFFER; -+ if (Success != g_XVBA_vtable.CreateDecodeBuffers(&bufferInput, &bufferOutput) -+ || bufferOutput.num_of_buffers_in_list != 1) -+ { -+ SetError(__FUNCTION__, "failed to create data buffer", __LINE__); -+ return false; -+ } -+ m_xvbaBufferPool.data_buffer = bufferOutput.buffer_list; -+ -+ // QO Buffer -+ bufferInput.buffer_type = XVBA_QM_BUFFER; -+ if (Success != g_XVBA_vtable.CreateDecodeBuffers(&bufferInput, &bufferOutput) -+ || bufferOutput.num_of_buffers_in_list != 1) -+ { -+ SetError(__FUNCTION__, "failed to create qm buffer", __LINE__); -+ return false; -+ } -+ m_xvbaBufferPool.iq_matrix_buffer = bufferOutput.buffer_list; -+ -+ -+ // initialize output -+ CSingleLock lock(g_graphicsContext); -+ m_xvbaConfig.stats = &m_bufferStats; -+ m_bufferStats.Reset(); -+ m_xvbaOutput.Start(); -+ Message *reply; -+ if (m_xvbaOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::INIT, -+ &reply, -+ 2000, -+ &m_xvbaConfig, -+ sizeof(m_xvbaConfig))) -+ { -+ bool success = reply->signal == COutputControlProtocol::ACC ? true : false; -+ reply->Release(); -+ if (!success) -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - vdpau output returned error", __FUNCTION__); -+ m_xvbaOutput.Dispose(); -+ return false; -+ } -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - failed to init output", __FUNCTION__); -+ m_xvbaOutput.Dispose(); -+ return false; -+ } -+ m_inMsgEvent.Reset(); -+ -+ return true; -+} -+ -+void CDecoder::DestroySession(bool precleanup /*= false*/) -+{ -+ // wait for unfinished decoding jobs -+ XbmcThreads::EndTime timer; -+ if (m_xvbaConfig.xvbaSession) -+ { -+ for (unsigned int i = 0; i < m_videoSurfaces.size(); ++i) -+ { -+ xvba_render_state *render = m_videoSurfaces[i]; -+ if (render->surface) -+ { -+ XVBA_Surface_Sync_Input syncInput; -+ XVBA_Surface_Sync_Output syncOutput; -+ syncInput.size = sizeof(syncInput); -+ syncInput.session = m_xvbaConfig.xvbaSession; -+ syncInput.surface = render->surface; -+ syncInput.query_status = XVBA_GET_SURFACE_STATUS; -+ syncOutput.size = sizeof(syncOutput); -+ timer.Set(1000); -+ while(!timer.IsTimePast()) -+ { -+ if (Success != g_XVBA_vtable.SyncSurface(&syncInput, &syncOutput)) -+ { -+ CLog::Log(LOGERROR,"XVBA::DestroySession - failed sync surface"); -+ break; -+ } -+ if (!(syncOutput.status_flags & XVBA_STILL_PENDING)) -+ break; -+ Sleep(10); -+ } -+ if (timer.IsTimePast()) -+ CLog::Log(LOGERROR,"XVBA::DestroySession - unfinished decoding job"); -+ } -+ } -+ } -+ -+ if (precleanup) -+ { -+ Message *reply; -+ if (m_xvbaOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::PRECLEANUP, -+ &reply, -+ 2000)) -+ { -+ bool success = reply->signal == COutputControlProtocol::ACC ? true : false; -+ reply->Release(); -+ if (!success) -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - pre-cleanup returned error", __FUNCTION__); -+ m_displayState = XVBA_ERROR; -+ } -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - pre-cleanup timed out", __FUNCTION__); -+ m_displayState = XVBA_ERROR; -+ } -+ } -+ else -+ m_xvbaOutput.Dispose(); -+ -+ XVBA_Destroy_Decode_Buffers_Input bufInput; -+ bufInput.size = sizeof(bufInput); -+ bufInput.num_of_buffers_in_list = 1; -+ bufInput.session = m_xvbaConfig.xvbaSession; -+ -+ for (unsigned int i=0; isurface) -+ { -+ g_XVBA_vtable.DestroySurface(render->surface); -+ render->surface = 0; -+ render->state = 0; -+ render->picture_descriptor = 0; -+ render->iq_matrix = 0; -+ } -+ } -+ -+ if (m_xvbaConfig.xvbaSession) -+ g_XVBA_vtable.DestroyDecode(m_xvbaConfig.xvbaSession); -+ m_xvbaConfig.xvbaSession = 0; -+} -+ -+bool CDecoder::IsSurfaceValid(xvba_render_state *render) -+{ -+ // find render state in queue -+ bool found(false); -+ unsigned int i; -+ for(i = 0; i < m_videoSurfaces.size(); ++i) -+ { -+ if(m_videoSurfaces[i] == render) -+ { -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ { -+ CLog::Log(LOGERROR,"%s - video surface not found", __FUNCTION__); -+ return false; -+ } -+ if (m_videoSurfaces[i]->surface == 0) -+ { -+ m_videoSurfaces[i]->state = 0; -+ return false; -+ } -+ -+ return true; -+} -+ -+bool CDecoder::EnsureDataControlBuffers(unsigned int num) -+{ -+ if (m_xvbaBufferPool.data_control_buffers.size() >= num) -+ return true; -+ -+ unsigned int missing = num - m_xvbaBufferPool.data_control_buffers.size(); -+ -+ XVBA_Create_DecodeBuff_Input bufferInput; -+ XVBA_Create_DecodeBuff_Output bufferOutput; -+ bufferInput.size = sizeof(bufferInput); -+ bufferInput.session = m_xvbaConfig.xvbaSession; -+ bufferInput.buffer_type = XVBA_DATA_CTRL_BUFFER; -+ bufferInput.num_of_buffers = 1; -+ bufferOutput.size = sizeof(bufferOutput); -+ -+ for (unsigned int i=0; iopaque; -+ CDecoder* xvba = (CDecoder*)ctx->GetHardware(); -+ unsigned int i; -+ -+ CSingleLock lock(xvba->m_decoderSection); -+ -+ xvba_render_state * render = NULL; -+ render = (xvba_render_state*)pic->data[0]; -+ if(!render) -+ { -+ CLog::Log(LOGERROR, "XVBA::FFReleaseBuffer - invalid context handle provided"); -+ return; -+ } -+ -+ for(i=0; i<4; i++) -+ pic->data[i]= NULL; -+ -+ // find render state in queue -+ if (!xvba->IsSurfaceValid(render)) -+ { -+ CLog::Log(LOGDEBUG, "XVBA::FFReleaseBuffer - ignoring invalid buffer"); -+ return; -+ } -+ -+ render->state &= ~FF_XVBA_STATE_USED_FOR_REFERENCE; -+} -+ -+void CDecoder::FFDrawSlice(struct AVCodecContext *avctx, -+ const AVFrame *src, int offset[4], -+ int y, int type, int height) -+{ -+ CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; -+ CDecoder* xvba = (CDecoder*)ctx->GetHardware(); -+ -+ CSingleLock lock(xvba->m_decoderSection); -+ -+ if(xvba->m_displayState != XVBA_OPEN) -+ return; -+ -+ if(src->linesize[0] || src->linesize[1] || src->linesize[2] -+ || offset[0] || offset[1] || offset[2]) -+ { -+ CLog::Log(LOGERROR, "XVBA::FFDrawSlice - invalid linesizes or offsets provided"); -+ return; -+ } -+ -+ xvba_render_state * render; -+ -+ render = (xvba_render_state*)src->data[0]; -+ if(!render) -+ { -+ CLog::Log(LOGERROR, "XVBA::FFDrawSlice - invalid context handle provided"); -+ return; -+ } -+ -+ // ffmpeg vc-1 decoder does not flush, make sure the data buffer is still valid -+ if (!xvba->IsSurfaceValid(render)) -+ { -+ CLog::Log(LOGWARNING, "XVBA::FFDrawSlice - ignoring invalid buffer"); -+ return; -+ } -+ -+ // decoding -+ XVBA_Decode_Picture_Start_Input startInput; -+ startInput.size = sizeof(startInput); -+ startInput.session = xvba->m_xvbaConfig.xvbaSession; -+ startInput.target_surface = render->surface; -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.StartDecodePicture(&startInput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed to start decoding", __LINE__); -+ return; -+ } -+ } -+ -+ XVBA_Decode_Picture_Input picInput; -+ picInput.size = sizeof(picInput); -+ picInput.session = xvba->m_xvbaConfig.xvbaSession; -+ XVBABufferDescriptor *list[2]; -+ picInput.buffer_list = list; -+ list[0] = xvba->m_xvbaBufferPool.picture_descriptor_buffer; -+ picInput.num_of_buffers_in_list = 1; -+ if (avctx->codec_id == CODEC_ID_H264) -+ { -+ list[1] = xvba->m_xvbaBufferPool.iq_matrix_buffer; -+ picInput.num_of_buffers_in_list = 2; -+ } -+ -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.DecodePicture(&picInput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed to decode picture 1", __LINE__); -+ return; -+ } -+ } -+ -+ if (!xvba->EnsureDataControlBuffers(render->num_slices)) -+ return; -+ -+ XVBADataCtrl *dataControl; -+ int location = 0; -+ xvba->m_xvbaBufferPool.data_buffer->data_size_in_buffer = 0; -+ for (unsigned int j = 0; j < render->num_slices; ++j) -+ { -+ int startCodeSize = 0; -+ uint8_t startCode[] = {0x00,0x00,0x01}; -+ if (avctx->codec_id == CODEC_ID_H264) -+ { -+ startCodeSize = 3; -+ memcpy((uint8_t*)xvba->m_xvbaBufferPool.data_buffer->bufferXVBA+location, -+ startCode, 3); -+ } -+ else if (avctx->codec_id == CODEC_ID_VC1 && -+ (memcmp(render->buffers[j].buffer, startCode, 3) != 0)) -+ { -+ startCodeSize = 4; -+ uint8_t sdf = 0x0d; -+ memcpy((uint8_t*)xvba->m_xvbaBufferPool.data_buffer->bufferXVBA+location, -+ startCode, 3); -+ memcpy((uint8_t*)xvba->m_xvbaBufferPool.data_buffer->bufferXVBA+location+3, -+ &sdf, 1); -+ } -+ // check for potential buffer overwrite -+ unsigned int bytesToCopy = render->buffers[j].size; -+ unsigned int freeBufferSize = xvba->m_xvbaBufferPool.data_buffer->buffer_size - -+ xvba->m_xvbaBufferPool.data_buffer->data_size_in_buffer; -+ if (bytesToCopy >= freeBufferSize) -+ { -+ xvba->SetError(__FUNCTION__, "bitstream buffer too large, maybe corrupted packet", __LINE__); -+ return; -+ } -+ memcpy((uint8_t*)xvba->m_xvbaBufferPool.data_buffer->bufferXVBA+location+startCodeSize, -+ render->buffers[j].buffer, -+ render->buffers[j].size); -+ dataControl = (XVBADataCtrl*)xvba->m_xvbaBufferPool.data_control_buffers[j]->bufferXVBA; -+ dataControl->SliceDataLocation = location; -+ dataControl->SliceBytesInBuffer = render->buffers[j].size+startCodeSize; -+ dataControl->SliceBitsInBuffer = dataControl->SliceBytesInBuffer * 8; -+ xvba->m_xvbaBufferPool.data_buffer->data_size_in_buffer += dataControl->SliceBytesInBuffer; -+ location += dataControl->SliceBytesInBuffer; -+ } -+ -+ int bufSize = xvba->m_xvbaBufferPool.data_buffer->data_size_in_buffer; -+ int padding = bufSize % 128; -+ if (padding) -+ { -+ padding = 128 - padding; -+ xvba->m_xvbaBufferPool.data_buffer->data_size_in_buffer += padding; -+ memset((uint8_t*)xvba->m_xvbaBufferPool.data_buffer->bufferXVBA+bufSize,0,padding); -+ } -+ -+ picInput.num_of_buffers_in_list = 2; -+ for (unsigned int i = 0; i < render->num_slices; ++i) -+ { -+ list[0] = xvba->m_xvbaBufferPool.data_buffer; -+ list[0]->data_offset = 0; -+ list[1] = xvba->m_xvbaBufferPool.data_control_buffers[i]; -+ list[1]->data_size_in_buffer = sizeof(*dataControl); -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.DecodePicture(&picInput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed to decode picture 2", __LINE__); -+ return; -+ } -+ } -+ } -+ XVBA_Decode_Picture_End_Input endInput; -+ endInput.size = sizeof(endInput); -+ endInput.session = xvba->m_xvbaConfig.xvbaSession; -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.EndDecodePicture(&endInput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed to decode picture 3", __LINE__); -+ return; -+ } -+ } -+ -+ // decode sync and error -+ XVBA_Surface_Sync_Input syncInput; -+ XVBA_Surface_Sync_Output syncOutput; -+ syncInput.size = sizeof(syncInput); -+ syncInput.session = xvba->m_xvbaConfig.xvbaSession; -+ syncInput.surface = render->surface; -+ syncInput.query_status = XVBA_GET_SURFACE_STATUS; -+ syncOutput.size = sizeof(syncOutput); -+ int64_t start = CurrentHostCounter(); -+ while (1) -+ { -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.SyncSurface(&syncInput, &syncOutput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed sync surface 1", __LINE__); -+ return; -+ } -+ } -+ if (!(syncOutput.status_flags & XVBA_STILL_PENDING)) -+ break; -+ if (CurrentHostCounter() - start > CurrentHostFrequency()) -+ { -+ xvba->SetError(__FUNCTION__, "timed out waiting for surface", __LINE__); -+ break; -+ } -+ usleep(100); -+ } -+ render->state |= FF_XVBA_STATE_DECODED; -+} -+ -+int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) -+{ -+ CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; -+ CDecoder* xvba = (CDecoder*)ctx->GetHardware(); -+ -+ pic->data[0] = -+ pic->data[1] = -+ pic->data[2] = -+ pic->data[3] = 0; -+ -+ pic->linesize[0] = -+ pic->linesize[1] = -+ pic->linesize[2] = -+ pic->linesize[3] = 0; -+ -+ CSingleLock lock(xvba->m_decoderSection); -+ -+ if(xvba->m_displayState != XVBA_OPEN) -+ return -1; -+ -+ if (xvba->m_xvbaConfig.xvbaSession == 0) -+ { -+ if (!xvba->CreateSession(avctx)) -+ return -1; -+ } -+ -+ xvba_render_state * render = NULL; -+ // find unused surface -+ { CSingleLock lock(xvba->m_videoSurfaceSec); -+ for(unsigned int i = 0; i < xvba->m_videoSurfaces.size(); ++i) -+ { -+ if(!(xvba->m_videoSurfaces[i]->state & (FF_XVBA_STATE_USED_FOR_REFERENCE | FF_XVBA_STATE_USED_FOR_RENDER))) -+ { -+ render = xvba->m_videoSurfaces[i]; -+ render->state = 0; -+ break; -+ } -+ } -+ } -+ -+ // create a new render state -+ if (render == NULL) -+ { -+ render = (xvba_render_state*)calloc(sizeof(xvba_render_state), 1); -+ if (render == NULL) -+ { -+ CLog::Log(LOGERROR, "XVBA::FFGetBuffer - calloc failed"); -+ return -1; -+ } -+ render->surface = 0; -+ render->buffers_alllocated = 0; -+ CSingleLock lock(xvba->m_videoSurfaceSec); -+ xvba->m_videoSurfaces.push_back(render); -+ } -+ -+ // create a new surface -+ if (render->surface == 0) -+ { -+ XVBA_Create_Surface_Input surfaceInput; -+ XVBA_Create_Surface_Output surfaceOutput; -+ surfaceInput.size = sizeof(surfaceInput); -+ surfaceInput.surface_type = xvba->m_xvbaConfig.decoderCap.surface_type; -+ surfaceInput.width = xvba->m_xvbaConfig.surfaceWidth; -+ surfaceInput.height = xvba->m_xvbaConfig.surfaceHeight; -+ surfaceInput.session = xvba->m_xvbaConfig.xvbaSession; -+ surfaceOutput.size = sizeof(surfaceOutput); -+ { CSingleLock lock(xvba->m_apiSec); -+ if (Success != g_XVBA_vtable.CreateSurface(&surfaceInput, &surfaceOutput)) -+ { -+ xvba->SetError(__FUNCTION__, "failed to create video surface", __LINE__); -+ return -1; -+ } -+ } -+ render->surface = surfaceOutput.surface; -+ render->picture_descriptor = (XVBAPictureDescriptor *)xvba->m_xvbaBufferPool.picture_descriptor_buffer->bufferXVBA; -+ render->iq_matrix = (XVBAQuantMatrixAvc *)xvba->m_xvbaBufferPool.iq_matrix_buffer->bufferXVBA; -+ CLog::Log(LOGDEBUG, "XVBA::FFGetBuffer - created video surface"); -+ } -+ -+ if (render == NULL) -+ return -1; -+ -+ pic->data[0] = (uint8_t*)render; -+ -+ pic->type= FF_BUFFER_TYPE_USER; -+ -+ render->state |= FF_XVBA_STATE_USED_FOR_REFERENCE; -+ render->state &= ~FF_XVBA_STATE_DECODED; -+ pic->reordered_opaque= avctx->reordered_opaque; -+ -+ return 0; -+} -+ -+int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) -+{ -+ int result = Check(avctx); -+ if (result) -+ return result; -+ -+ CSingleLock lock(m_decoderSection); -+ -+ if(frame) -+ { // we have a new frame from decoder -+ -+ xvba_render_state * render = (xvba_render_state*)frame->data[0]; -+ if(!render) -+ { -+ CLog::Log(LOGERROR, "XVBA::Decode - no render buffer"); -+ return VC_ERROR; -+ } -+ -+ // ffmpeg vc-1 decoder does not flush, make sure the data buffer is still valid -+ if (!IsSurfaceValid(render)) -+ { -+ CLog::Log(LOGWARNING, "XVBA::Decode - ignoring invalid buffer"); -+ return VC_BUFFER; -+ } -+ if (!(render->state & FF_XVBA_STATE_DECODED)) -+ { -+ CLog::Log(LOGDEBUG, "XVBA::Decode - ffmpeg failed"); -+ return VC_BUFFER; -+ } -+ -+ CSingleLock lock(m_videoSurfaceSec); -+ render->state |= FF_XVBA_STATE_USED_FOR_RENDER; -+ lock.Leave(); -+ -+ // send frame to output for processing -+ CXvbaDecodedPicture pic; -+ memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); -+ ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); -+ pic.render = render; -+ m_bufferStats.IncDecoded(); -+ m_xvbaOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); -+ -+ m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); -+ } -+ -+ int retval = 0; -+ uint16_t decoded, processed, render; -+ Message *msg; -+ while (m_xvbaOutput.m_controlPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputControlProtocol::ERROR) -+ { -+ m_displayState = XVBA_ERROR; -+ retval |= VC_ERROR; -+ } -+ msg->Release(); -+ } -+ -+ m_bufferStats.Get(decoded, processed, render); -+ -+ uint64_t startTime = CurrentHostCounter(); -+ while (!retval) -+ { -+ if (m_xvbaOutput.m_dataPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputDataProtocol::PICTURE) -+ { -+ if (m_presentPicture) -+ { -+ m_presentPicture->ReturnUnused(); -+ m_presentPicture = 0; -+ } -+ -+ m_presentPicture = *(CXvbaRenderPicture**)msg->data; -+ m_presentPicture->xvba = this; -+ m_bufferStats.DecRender(); -+ m_bufferStats.Get(decoded, processed, render); -+ retval |= VC_PICTURE; -+ } -+ msg->Release(); -+ } -+ else if (m_xvbaOutput.m_controlPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputControlProtocol::STATS) -+ { -+ m_bufferStats.Get(decoded, processed, render); -+ } -+ else -+ { -+ m_displayState = XVBA_ERROR; -+ retval |= VC_ERROR; -+ } -+ msg->Release(); -+ } -+ -+ if ((m_codecControl & DVP_FLAG_DRAIN)) -+ { -+ if (decoded + processed + render < 2) -+ { -+ retval |= VC_BUFFER; -+ } -+ } -+ else -+ { -+ if (decoded + processed + render < 4) -+ { -+ retval |= VC_BUFFER; -+ } -+ } -+ -+ if (!retval && !m_inMsgEvent.WaitMSec(2000)) -+ break; -+ } -+ uint64_t diff = CurrentHostCounter() - startTime; -+ if (retval & VC_PICTURE) -+ { -+ m_bufferStats.SetParams(diff, m_speed); -+ if (diff*1000/CurrentHostFrequency() > 50) -+ CLog::Log(LOGDEBUG,"XVBA::Decode long wait: %d", (int)((diff*1000)/CurrentHostFrequency())); -+ } -+ -+ if (!retval) -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - timed out waiting for output message", __FUNCTION__); -+ m_displayState = XVBA_ERROR; -+ retval |= VC_ERROR; -+ } -+ -+ return retval; -+ -+} -+ -+bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) -+{ -+ CSingleLock lock(m_decoderSection); -+ -+ if (m_displayState != XVBA_OPEN) -+ return false; -+ -+ *picture = m_presentPicture->DVDPic; -+ picture->xvba = m_presentPicture; -+ -+ return true; -+} -+ -+void CDecoder::ReturnRenderPicture(CXvbaRenderPicture *renderPic) -+{ -+ m_xvbaOutput.m_dataPort.SendOutMessage(COutputDataProtocol::RETURNPIC, &renderPic, sizeof(renderPic)); -+} -+ -+ -+//void CDecoder::CopyYV12(int index, uint8_t *dest) -+//{ -+// CSharedLock lock(m_decoderSection); -+// -+// { CSharedLock dLock(m_displaySection); -+// if(m_displayState != XVBA_OPEN) -+// return; -+// } -+// -+// if (!m_flipBuffer[index].outPic) -+// { -+// CLog::Log(LOGWARNING, "XVBA::Present: present picture is NULL"); -+// return; -+// } -+// -+// XVBA_GetSurface_Target target; -+// target.size = sizeof(target); -+// target.surfaceType = XVBA_YV12; -+// target.flag = XVBA_FRAME; -+// -+// XVBA_Get_Surface_Input input; -+// input.size = sizeof(input); -+// input.session = m_xvbaSession; -+// input.src_surface = m_flipBuffer[index].outPic->render->surface; -+// input.target_buffer = dest; -+// input.target_pitch = m_surfaceWidth; -+// input.target_width = m_surfaceWidth; -+// input.target_height = m_surfaceHeight; -+// input.target_parameter = target; -+// { CSingleLock lock(m_apiSec); -+// if (Success != g_XVBA_vtable.GetSurface(&input)) -+// { -+// CLog::Log(LOGERROR,"(XVBA::CopyYV12) failed to get surface"); -+// } -+// } -+//} -+ -+void CDecoder::Reset() -+{ -+ CSingleLock lock(m_decoderSection); -+ -+ if (!m_xvbaConfig.xvbaSession) -+ return; -+ -+ Message *reply; -+ if (m_xvbaOutput.m_controlPort.SendOutMessageSync(COutputControlProtocol::FLUSH, -+ &reply, -+ 2000)) -+ { -+ bool success = reply->signal == COutputControlProtocol::ACC ? true : false; -+ reply->Release(); -+ if (!success) -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - flush returned error", __FUNCTION__); -+ m_displayState = XVBA_ERROR; -+ } -+ else -+ m_bufferStats.Reset(); -+ } -+ else -+ { -+ CLog::Log(LOGERROR, "XVBA::%s - flush timed out", __FUNCTION__); -+ m_displayState = XVBA_ERROR; -+ } -+} -+ -+bool CDecoder::CanSkipDeint() -+{ -+ return m_bufferStats.CanSkipDeint(); -+} -+ -+void CDecoder::SetSpeed(int speed) -+{ -+ m_speed = speed; -+} -+ -+//----------------------------------------------------------------------------- -+// RenderPicture -+//----------------------------------------------------------------------------- -+ -+CXvbaRenderPicture* CXvbaRenderPicture::Acquire() -+{ -+ CSingleLock lock(*renderPicSection); -+ -+ if (refCount == 0) -+ xvba->Acquire(); -+ -+ refCount++; -+ return this; -+} -+ -+long CXvbaRenderPicture::Release() -+{ -+ CSingleLock lock(*renderPicSection); -+ -+ refCount--; -+ if (refCount > 0) -+ return refCount; -+ -+ lock.Leave(); -+ xvba->ReturnRenderPicture(this); -+ xvba->ReleasePicReference(); -+ -+ return refCount; -+} -+ -+void CXvbaRenderPicture::ReturnUnused() -+{ -+ { CSingleLock lock(*renderPicSection); -+ if (refCount > 0) -+ return; -+ } -+ if (xvba) -+ xvba->ReturnRenderPicture(this); -+} -+ -+//----------------------------------------------------------------------------- -+// Output -+//----------------------------------------------------------------------------- -+COutput::COutput(CEvent *inMsgEvent) : -+ CThread("XVBA Output Thread"), -+ m_controlPort("OutputControlPort", inMsgEvent, &m_outMsgEvent), -+ m_dataPort("OutputDataPort", inMsgEvent, &m_outMsgEvent) -+{ -+ m_inMsgEvent = inMsgEvent; -+ -+ CXvbaRenderPicture pic; -+ pic.renderPicSection = &m_bufferPool.renderPicSec; -+ pic.refCount = 0; -+ for (unsigned int i = 0; i < NUM_RENDER_PICS; i++) -+ { -+ m_bufferPool.allRenderPics.push_back(pic); -+ } -+ for (unsigned int i = 0; i < m_bufferPool.allRenderPics.size(); ++i) -+ { -+ m_bufferPool.freeRenderPics.push_back(&m_bufferPool.allRenderPics[i]); -+ } -+} -+ -+void COutput::Start() -+{ -+ Create(); -+} -+ -+COutput::~COutput() -+{ -+ Dispose(); -+ -+ m_bufferPool.freeRenderPics.clear(); -+ m_bufferPool.usedRenderPics.clear(); -+ m_bufferPool.allRenderPics.clear(); -+} -+ -+void COutput::Dispose() -+{ -+ CSingleLock lock(g_graphicsContext); -+ m_bStop = true; -+ m_outMsgEvent.Set(); -+ StopThread(); -+ m_controlPort.Purge(); -+ m_dataPort.Purge(); -+} -+ -+void COutput::OnStartup() -+{ -+ CLog::Log(LOGNOTICE, "COutput::OnStartup: Output Thread created"); -+} -+ -+void COutput::OnExit() -+{ -+ CLog::Log(LOGNOTICE, "COutput::OnExit: Output Thread terminated"); -+} -+ -+enum OUTPUT_STATES -+{ -+ O_TOP = 0, // 0 -+ O_TOP_ERROR, // 1 -+ O_TOP_UNCONFIGURED, // 2 -+ O_TOP_CONFIGURED, // 3 -+ O_TOP_CONFIGURED_WAIT_RES1, // 4 -+ O_TOP_CONFIGURED_WAIT_DEC, // 5 -+ O_TOP_CONFIGURED_STEP1, // 6 -+ O_TOP_CONFIGURED_WAIT_RES2, // 7 -+ O_TOP_CONFIGURED_STEP2, // 8 -+}; -+ -+int OUTPUT_parentStates[] = { -+ -1, -+ 0, //TOP_ERROR -+ 0, //TOP_UNCONFIGURED -+ 0, //TOP_CONFIGURED -+ 3, //TOP_CONFIGURED_WAIT_RES1 -+ 3, //TOP_CONFIGURED_WAIT_DEC -+ 3, //TOP_CONFIGURED_STEP1 -+ 3, //TOP_CONFIGURED_WAIT_RES2 -+ 3, //TOP_CONFIGURED_STEP2 -+}; -+ -+void COutput::StateMachine(int signal, Protocol *port, Message *msg) -+{ -+ for (int state = m_state; ; state = OUTPUT_parentStates[state]) -+ { -+ switch (state) -+ { -+ case O_TOP: // TOP -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::FLUSH: -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ case COutputControlProtocol::PRECLEANUP: -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ default: -+ break; -+ } -+ } -+ else if (port == &m_dataPort) -+ { -+ switch (signal) -+ { -+ case COutputDataProtocol::RETURNPIC: -+ CXvbaRenderPicture *pic; -+ pic = *((CXvbaRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ return; -+ default: -+ break; -+ } -+ } -+ { -+ std::string portName = port == NULL ? "timer" : port->portName; -+ CLog::Log(LOGWARNING, "COutput::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state); -+ } -+ return; -+ -+ case O_TOP_ERROR: -+ m_extTimeout = 1000; -+ break; -+ -+ case O_TOP_UNCONFIGURED: -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::INIT: -+ CXvbaConfig *data; -+ data = (CXvbaConfig*)msg->data; -+ if (data) -+ { -+ m_config = *data; -+ } -+ Init(); -+ EnsureBufferPool(); -+ if (!m_xvbaError) -+ { -+ m_state = O_TOP_CONFIGURED_WAIT_RES1; -+ msg->Reply(COutputControlProtocol::ACC); -+ } -+ else -+ { -+ m_state = O_TOP_ERROR; -+ msg->Reply(COutputControlProtocol::ERROR); -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED: -+ if (port == &m_controlPort) -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::FLUSH: -+ m_state = O_TOP_CONFIGURED_WAIT_RES1; -+ Flush(); -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ case COutputControlProtocol::PRECLEANUP: -+ m_state = O_TOP_UNCONFIGURED; -+ m_extTimeout = 10000; -+ Flush(); -+ ReleaseBufferPool(true); -+ msg->Reply(COutputControlProtocol::ACC); -+ return; -+ default: -+ break; -+ } -+ } -+ else if (port == &m_dataPort) -+ { -+ switch (signal) -+ { -+ case COutputDataProtocol::NEWFRAME: -+ CXvbaDecodedPicture *frame; -+ frame = (CXvbaDecodedPicture*)msg->data; -+ if (frame) -+ { -+ m_decodedPics.push(*frame); -+ m_extTimeout = 0; -+ } -+ return; -+ case COutputDataProtocol::RETURNPIC: -+ CXvbaRenderPicture *pic; -+ pic = *((CXvbaRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ m_controlPort.SendInMessage(COutputControlProtocol::STATS); -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_WAIT_RES1: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ if (!m_decodedPics.empty() && FindFreeSurface() >= 0 && !m_bufferPool.freeRenderPics.empty()) -+ { -+ m_state = O_TOP_CONFIGURED_WAIT_DEC; -+ m_bStateMachineSelfTrigger = true; -+ } -+ else -+ { -+ if (m_extTimeout != 0) -+ { -+ uint16_t decoded, processed, render; -+ m_config.stats->Get(decoded, processed, render); -+// CLog::Log(LOGDEBUG, "CVDPAU::COutput - timeout idle: decoded: %d, proc: %d, render: %d", decoded, processed, render); -+ } -+ m_extTimeout = 100; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_WAIT_DEC: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ if (IsDecodingFinished()) -+ { -+ m_state = O_TOP_CONFIGURED_STEP1; -+ m_bStateMachineSelfTrigger = true; -+ } -+ else -+ { -+ m_extTimeout = 1; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_STEP1: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ m_processPicture = m_decodedPics.front(); -+ m_decodedPics.pop(); -+ InitCycle(); -+ CXvbaRenderPicture *pic; -+ pic = ProcessPicture(); -+ if (pic) -+ { -+ m_config.stats->IncRender(); -+ m_dataPort.SendInMessage(COutputDataProtocol::PICTURE, &pic, sizeof(pic)); -+ } -+ if (m_xvbaError) -+ { -+ m_state = O_TOP_ERROR; -+ return; -+ } -+ if (m_deinterlacing && !m_deintSkip) -+ { -+ m_state = O_TOP_CONFIGURED_WAIT_RES2; -+ m_extTimeout = 0; -+ } -+ else -+ { -+ FiniCycle(); -+ m_state = O_TOP_CONFIGURED_WAIT_RES1; -+ m_extTimeout = 0; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_WAIT_RES2: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ if (FindFreeSurface() >= 0 && !m_bufferPool.freeRenderPics.empty()) -+ { -+ m_state = O_TOP_CONFIGURED_STEP2; -+ m_bStateMachineSelfTrigger = true; -+ } -+ else -+ { -+ if (m_extTimeout != 0) -+ { -+ uint16_t decoded, processed, render; -+ m_config.stats->Get(decoded, processed, render); -+ CLog::Log(LOGDEBUG, "CVDPAU::COutput - timeout idle: decoded: %d, proc: %d, render: %d", decoded, processed, render); -+ } -+ m_extTimeout = 100; -+ } -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ case O_TOP_CONFIGURED_STEP2: -+ if (port == NULL) // timeout -+ { -+ switch (signal) -+ { -+ case COutputControlProtocol::TIMEOUT: -+ CXvbaRenderPicture *pic; -+ m_deintStep = 1; -+ pic = ProcessPicture(); -+ if (pic) -+ { -+ m_config.stats->IncRender(); -+ m_dataPort.SendInMessage(COutputDataProtocol::PICTURE, &pic, sizeof(pic)); -+ } -+ if (m_xvbaError) -+ { -+ m_state = O_TOP_ERROR; -+ return; -+ } -+ FiniCycle(); -+ m_state = O_TOP_CONFIGURED_WAIT_RES1; -+ m_extTimeout = 0; -+ return; -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: // we are in no state, should not happen -+ CLog::Log(LOGERROR, "COutput::%s - no valid state: %d", __FUNCTION__, m_state); -+ return; -+ } -+ } // for -+} -+ -+void COutput::Process() -+{ -+ Message *msg; -+ Protocol *port; -+ bool gotMsg; -+ -+ m_state = O_TOP_UNCONFIGURED; -+ m_extTimeout = 1000; -+ m_bStateMachineSelfTrigger = false; -+ -+ while (!m_bStop) -+ { -+ gotMsg = false; -+ -+ if (m_bStateMachineSelfTrigger) -+ { -+ m_bStateMachineSelfTrigger = false; -+ // self trigger state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ // check control port -+ else if (m_controlPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_controlPort; -+ } -+ // check data port -+ else if (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ gotMsg = true; -+ port = &m_dataPort; -+ } -+ if (gotMsg) -+ { -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ continue; -+ } -+ -+ // wait for message -+ else if (m_outMsgEvent.WaitMSec(m_extTimeout)) -+ { -+ continue; -+ } -+ // time out -+ else -+ { -+ msg = m_controlPort.GetMessage(); -+ msg->signal = COutputControlProtocol::TIMEOUT; -+ port = 0; -+ // signal timeout to state machine -+ StateMachine(msg->signal, port, msg); -+ if (!m_bStateMachineSelfTrigger) -+ { -+ msg->Release(); -+ msg = NULL; -+ } -+ } -+ } -+ Flush(); -+ Uninit(); -+} -+ -+bool COutput::Init() -+{ -+ if (!CreateGlxContext()) -+ return false; -+ -+ m_xvbaError = false; -+ m_processPicture.render = 0; -+ m_fence = None; -+ -+ return true; -+} -+ -+bool COutput::Uninit() -+{ -+ ReleaseBufferPool(); -+ DestroyGlxContext(); -+ return true; -+} -+ -+void COutput::Flush() -+{ -+ while (!m_decodedPics.empty()) -+ { -+ CXvbaDecodedPicture pic = m_decodedPics.front(); -+ m_decodedPics.pop(); -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~(FF_XVBA_STATE_USED_FOR_RENDER | FF_XVBA_STATE_DECODED); -+ } -+ -+ if (m_processPicture.render) -+ { -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ m_processPicture.render->state &= ~(FF_XVBA_STATE_USED_FOR_RENDER | FF_XVBA_STATE_DECODED); -+ m_processPicture.render = 0; -+ } -+ -+ Message *msg; -+ while (m_dataPort.ReceiveOutMessage(&msg)) -+ { -+ if (msg->signal == COutputDataProtocol::NEWFRAME) -+ { -+ CXvbaDecodedPicture pic = *(CXvbaDecodedPicture*)msg->data; -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ if (pic.render) -+ pic.render->state &= ~(FF_XVBA_STATE_USED_FOR_RENDER | FF_XVBA_STATE_DECODED); -+ } -+ else if (msg->signal == COutputDataProtocol::RETURNPIC) -+ { -+ CXvbaRenderPicture *pic; -+ pic = *((CXvbaRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ } -+ msg->Release(); -+ } -+ -+ while (m_dataPort.ReceiveInMessage(&msg)) -+ { -+ if (msg->signal == COutputDataProtocol::PICTURE) -+ { -+ CXvbaRenderPicture *pic; -+ pic = *((CXvbaRenderPicture**)msg->data); -+ ProcessReturnPicture(pic); -+ } -+ } -+} -+ -+bool COutput::IsDecodingFinished() -+{ -+ // check for decoding to be finished -+ CXvbaDecodedPicture decodedPic = m_decodedPics.front(); -+ -+ XVBA_Surface_Sync_Input syncInput; -+ XVBA_Surface_Sync_Output syncOutput; -+ syncInput.size = sizeof(syncInput); -+ syncInput.session = m_config.xvbaSession; -+ syncInput.surface = decodedPic.render->surface; -+ syncInput.query_status = XVBA_GET_SURFACE_STATUS; -+ syncOutput.size = sizeof(syncOutput); -+ { CSingleLock lock(*(m_config.apiSec)); -+ if (Success != g_XVBA_vtable.SyncSurface(&syncInput, &syncOutput)) -+ { -+ CLog::Log(LOGERROR,"XVBA - failed sync surface"); -+ m_xvbaError = true; -+ return false; -+ } -+ } -+ if (!(syncOutput.status_flags & XVBA_STILL_PENDING)) -+ return true; -+ -+ return false; -+} -+ -+CXvbaRenderPicture* COutput::ProcessPicture() -+{ -+ CXvbaRenderPicture *retPic = 0; -+ -+ if (m_deintStep == 1) -+ { -+ if(m_field == XVBA_TOP_FIELD) -+ m_field = XVBA_BOTTOM_FIELD; -+ else -+ m_field = XVBA_TOP_FIELD; -+ } -+ -+ // find unused shared surface -+ unsigned int idx = FindFreeSurface(); -+ XvbaBufferPool::GLVideoSurface *glSurface = &m_bufferPool.glSurfaces[idx]; -+ glSurface->used = true; -+ glSurface->field = m_field; -+ glSurface->render = m_processPicture.render; -+ glSurface->transferred = false; -+ -+ int cmd = 0; -+ m_config.stats->GetCmd(cmd); -+ -+// if (m_fence) -+// glDeleteSync(m_fence); -+// m_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -+ -+ // transfer surface -+ XVBA_Transfer_Surface_Input transInput; -+ transInput.size = sizeof(transInput); -+ transInput.session = m_config.xvbaSession; -+ transInput.src_surface = m_processPicture.render->surface; -+ transInput.target_surface = glSurface->glSurface; -+ transInput.flag = m_field; -+ { CSingleLock lock(*(m_config.apiSec)); -+ if (Success != g_XVBA_vtable.TransferSurface(&transInput)) -+ { -+ CLog::Log(LOGERROR,"(XVBA) failed to transfer surface"); -+ m_xvbaError = true; -+ return retPic; -+ } -+ } -+ -+ // prepare render pic -+ retPic = m_bufferPool.freeRenderPics.front(); -+ m_bufferPool.freeRenderPics.pop_front(); -+ m_bufferPool.usedRenderPics.push_back(retPic); -+ retPic->sourceIdx = glSurface->id; -+ retPic->DVDPic = m_processPicture.DVDPic; -+ retPic->valid = true; -+ retPic->texture = glSurface->texture; -+ retPic->crop = CRect(0,0,0,0); -+ retPic->texWidth = m_config.surfaceWidth; -+ retPic->texHeight = m_config.surfaceHeight; -+ retPic->xvbaOutput = this; -+ -+ // set repeat pic for de-interlacing -+ if (m_deinterlacing) -+ { -+ if (m_deintStep == 1) -+ { -+ retPic->DVDPic.pts = DVD_NOPTS_VALUE; -+ retPic->DVDPic.dts = DVD_NOPTS_VALUE; -+ } -+ retPic->DVDPic.iRepeatPicture = 0.0; -+ } -+ -+ return retPic; -+} -+ -+void COutput::ProcessReturnPicture(CXvbaRenderPicture *pic) -+{ -+ std::deque::iterator it; -+ it = std::find(m_bufferPool.usedRenderPics.begin(), m_bufferPool.usedRenderPics.end(), pic); -+ if (it == m_bufferPool.usedRenderPics.end()) -+ { -+ CLog::Log(LOGWARNING, "COutput::ProcessReturnPicture - pic not found"); -+ return; -+ } -+ m_bufferPool.usedRenderPics.erase(it); -+ m_bufferPool.freeRenderPics.push_back(pic); -+ if (!pic->valid) -+ { -+ CLog::Log(LOGDEBUG, "COutput::%s - return of invalid render pic", __FUNCTION__); -+ return; -+ } -+ -+ xvba_render_state *render = m_bufferPool.glSurfaces[pic->sourceIdx].render; -+ if (render) -+ { -+ // check if video surface is referenced by other glSurfaces -+ bool referenced(false); -+ for (unsigned int i=0; isourceIdx) -+ continue; -+ if (m_bufferPool.glSurfaces[i].render == render) -+ { -+ referenced = true; -+ break; -+ } -+ } -+ if (m_processPicture.render == render) -+ referenced = true; -+ -+ // release video surface -+ if (!referenced) -+ { -+ CSingleLock lock(*m_config.videoSurfaceSec); -+ render->state &= ~(FF_XVBA_STATE_USED_FOR_RENDER | FF_XVBA_STATE_DECODED); -+ } -+ -+ // unreference video surface -+ m_bufferPool.glSurfaces[pic->sourceIdx].render = 0; -+ -+ m_bufferPool.glSurfaces[pic->sourceIdx].used = false; -+ return; -+ } -+} -+ -+int COutput::FindFreeSurface() -+{ -+ // find free shared surface -+ unsigned int i; -+ for (i = 0; i < m_bufferPool.glSurfaces.size(); ++i) -+ { -+ if (!m_bufferPool.glSurfaces[i].used) -+ break; -+ } -+ if (i == m_bufferPool.glSurfaces.size()) -+ return -1; -+ else -+ return i; -+} -+ -+void COutput::InitCycle() -+{ -+ uint64_t latency; -+ int speed; -+ m_config.stats->GetParams(latency, speed); -+ latency = (latency*1000)/CurrentHostFrequency(); -+ -+ m_config.stats->SetCanSkipDeint(false); -+ -+ EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode; -+ EINTERLACEMETHOD method = g_settings.m_currentVideoSettings.m_InterlaceMethod; -+ bool interlaced = m_processPicture.DVDPic.iFlags & DVP_FLAG_INTERLACED; -+ -+ if (mode == VS_DEINTERLACEMODE_FORCE || -+ (mode == VS_DEINTERLACEMODE_AUTO && interlaced)) -+ { -+ if((method == VS_INTERLACEMETHOD_AUTO && interlaced) -+ || method == VS_INTERLACEMETHOD_XVBA) -+ { -+ m_deinterlacing = true; -+ m_deintSkip = false; -+ m_config.stats->SetCanSkipDeint(true); -+ -+ if (m_processPicture.DVDPic.iFlags & DVP_FLAG_DROPDEINT) -+ { -+ m_deintSkip = true; -+ } -+ -+ // do only half deinterlacing -+ if (speed != DVD_PLAYSPEED_NORMAL || !g_graphicsContext.IsFullScreenVideo()) -+ { -+ m_config.stats->SetCanSkipDeint(false); -+ m_deintSkip = true; -+ } -+ -+ if(m_processPicture.DVDPic.iFlags & DVP_FLAG_TOP_FIELD_FIRST) -+ m_field = XVBA_TOP_FIELD; -+ else -+ m_field = XVBA_BOTTOM_FIELD; -+ } -+ } -+ else -+ { -+ m_deinterlacing = false; -+ m_field = XVBA_FRAME; -+ } -+ -+ m_processPicture.DVDPic.format = RENDER_FMT_XVBA; -+ m_processPicture.DVDPic.iFlags &= ~(DVP_FLAG_TOP_FIELD_FIRST | -+ DVP_FLAG_REPEAT_TOP_FIELD | -+ DVP_FLAG_INTERLACED); -+ m_processPicture.DVDPic.iWidth = m_config.vidWidth; -+ m_processPicture.DVDPic.iHeight = m_config.vidHeight; -+ -+ m_deintStep = 0; -+} -+ -+void COutput::FiniCycle() -+{ -+// { CSingleLock lock(*m_config.videoSurfaceSec); -+// m_processPicture.render->state &= ~FF_XVBA_STATE_USED_FOR_RENDER; -+// } -+ m_processPicture.render = 0; -+ m_config.stats->DecDecoded(); -+} -+ -+bool COutput::EnsureBufferPool() -+{ -+ if (m_config.useSharedSurfaces && m_bufferPool.glSurfaces.empty()) -+ { -+ GLenum textureTarget; -+ if (!glewIsSupported("GL_ARB_texture_non_power_of_two") && glewIsSupported("GL_ARB_texture_rectangle")) -+ { -+ textureTarget = GL_TEXTURE_RECTANGLE_ARB; -+ } -+ else -+ textureTarget = GL_TEXTURE_2D; -+ -+ // create shared surfaces -+ XvbaBufferPool::GLVideoSurface surface; -+ for (unsigned int i = 0; i < NUM_RENDER_PICS; ++i) -+ { -+ glEnable(textureTarget); -+ glGenTextures(1, &surface.texture); -+ glBindTexture(textureTarget, surface.texture); -+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4); -+ glTexImage2D(textureTarget, 0, GL_RGBA, m_config.surfaceWidth, m_config.surfaceHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); -+ -+ XVBA_Create_GLShared_Surface_Input surfInput; -+ XVBA_Create_GLShared_Surface_Output surfOutput; -+ surfInput.size = sizeof(surfInput); -+ surfInput.session = m_config.xvbaSession; -+ surfInput.gltexture = surface.texture; -+ surfInput.glcontext = m_glContext; -+ surfOutput.size = sizeof(surfOutput); -+ surfOutput.surface = 0; -+ if (Success != g_XVBA_vtable.CreateGLSharedSurface(&surfInput, &surfOutput)) -+ { -+ CLog::Log(LOGERROR,"(XVBA) failed to create shared surface"); -+ m_xvbaError = true; -+ break; -+ } -+ CLog::Log(LOGDEBUG, "XVBA::GetTexture - created shared surface"); -+ -+ surface.glSurface = surfOutput.surface; -+ surface.id = i; -+ surface.used = false; -+ surface.render = 0; -+ m_bufferPool.glSurfaces.push_back(surface); -+ } -+ glDisable(textureTarget); -+ } -+ -+ return true; -+} -+ -+void COutput::ReleaseBufferPool(bool precleanup /*= false*/) -+{ -+// if (m_fence) -+// { -+// uint64_t maxTimeout = 1000000000LL; -+// glClientWaitSync(m_fence, GL_SYNC_FLUSH_COMMANDS_BIT, maxTimeout); -+// glDeleteSync(m_fence); -+// m_fence = None; -+// } -+ -+ CSingleLock lock(m_bufferPool.renderPicSec); -+ -+ for (unsigned int i = 0; i < m_bufferPool.glSurfaces.size(); ++i) -+ { -+ if (m_bufferPool.glSurfaces[i].glSurface) -+ { -+ g_XVBA_vtable.DestroySurface(m_bufferPool.glSurfaces[i].glSurface); -+ m_bufferPool.glSurfaces[i].glSurface = 0; -+ } -+ if (m_bufferPool.glSurfaces[i].texture && !precleanup) -+ { -+ glDeleteTextures(1, &m_bufferPool.glSurfaces[i].texture); -+ m_bufferPool.glSurfaces[i].texture = 0; -+ } -+ m_bufferPool.glSurfaces[i].render = 0; -+ m_bufferPool.glSurfaces[i].used = true; -+ } -+ -+ if (!precleanup) -+ { -+ m_bufferPool.glSurfaces.clear(); -+ -+ // invalidate all used render pictures -+ for (unsigned int i = 0; i < m_bufferPool.usedRenderPics.size(); ++i) -+ { -+ m_bufferPool.usedRenderPics[i]->valid = false; -+ } -+ } -+} -+ -+void COutput::PreReleaseBufferPool() -+{ -+ CSingleLock lock(m_bufferPool.renderPicSec); -+ -+ if (m_config.useSharedSurfaces) -+ { -+ for (unsigned int i = 0; i < m_bufferPool.glSurfaces.size(); ++i) -+ { -+ if (!m_bufferPool.glSurfaces[i].used) -+ { -+ g_XVBA_vtable.DestroySurface(m_bufferPool.glSurfaces[i].glSurface); -+ glDeleteTextures(1, &m_bufferPool.glSurfaces[i].texture); -+ m_bufferPool.glSurfaces[i].glSurface = 0; -+ m_bufferPool.glSurfaces[i].used = true; -+ } -+ } -+ } -+} -+ -+bool COutput::CreateGlxContext() -+{ -+ GLXContext glContext; -+ -+ m_Display = g_Windowing.GetDisplay(); -+ glContext = g_Windowing.GetGlxContext(); -+ m_Window = g_Windowing.GetWindow(); -+ -+ // Get our window attribs. -+ XWindowAttributes wndattribs; -+ XGetWindowAttributes(m_Display, m_Window, &wndattribs); -+ -+ // Get visual Info -+ XVisualInfo visInfo; -+ visInfo.visualid = wndattribs.visual->visualid; -+ int nvisuals = 0; -+ XVisualInfo* visuals = XGetVisualInfo(m_Display, VisualIDMask, &visInfo, &nvisuals); -+ if (nvisuals != 1) -+ { -+ CLog::Log(LOGERROR, "XVBA::COutput::CreateGlxContext - could not find visual"); -+ return false; -+ } -+ visInfo = visuals[0]; -+ XFree(visuals); -+ -+ m_pixmap = XCreatePixmap(m_Display, -+ m_Window, -+ 192, -+ 108, -+ visInfo.depth); -+ if (!m_pixmap) -+ { -+ CLog::Log(LOGERROR, "XVBA::COutput::CreateGlxContext - Unable to create XPixmap"); -+ return false; -+ } -+ -+ // create gl pixmap -+ m_glPixmap = glXCreateGLXPixmap(m_Display, &visInfo, m_pixmap); -+ -+ if (!m_glPixmap) -+ { -+ CLog::Log(LOGINFO, "XVBA::COutput::CreateGlxContext - Could not create glPixmap"); -+ return false; -+ } -+ -+ m_glContext = glXCreateContext(m_Display, &visInfo, glContext, True); -+ -+ if (!glXMakeCurrent(m_Display, m_glPixmap, m_glContext)) -+ { -+ CLog::Log(LOGINFO, "XVBA::COutput::CreateGlxContext - Could not make Pixmap current"); -+ return false; -+ } -+ -+ CLog::Log(LOGNOTICE, "XVBA::COutput::CreateGlxContext - created context"); -+ return true; -+} -+ -+bool COutput::DestroyGlxContext() -+{ -+ if (m_glContext) -+ { -+ glXMakeCurrent(m_Display, None, NULL); -+ glXDestroyContext(m_Display, m_glContext); -+ } -+ m_glContext = 0; -+ -+ if (m_glPixmap) -+ glXDestroyPixmap(m_Display, m_glPixmap); -+ m_glPixmap = 0; -+ -+ if (m_pixmap) -+ XFreePixmap(m_Display, m_pixmap); -+ m_pixmap = 0; -+ -+ return true; -+} -+ -+#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 -@@ -0,0 +1,382 @@ -+/* -+ * Copyright (C) 2005-2011 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 "X11/Xlib.h" -+#include "amd/amdxvba.h" -+#include "DllAvCodec.h" -+#include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h" -+#include "threads/Thread.h" -+#include "threads/CriticalSection.h" -+#include "threads/SharedSection.h" -+#include "threads/Event.h" -+#include "guilib/DispResource.h" -+#include "guilib/Geometry.h" -+#include "libavcodec/xvba.h" -+#include "utils/ActorProtocol.h" -+#include "settings/VideoSettings.h" -+#include -+#include -+#include -+ -+using namespace Actor; -+ -+ -+namespace XVBA -+{ -+ -+//----------------------------------------------------------------------------- -+// XVBA data structs -+//----------------------------------------------------------------------------- -+ -+class CDecoder; -+class CXVBAContext; -+class COutput; -+ -+#define NUM_RENDER_PICS 9 -+ -+/** -+ * Buffer statistics used to control number of frames in queue -+ */ -+ -+class CXvbaBufferStats -+{ -+public: -+ uint16_t decodedPics; -+ uint16_t processedPics; -+ uint16_t renderPics; -+ uint64_t latency; // time decoder has waited for a frame, ideally there is no latency -+ int playSpeed; -+ bool canSkipDeint; -+ int processCmd; -+ -+ void IncDecoded() { CSingleLock l(m_sec); decodedPics++;} -+ void DecDecoded() { CSingleLock l(m_sec); decodedPics--;} -+ void IncProcessed() { CSingleLock l(m_sec); processedPics++;} -+ void DecProcessed() { CSingleLock l(m_sec); processedPics--;} -+ void IncRender() { CSingleLock l(m_sec); renderPics++;} -+ void DecRender() { CSingleLock l(m_sec); renderPics--;} -+ void Reset() { CSingleLock l(m_sec); decodedPics=0; processedPics=0;renderPics=0;latency=0;} -+ void Get(uint16_t &decoded, uint16_t &processed, uint16_t &render) {CSingleLock l(m_sec); decoded = decodedPics, processed=processedPics, render=renderPics;} -+ void SetParams(uint64_t time, int speed) { CSingleLock l(m_sec); latency = time; playSpeed = speed; } -+ void GetParams(uint64_t &lat, int &speed) { CSingleLock l(m_sec); lat = latency; speed = playSpeed; } -+ void SetCmd(int cmd) { CSingleLock l(m_sec); processCmd = cmd; } -+ void GetCmd(int &cmd) { CSingleLock l(m_sec); cmd = processCmd; processCmd = 0; } -+ void SetCanSkipDeint(bool canSkip) { CSingleLock l(m_sec); canSkipDeint = canSkip; } -+ bool CanSkipDeint() { CSingleLock l(m_sec); if (canSkipDeint) return true; else return false;} -+private: -+ CCriticalSection m_sec; -+}; -+ -+/** -+ * CXvbaConfig holds all configuration parameters needed by vdpau -+ * The structure is sent to the internal classes CMixer and COutput -+ * for init. -+ */ -+ -+struct CXvbaConfig -+{ -+ int surfaceWidth; -+ int surfaceHeight; -+ int vidWidth; -+ int vidHeight; -+ int outWidth; -+ int outHeight; -+ bool useSharedSurfaces; -+ -+ CXVBAContext *context; -+ XVBADecodeCap decoderCap; -+ void *xvbaSession; -+ std::vector *videoSurfaces; -+ CCriticalSection *videoSurfaceSec; -+ CCriticalSection *apiSec; -+ -+ CXvbaBufferStats *stats; -+ int numRenderBuffers; -+ uint32_t maxReferences; -+}; -+ -+/** -+ * Holds a decoded frame -+ * Input to COutput for further processing -+ */ -+struct CXvbaDecodedPicture -+{ -+ DVDVideoPicture DVDPic; -+ xvba_render_state *render; -+}; -+ -+/** -+ * Ready to render textures -+ * Sent from COutput back to CDecoder -+ * Objects are referenced by DVDVideoPicture and are sent -+ * to renderer -+ */ -+class CXvbaRenderPicture -+{ -+ friend class CDecoder; -+ friend class COutput; -+public: -+ DVDVideoPicture DVDPic; -+ int texWidth, texHeight; -+ CRect crop; -+ GLuint texture; -+ uint32_t sourceIdx; -+ bool valid; -+ CDecoder *xvba; -+ CXvbaRenderPicture* Acquire(); -+ long Release(); -+private: -+ void ReturnUnused(); -+ int refCount; -+ CCriticalSection *renderPicSection; -+ COutput *xvbaOutput; -+}; -+ -+//----------------------------------------------------------------------------- -+// Output -+//----------------------------------------------------------------------------- -+ -+/** -+ * Buffer pool holds allocated xvba and gl resources -+ * Embedded in COutput -+ */ -+struct XvbaBufferPool -+{ -+ struct GLVideoSurface -+ { -+ unsigned int id; -+ bool used; -+ bool transferred; -+ GLuint texture; -+ void *glSurface; -+ xvba_render_state *render; -+ XVBA_SURFACE_FLAG field; -+ }; -+ std::vector glSurfaces; -+ std::vector allRenderPics; -+ std::deque usedRenderPics; -+ std::deque freeRenderPics; -+ CCriticalSection renderPicSec; -+}; -+ -+class COutputControlProtocol : public Protocol -+{ -+public: -+ COutputControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ INIT, -+ FLUSH, -+ PRECLEANUP, -+ TIMEOUT, -+ }; -+ enum InSignal -+ { -+ ACC, -+ ERROR, -+ STATS, -+ }; -+}; -+ -+class COutputDataProtocol : public Protocol -+{ -+public: -+ COutputDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {}; -+ enum OutSignal -+ { -+ NEWFRAME = 0, -+ RETURNPIC, -+ }; -+ enum InSignal -+ { -+ PICTURE, -+ }; -+}; -+ -+/** -+ * COutput is embedded in CDecoder and embeds CMixer -+ * The class has its own OpenGl context which is shared with render thread -+ * COuput generated ready to render textures and passes them back to -+ * CDecoder -+ */ -+class COutput : private CThread -+{ -+public: -+ COutput(CEvent *inMsgEvent); -+ virtual ~COutput(); -+ void Start(); -+ void Dispose(); -+ COutputControlProtocol m_controlPort; -+ COutputDataProtocol m_dataPort; -+protected: -+ void OnStartup(); -+ void OnExit(); -+ void Process(); -+ void StateMachine(int signal, Protocol *port, Message *msg); -+ bool HasWork(); -+ bool IsDecodingFinished(); -+ CXvbaRenderPicture* ProcessPicture(); -+ void ProcessReturnPicture(CXvbaRenderPicture *pic); -+ int FindFreeSurface(); -+ void InitCycle(); -+ void FiniCycle(); -+ bool Init(); -+ bool Uninit(); -+ void Flush(); -+ bool CreateGlxContext(); -+ bool DestroyGlxContext(); -+ bool EnsureBufferPool(); -+ void ReleaseBufferPool(bool precleanup = false); -+ void PreReleaseBufferPool(); -+ CEvent m_outMsgEvent; -+ CEvent *m_inMsgEvent; -+ int m_state; -+ bool m_bStateMachineSelfTrigger; -+ -+ // extended state variables for state machine -+ int m_extTimeout; -+ bool m_xvbaError; -+ CXvbaConfig m_config; -+ XvbaBufferPool m_bufferPool; -+ Display *m_Display; -+ Window m_Window; -+ GLXContext m_glContext; -+ GLXWindow m_glWindow; -+ Pixmap m_pixmap; -+ GLXPixmap m_glPixmap; -+ GLsync m_fence; -+ std::queue m_decodedPics; -+ CXvbaDecodedPicture m_processPicture; -+ XVBA_SURFACE_FLAG m_field; -+ bool m_deinterlacing; -+ int m_deintStep; -+ bool m_deintSkip; -+}; -+ -+//----------------------------------------------------------------------------- -+// XVBA decoder -+//----------------------------------------------------------------------------- -+ -+class CXVBAContext -+{ -+public: -+ static bool EnsureContext(CXVBAContext **ctx); -+ void *GetContext(); -+ void Release(); -+private: -+ CXVBAContext(); -+ void Close(); -+ bool LoadSymbols(); -+ bool CreateContext(); -+ void DestroyContext(); -+ static CXVBAContext *m_context; -+ static CCriticalSection m_section; -+ static Display *m_display; -+ int m_refCount; -+ static void *m_dlHandle; -+ void *m_xvbaContext; -+}; -+ -+class CDecoder : public CDVDVideoCodecFFmpeg::IHardwareDecoder, -+ public IDispResource -+{ -+ friend class CXvbaRenderPicture; -+ -+public: -+ -+ struct pictureAge -+ { -+ int b_age; -+ int ip_age[2]; -+ }; -+ -+ enum EDisplayState -+ { XVBA_OPEN -+ , XVBA_RESET -+ , XVBA_LOST -+ , XVBA_ERROR -+ }; -+ -+ CDecoder(); -+ virtual ~CDecoder(); -+ virtual void OnLostDevice(); -+ virtual void OnResetDevice(); -+ -+ virtual bool Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned int surfaces = 0); -+ virtual int Decode (AVCodecContext* avctx, AVFrame* frame); -+ virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); -+ virtual void Reset(); -+ virtual void Close(); -+ virtual int Check(AVCodecContext* avctx); -+ virtual long Release(); -+ virtual const std::string Name() { return "xvba"; } -+ virtual bool CanSkipDeint(); -+ virtual void SetSpeed(int speed); -+ -+ bool Supports(EINTERLACEMETHOD method); -+ long ReleasePicReference(); -+ -+protected: -+ bool CreateSession(AVCodecContext* avctx); -+ void DestroySession(bool precleanup = false); -+ bool EnsureDataControlBuffers(unsigned int num); -+ void ResetState(); -+ void SetError(const char* function, const char* msg, int line); -+ bool IsSurfaceValid(xvba_render_state *render); -+ void ReturnRenderPicture(CXvbaRenderPicture *renderPic); -+ -+ // callbacks for ffmpeg -+ static void FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic); -+ static void FFDrawSlice(struct AVCodecContext *avctx, -+ const AVFrame *src, int offset[4], -+ int y, int type, int height); -+ static int FFGetBuffer(AVCodecContext *avctx, AVFrame *pic); -+ -+ DllAvUtil m_dllAvUtil; -+ CCriticalSection m_decoderSection; -+ CEvent m_displayEvent; -+ EDisplayState m_displayState; -+ CXvbaConfig m_xvbaConfig; -+ std::vector m_videoSurfaces; -+ CCriticalSection m_apiSec, m_videoSurfaceSec; -+ ThreadIdentifier m_decoderThread; -+ -+ unsigned int m_decoderId; -+ struct XVBABufferPool -+ { -+ XVBABufferDescriptor *picture_descriptor_buffer; -+ XVBABufferDescriptor *iq_matrix_buffer; -+ XVBABufferDescriptor *data_buffer; -+ std::vector data_control_buffers; -+ }; -+ XVBABufferPool m_xvbaBufferPool; -+ -+ COutput m_xvbaOutput; -+ CXvbaBufferStats m_bufferStats; -+ CEvent m_inMsgEvent; -+ CXvbaRenderPicture *m_presentPicture; -+ -+ int m_speed; -+ int m_codecControl; -+}; -+ -+} -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.8.1.6 - - -From 4e72c3c72b1569934677c2ab97e0aa6e5875abfd Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Sun, 4 Nov 2012 16:24:10 +0100 -Subject: [PATCH 64/94] 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.8.1.6 - - -From 4eb0a1c62e0f2d6766f3364bec110ceb989de328 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 16 Jun 2012 12:46:30 +0200 -Subject: [PATCH 65/94] 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.8.1.6 - - -From b40ec058cfcfa0470d38d54062844285a8866ca4 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 23 Aug 2012 19:39:49 +0200 -Subject: [PATCH 66/94] 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.8.1.6 - - -From f6cefb6c48c29b0d8fa8154b4dda24f318bc5208 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 67/94] dvdplayer: observe pts counter overflow - ---- - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 198 ++++++++++++++++++++- - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 3 + - 2 files changed, 200 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -index 35d0fc5..97d963a 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp -@@ -18,13 +18,13 @@ - * - */ - --#include "system.h" - #ifndef __STDC_CONSTANT_MACROS - #define __STDC_CONSTANT_MACROS - #endif - #ifndef __STDC_LIMIT_MACROS - #define __STDC_LIMIT_MACROS - #endif -+#include "system.h" - #ifdef _LINUX - #include "stdint.h" - #endif -@@ -499,6 +499,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) - AddStream(i); - } - -+ m_bPtsWrapChecked = false; -+ m_bPtsWrap = false; -+ - return true; - } - -@@ -603,6 +606,12 @@ double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) - if (pts == (int64_t)AV_NOPTS_VALUE) - return DVD_NOPTS_VALUE; - -+ if (m_bPtsWrap) -+ { -+ if (pts < m_iStartTime && pts < m_iEndTime) -+ pts += m_iMaxTime; -+ } -+ - // do calculations in floats as they can easily overflow otherwise - // we don't care for having a completly exact timestamp anyway - double timestamp = (double)pts * num / den; -@@ -725,6 +734,24 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() - pkt.pts = AV_NOPTS_VALUE; - } - -+ if (!m_bPtsWrapChecked && m_pFormatContext->iformat->flags & AVFMT_TS_DISCONT) -+ { -+ int defaultStream = m_dllAvFormat.av_find_default_stream_index(m_pFormatContext); -+ int64_t duration = m_pFormatContext->streams[defaultStream]->duration * 1.5; -+ m_iMaxTime = 1LL<streams[defaultStream]->pts_wrap_bits; -+ m_iStartTime = m_pFormatContext->streams[defaultStream]->start_time; -+ if (m_iStartTime != DVD_NOPTS_VALUE) -+ { -+ m_iEndTime = (m_iStartTime + duration) & ~m_iMaxTime; -+ if (m_iEndTime < m_iStartTime) -+ { -+ CLog::Log(LOGNOTICE,"CDVDDemuxFFmpeg::Read - file contains pts overflow"); -+ m_bPtsWrap = true; -+ } -+ } -+ m_bPtsWrapChecked = true; -+ } -+ - // copy contents into our own packet - pPacket->iSize = pkt.size; - -@@ -839,10 +866,20 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) - int ret; - { - CSingleLock lock(m_critSection); -+ - ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); - - if(ret >= 0) -+ { - UpdateCurrentPTS(); -+ -+ // seek may fail silently on streams which allow discontinuity -+ // if current timestamp is way off asume a pts overflow and try bisect seek -+ if (m_bPtsWrap && fabs(time - m_iCurrentPts/1000) > 10000) -+ { -+ ret = SeekTimeDiscont(seek_pts, backwords) ? 1 : -1; -+ } -+ } - } - - if(m_iCurrentPts == DVD_NOPTS_VALUE) -@@ -861,6 +898,165 @@ bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) - return (ret >= 0); - } - -+bool CDVDDemuxFFmpeg::SeekTimeDiscont(int64_t pts, bool backwards) -+{ -+ // this code is taken from ffmpeg function ff_gen_search -+ // it is modified to assume a pts overflow if timestamp < start_time -+ if (!m_pFormatContext->iformat->read_timestamp) -+ return false; -+ -+ int defaultStream = m_dllAvFormat.av_find_default_stream_index(m_pFormatContext); -+ -+ if (defaultStream < 0) -+ { -+ return false; -+ } -+ -+ // timestamp for default must be expressed in AV_TIME_BASE units -+ pts = m_dllAvUtil.av_rescale_rnd(pts, m_pFormatContext->streams[defaultStream]->time_base.den, -+ AV_TIME_BASE * (int64_t)m_pFormatContext->streams[defaultStream]->time_base.num, -+ AV_ROUND_NEAR_INF); -+ -+ int64_t pos, pos_min, pos_max, pos_limit, ts, ts_min, ts_max; -+ int64_t start_pos, filesize; -+ int no_change; -+ -+ pos_min = m_pFormatContext->data_offset; -+ ts_min = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos_min, INT64_MAX); -+ if (ts_min == AV_NOPTS_VALUE) -+ return false; -+ -+ if(ts_min >= pts) -+ { -+ pos = pos_min; -+ return true; -+ } -+ -+ int step= 1024; -+ filesize = m_pInput->GetLength(); -+ pos_max = filesize - 1; -+ do -+ { -+ pos_max -= step; -+ ts_max = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos_max, pos_max + step); -+ step += step; -+ }while (ts_max == AV_NOPTS_VALUE && pos_max >= step); -+ -+ if (ts_max == AV_NOPTS_VALUE) -+ return false; -+ -+ if (ts_max < m_iStartTime && ts_max < m_iEndTime) -+ ts_max += m_iMaxTime; -+ -+ for(;;) -+ { -+ int64_t tmp_pos = pos_max + 1; -+ int64_t tmp_ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &tmp_pos, INT64_MAX); -+ if(tmp_ts == AV_NOPTS_VALUE) -+ break; -+ -+ if (tmp_ts < m_iStartTime && tmp_ts < m_iEndTime) -+ tmp_ts += m_iMaxTime; -+ -+ ts_max = tmp_ts; -+ pos_max = tmp_pos; -+ if (tmp_pos >= filesize) -+ break; -+ } -+ pos_limit = pos_max; -+ -+ if(ts_max <= pts) -+ { -+ bool ret = SeekByte(pos_max); -+ if (ret) -+ { -+ m_iCurrentPts = ConvertTimestamp(ts_max, m_pFormatContext->streams[defaultStream]->time_base.den, -+ m_pFormatContext->streams[defaultStream]->time_base.num); -+ } -+ return ret; -+ } -+ -+ if(ts_min > ts_max) -+ { -+ return false; -+ } -+ else if (ts_min == ts_max) -+ { -+ pos_limit = pos_min; -+ } -+ -+ no_change=0; -+ while (pos_min < pos_limit) -+ { -+ if (no_change == 0) -+ { -+ int64_t approximate_keyframe_distance= pos_max - pos_limit; -+ // interpolate position (better than dichotomy) -+ pos = m_dllAvUtil.av_rescale_rnd(pts - ts_min, pos_max - pos_min, -+ ts_max - ts_min, AV_ROUND_NEAR_INF) -+ + pos_min - approximate_keyframe_distance; -+ } -+ else if (no_change == 1) -+ { -+ // bisection, if interpolation failed to change min or max pos last time -+ pos = (pos_min + pos_limit) >> 1; -+ } -+ else -+ { -+ /* linear search if bisection failed, can only happen if there -+ are very few or no keyframes between min/max */ -+ pos = pos_min; -+ } -+ if (pos <= pos_min) -+ pos= pos_min + 1; -+ else if (pos > pos_limit) -+ pos= pos_limit; -+ start_pos = pos; -+ -+ ts = m_pFormatContext->iformat->read_timestamp(m_pFormatContext, defaultStream, -+ &pos, INT64_MAX); -+ if (pos == pos_max) -+ no_change++; -+ else -+ no_change=0; -+ -+ if (ts == AV_NOPTS_VALUE) -+ { -+ return false; -+ } -+ -+ if (ts < m_iStartTime && ts < m_iEndTime) -+ ts += m_iMaxTime; -+ -+ if (pts <= ts) -+ { -+ pos_limit = start_pos - 1; -+ pos_max = pos; -+ ts_max = ts; -+ } -+ if (pts >= ts) -+ { -+ pos_min = pos; -+ ts_min = ts; -+ } -+ } -+ -+ pos = (backwards) ? pos_min : pos_max; -+ ts = (backwards) ? ts_min : ts_max; -+ -+ bool ret = SeekByte(pos); -+ if (ret) -+ { -+ m_iCurrentPts = ConvertTimestamp(ts, m_pFormatContext->streams[defaultStream]->time_base.den, -+ m_pFormatContext->streams[defaultStream]->time_base.num); -+ } -+ -+ return ret; -+} -+ - bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) - { - CSingleLock lock(m_critSection); -diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -index acef490..72ecc52 100644 ---- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h -@@ -97,6 +97,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); -+ bool SeekTimeDiscont(int64_t pts, bool backwards); - bool SeekByte(int64_t pos); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); -@@ -141,5 +142,7 @@ class CDVDDemuxFFmpeg : public CDVDDemux - unsigned m_program; - XbmcThreads::EndTime m_timeout; - -+ bool m_bPtsWrap, m_bPtsWrapChecked; -+ int64_t m_iStartTime, m_iMaxTime, m_iEndTime; - }; - --- -1.8.1.6 - - -From 6451b4fbb7e662df575f3295479715fd35beb178 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 68/94] 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.8.1.6 - - -From d5540e46e039d6aa850a3134ad805f2a5fb1c947 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 69/94] 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 --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.8.1.6 - - -From c1360c2b0e3b49eb36a46425d3cc4231780d5156 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 11 Oct 2012 13:01:08 +0200 -Subject: [PATCH 70/94] dvdplayer: correct determination if video is playing - ---- - xbmc/cores/dvdplayer/DVDPlayer.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 21414ab..f7ede88 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -2395,6 +2395,7 @@ bool CDVDPlayer::HasVideo() const - return m_HasVideo; - } - -+ - bool CDVDPlayer::HasAudio() const - { - return m_HasAudio; --- -1.8.1.6 - - -From a72371b3b3fab502a346a2e80896514be65780ba Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 71/94] 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 - class CDVDMsgPlayerSeek : public CDVDMsg - { - public: -- CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false) -+ CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false, bool sync = true) - : CDVDMsg(PLAYER_SEEK) - , m_time(time) - , m_backward(backward) -@@ -226,6 +226,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg - , m_accurate(accurate) - , m_restore(restore) - , m_trickplay(trickplay) -+ , m_sync(sync) - {} - int GetTime() { return m_time; } - bool GetBackward() { return m_backward; } -@@ -233,6 +234,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg - bool GetAccurate() { return m_accurate; } - bool GetRestore() { return m_restore; } - bool GetTrickPlay() { return m_trickplay; } -+ bool GetSync() { return m_sync; } - private: - int m_time; - bool m_backward; -@@ -240,6 +242,7 @@ class CDVDMsgPlayerSeek : public CDVDMsg - bool m_accurate; - bool m_restore; // whether to restore any EDL cut time - bool m_trickplay; -+ bool m_sync; - }; - - class CDVDMsgPlayerSeekChapter : public CDVDMsg -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index f7ede88..2929db5 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayer.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1553,11 +1553,13 @@ void CDVDPlayer::HandlePlaySpeed() - } - else if (m_CurrentVideo.id >= 0 - && (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file -- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() -+ && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200)) -+ && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE) - && m_SpeedState.lasttime != GetTime()) - { - m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts(); - m_SpeedState.lasttime = GetTime(); -+ m_SpeedState.lastabstime = CDVDClock::GetAbsoluteClock(); - // check how much off clock video is when ff/rw:ing - // a problem here is that seeking isn't very accurate - // and since the clock will be resynced after seek -@@ -1576,7 +1578,7 @@ void CDVDPlayer::HandlePlaySpeed() - { - CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up"); - int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL); -- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true)); -+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true, false)); - } - } - } -@@ -2040,7 +2042,7 @@ void CDVDPlayer::HandleMessages() - if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward())) - CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time); - } -- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate()); -+ FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync()); - } - else - CLog::Log(LOGWARNING, "error while seeking"); -@@ -2178,9 +2180,10 @@ void CDVDPlayer::HandleMessages() - double offset; - offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; - offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; -+ offset = DVD_TIME_TO_MSEC(offset); - if(offset > 1000) offset = 1000; - if(offset < -1000) offset = -1000; -- m_State.time += DVD_TIME_TO_MSEC(offset); -+ m_State.time += offset; - m_State.timestamp = CDVDClock::GetAbsoluteClock(); - } - -@@ -2196,7 +2199,8 @@ void CDVDPlayer::HandleMessages() - // do a seek after rewind, clock is not in sync with current pts - if (m_playSpeed < 0 && speed >= 0) - { -- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true)); -+ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset); -+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true)); - } - - // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE -@@ -3145,7 +3149,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) - return true; - } - --void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) -+void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync) - { - double startpts; - if(accurate) -@@ -3157,19 +3161,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) - if(startpts != DVD_NOPTS_VALUE) - startpts -= m_offset_pts; - -- m_CurrentAudio.inited = false; -+ if (sync) -+ { -+ m_CurrentAudio.inited = false; -+ m_CurrentVideo.inited = false; -+ m_CurrentSubtitle.inited = false; -+ m_CurrentTeletext.inited = false; -+ } -+ - m_CurrentAudio.dts = DVD_NOPTS_VALUE; - m_CurrentAudio.startpts = startpts; - -- m_CurrentVideo.inited = false; - m_CurrentVideo.dts = DVD_NOPTS_VALUE; - m_CurrentVideo.startpts = startpts; - -- m_CurrentSubtitle.inited = false; - m_CurrentSubtitle.dts = DVD_NOPTS_VALUE; - m_CurrentSubtitle.startpts = startpts; - -- m_CurrentTeletext.inited = false; - m_CurrentTeletext.dts = DVD_NOPTS_VALUE; - m_CurrentTeletext.startpts = startpts; - -@@ -3213,7 +3221,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) - m_CurrentTeletext.started = false; - } - -- if(pts != DVD_NOPTS_VALUE) -+ if(pts != DVD_NOPTS_VALUE && sync) - m_clock.Discontinuity(pts); - UpdatePlayState(0); - } -diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h -index ebe0ce8..d0a8bbc 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 - bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset); - - -- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true); -+ void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true); - - void HandleMessages(); - void HandlePlaySpeed(); -@@ -359,8 +359,9 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer - int m_playSpeed; - struct SSpeedState - { -- double lastpts; // holds last display pts during ff/rw operations -- double lasttime; -+ double lastpts; // holds last display pts during ff/rw operations -+ int64_t lasttime; -+ double lastabstime; - } m_SpeedState; - - int m_errorCount; -diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 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) - - if( m_speed < 0 ) - { -- double decoderPts = m_droppingStats.m_lastDecoderPts; -+ double inputPts = m_droppingStats.m_lastPts; - double renderPts = m_droppingStats.m_lastRenderPts; - if (pts > renderPts) - { -- if (decoderPts >= 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.8.1.6 - - -From c08ecf582faf1b75494f059f52f89fa8889ef70a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 72/94] 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; screennum -Date: Sun, 2 Dec 2012 15:46:55 +0100 -Subject: [PATCH 73/94] 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__); -+ - RESOLUTION_INFO res; - unsigned int i; - bool found(false); --- -1.8.1.6 - - -From 73bb3c6b3ab54579e37fc1d282ee6749a542578f Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 74/94] 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); - } - - // m_SDLSurface is free()'d by SDL_Quit(). --- -1.8.1.6 - - -From fd28b5d6cbb3f3e6e465b6c259793830b236c33e 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/94] 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); - - TiXmlElement *pRootElement = xmlDoc.RootElement(); -- if (strcasecmp(pRootElement->Value(), "screen") != screennum) -+ if (atoi(pRootElement->Attribute("id")) != screennum) - { - // TODO ERROR - return false; --- -1.8.1.6 - - -From 6face143a4f3c50b4a173fab49df3036eca044f0 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 20 Dec 2012 19:35:38 +0100 -Subject: [PATCH 76/94] 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.8.1.6 - - -From 23667e3eaacb154198ebf6c99b41633af25ad31a Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 77/94] 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) - { --- -1.8.1.6 - - -From 117af2d5845fdbe7aef7952bffe4939b78f96483 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 78/94] 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.8.1.6 - - -From 983313a0eacdcf1a86ef95a7362388c0efad2564 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 79/94] 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() - #if defined(_WIN32) - ShowWindow(g_hWnd,SW_RESTORE); - SetForegroundWindow(g_hWnd); --#elif !defined(TARGET_DARWIN_OSX) -- // Hack to reclaim focus, thus rehiding system mouse pointer. -- // Surely there's a better way? -- g_graphicsContext.ToggleFullScreenRoot(); -- g_graphicsContext.ToggleFullScreenRoot(); - #endif - } - g_application.ResetScreenSaver(); --- -1.8.1.6 - - -From 40654c21bfe1647b1d5ffc26ef31694b73bd8ce8 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 80/94] 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.8.1.6 - - -From 5720e3242b3e70472b1f6ff3088190bf5709344e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 81/94] 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.8.1.6 - - -From e2af52335ec96e115fb53eb2250be7eab7b0733f Mon Sep 17 00:00:00 2001 -From: unknown -Date: Fri, 18 Jan 2013 15:16:38 +0100 -Subject: [PATCH 82/94] 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.8.1.6 - - -From f37a312359b0ad0a4162c450fc4e6937773194f7 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Fri, 14 Dec 2012 14:19:15 +0100 -Subject: [PATCH 83/94] 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 6e772a4..9fd9537 100644 ---- a/xbmc/pvr/addons/PVRClients.cpp -+++ b/xbmc/pvr/addons/PVRClients.cpp -@@ -715,16 +715,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.8.1.6 - - -From d7ef98cc0e178d3b9bc1ca2ef0d4bcffdbaea756 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 3 Feb 2013 08:17:16 +0100 -Subject: [PATCH 84/94] 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.8.1.6 - - -From 98bab351e15f230b4a0cae794ead4332e8a5d12c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Mon, 25 Feb 2013 08:47:10 +0100 -Subject: [PATCH 85/94] 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.8.1.6 - - -From 7aa861a120b8eed5a94c3966a2dfafd513e81210 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 5 Mar 2013 17:01:53 +0100 -Subject: [PATCH 86/94] 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.8.1.6 - - -From 5ec02cfe6a7d215228640644d244851c605533af Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 6 Mar 2013 07:35:10 +0100 -Subject: [PATCH 87/94] 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.8.1.6 - - -From 777f525eab06ebb5954da18e9ca31bc6cf5043ca Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 9 Mar 2013 14:04:15 +0100 -Subject: [PATCH 88/94] 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.8.1.6 - - -From 15ec9232d554ce0100b54dbe4bde0b783de5ada2 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 21 Apr 2013 09:19:34 +0200 -Subject: [PATCH 89/94] vdpau: fix deadlock if decoder is closed while refresh - rate changes - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index b69ae8c..cd3507c 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -171,6 +171,8 @@ void CDecoder::Close() - { - CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); - -+ g_Windowing.Unregister(this); -+ - CSingleLock lock(m_DecoderSection); - - FiniVDPAUOutput(); -@@ -187,7 +189,6 @@ void CDecoder::Close() - free(render); - } - -- g_Windowing.Unregister(this); - m_dllAvUtil.Unload(); - } - --- -1.8.1.6 - - -From ccfc625faf40ba765d5af43646f44f5ca85e4821 Mon Sep 17 00:00:00 2001 -From: fritsch -Date: Sat, 12 Jan 2013 13:03:50 +0100 -Subject: [PATCH 90/94] 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. ---- - .../dvdplayer/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 fc51dbf..e90b3b9 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 17a12d0..ce3c1f7 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 0e68a80..d390ec7 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.8.1.6 - - -From 946eeb7e6785d0faa254e1dc8e4479a0e4a7bf7c Mon Sep 17 00:00:00 2001 -From: Bob van Loosen -Date: Tue, 14 May 2013 12:28:45 +0200 -Subject: [PATCH 91/94] fixed: when doing a format conversion from float to 32 - bit int, multiply with INT32_MAX - 127, since this is the maximum value that - can be stored in 32 bit float and int, if INT32_MAX gets converted to float, - it gets rounded to INT32_MAX + 1 which can cause wrap around distortion - ---- - xbmc/cores/AudioEngine/Utils/AEConvert.cpp | 32 +++++++++++++++++------------- - 1 file changed, 18 insertions(+), 14 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Utils/AEConvert.cpp b/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -index 2e4da19..e57530e 100644 ---- a/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -+++ b/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -@@ -922,17 +922,21 @@ unsigned int CAEConvert::Float_S24NE3(float *data, const unsigned int samples, u - return samples * 3; - } - -+//float can't store INT32_MAX, it gets rounded up to INT32_MAX + 1 -+//INT32_MAX - 127 is the maximum value that can exactly be stored in both 32 bit float and int -+#define MUL32 ((float)(INT32_MAX - 127)) -+ - unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, uint8_t *dest) - { - int32_t *dst = (int32_t*)dest; - #ifdef __SSE__ -- const __m128 mul = _mm_set_ps1((float)INT32_MAX); -+ const __m128 mul = _mm_set_ps1(MUL32); - unsigned int count = samples; - - /* work around invalid alignment */ - while ((((uintptr_t)data & 0xF) || ((uintptr_t)dest & 0xF)) && count > 0) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - ++data; - ++dst; - --count; -@@ -955,7 +959,7 @@ unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, ui - const uint32_t odd = samples - even; - if (odd == 1) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - else -@@ -988,7 +992,7 @@ unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, ui - /* no SIMD */ - for (uint32_t i = 0; i < samples; ++i, ++data, ++dst) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - #endif -@@ -1002,7 +1006,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - int32_t *dst = (int32_t*)dest; - for (float *end = data + (samples & ~0x3); data < end; data += 4, dst += 4) - { -- float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), INT32_MAX); -+ float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), MUL32); - int32x4_t ret = vcvtq_s32_f32(val); - #ifdef __BIG_ENDIAN__ - ret = vrev64q_s32(ret); -@@ -1012,7 +1016,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - - if (samples & 0x2) - { -- float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), INT32_MAX); -+ float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), MUL32); - int32x2_t ret = vcvt_s32_f32(val); - #ifdef __BIG_ENDIAN__ - ret = vrev64_s32(ret); -@@ -1024,7 +1028,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - - if (samples & 0x1) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - #endif -@@ -1035,13 +1039,13 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - { - int32_t *dst = (int32_t*)dest; - #ifdef __SSE__ -- const __m128 mul = _mm_set_ps1((float)INT32_MAX); -+ const __m128 mul = _mm_set_ps1(MUL32); - unsigned int count = samples; - - /* work around invalid alignment */ - while ((((uintptr_t)data & 0xF) || ((uintptr_t)dest & 0xF)) && count > 0) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - ++data; - ++dst; - --count; -@@ -1064,7 +1068,7 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - const uint32_t odd = samples - even; - if (odd == 1) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - else -@@ -1096,7 +1100,7 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - /* no SIMD */ - for (uint32_t i = 0; i < samples; ++i, ++data, ++dst) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - #endif -@@ -1110,7 +1114,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - int32_t *dst = (int32_t*)dest; - for (float *end = data + (samples & ~0x3); data < end; data += 4, dst += 4) - { -- float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), INT32_MAX); -+ float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), MUL32); - int32x4_t ret = vcvtq_s32_f32(val); - #ifndef __BIG_ENDIAN__ - ret = vrev64q_s32(ret); -@@ -1120,7 +1124,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - - if (samples & 0x2) - { -- float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), INT32_MAX); -+ float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), MUL32); - int32x2_t ret = vcvt_s32_f32(val); - #ifndef __BIG_ENDIAN__ - ret = vrev64_s32(ret); -@@ -1132,7 +1136,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - - if (samples & 0x1) - { -- dst[0] = safeRound(data[0] * (float)INT32_MAX); -+ dst[0] = safeRound(data[0] * MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - #endif --- -1.8.1.6 - - -From 3b836009536642941d58d1f21d21ea7599854d75 Mon Sep 17 00:00:00 2001 -From: Bob van Loosen -Date: Tue, 14 May 2013 18:43:01 +0200 -Subject: [PATCH 92/94] rename: MUL32 -> AE_MUL32 - ---- - xbmc/cores/AudioEngine/Utils/AEConvert.cpp | 30 +++++++++++++++--------------- - 1 file changed, 15 insertions(+), 15 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Utils/AEConvert.cpp b/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -index e57530e..a6ac060 100644 ---- a/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -+++ b/xbmc/cores/AudioEngine/Utils/AEConvert.cpp -@@ -924,19 +924,19 @@ unsigned int CAEConvert::Float_S24NE3(float *data, const unsigned int samples, u - - //float can't store INT32_MAX, it gets rounded up to INT32_MAX + 1 - //INT32_MAX - 127 is the maximum value that can exactly be stored in both 32 bit float and int --#define MUL32 ((float)(INT32_MAX - 127)) -+#define AE_MUL32 ((float)(INT32_MAX - 127)) - - unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, uint8_t *dest) - { - int32_t *dst = (int32_t*)dest; - #ifdef __SSE__ -- const __m128 mul = _mm_set_ps1(MUL32); -+ const __m128 mul = _mm_set_ps1(AE_MUL32); - unsigned int count = samples; - - /* work around invalid alignment */ - while ((((uintptr_t)data & 0xF) || ((uintptr_t)dest & 0xF)) && count > 0) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - ++data; - ++dst; - --count; -@@ -959,7 +959,7 @@ unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, ui - const uint32_t odd = samples - even; - if (odd == 1) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - else -@@ -992,7 +992,7 @@ unsigned int CAEConvert::Float_S32LE(float *data, const unsigned int samples, ui - /* no SIMD */ - for (uint32_t i = 0; i < samples; ++i, ++data, ++dst) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - #endif -@@ -1006,7 +1006,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - int32_t *dst = (int32_t*)dest; - for (float *end = data + (samples & ~0x3); data < end; data += 4, dst += 4) - { -- float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), MUL32); -+ float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), AE_MUL32); - int32x4_t ret = vcvtq_s32_f32(val); - #ifdef __BIG_ENDIAN__ - ret = vrev64q_s32(ret); -@@ -1016,7 +1016,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - - if (samples & 0x2) - { -- float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), MUL32); -+ float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), AE_MUL32); - int32x2_t ret = vcvt_s32_f32(val); - #ifdef __BIG_ENDIAN__ - ret = vrev64_s32(ret); -@@ -1028,7 +1028,7 @@ unsigned int CAEConvert::Float_S32LE_Neon(float *data, const unsigned int sample - - if (samples & 0x1) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapLE32(dst[0]); - } - #endif -@@ -1039,13 +1039,13 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - { - int32_t *dst = (int32_t*)dest; - #ifdef __SSE__ -- const __m128 mul = _mm_set_ps1(MUL32); -+ const __m128 mul = _mm_set_ps1(AE_MUL32); - unsigned int count = samples; - - /* work around invalid alignment */ - while ((((uintptr_t)data & 0xF) || ((uintptr_t)dest & 0xF)) && count > 0) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - ++data; - ++dst; - --count; -@@ -1068,7 +1068,7 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - const uint32_t odd = samples - even; - if (odd == 1) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - else -@@ -1100,7 +1100,7 @@ unsigned int CAEConvert::Float_S32BE(float *data, const unsigned int samples, ui - /* no SIMD */ - for (uint32_t i = 0; i < samples; ++i, ++data, ++dst) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - #endif -@@ -1114,7 +1114,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - int32_t *dst = (int32_t*)dest; - for (float *end = data + (samples & ~0x3); data < end; data += 4, dst += 4) - { -- float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), MUL32); -+ float32x4_t val = vmulq_n_f32(vld1q_f32((const float32_t *)data), AE_MUL32); - int32x4_t ret = vcvtq_s32_f32(val); - #ifndef __BIG_ENDIAN__ - ret = vrev64q_s32(ret); -@@ -1124,7 +1124,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - - if (samples & 0x2) - { -- float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), MUL32); -+ float32x2_t val = vmul_n_f32(vld1_f32((const float32_t *)data), AE_MUL32); - int32x2_t ret = vcvt_s32_f32(val); - #ifndef __BIG_ENDIAN__ - ret = vrev64_s32(ret); -@@ -1136,7 +1136,7 @@ unsigned int CAEConvert::Float_S32BE_Neon(float *data, const unsigned int sample - - if (samples & 0x1) - { -- dst[0] = safeRound(data[0] * MUL32); -+ dst[0] = safeRound(data[0] * AE_MUL32); - dst[0] = Endian_SwapBE32(dst[0]); - } - #endif --- -1.8.1.6 - - -From b023eb13b42a5bc02ee2a58b40463a6da0bf445f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sat, 11 May 2013 11:35:08 +0200 -Subject: [PATCH 93/94] Linux: fix handling of zombie processes - ---- - xbmc/Util.cpp | 11 ++++++++++- - xbmc/main/main.cpp | 7 ------- - 2 files changed, 10 insertions(+), 8 deletions(-) - -diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp -index a503ee5..e5cd053 100644 ---- a/xbmc/Util.cpp -+++ b/xbmc/Util.cpp -@@ -1632,6 +1632,15 @@ bool CUtil::Command(const CStdStringArray& arrArgs, bool waitExit) - int n = 0; - if (child == 0) - { -+ if (!waitExit) -+ { -+ // fork again in order not to leave a zombie process -+ child = fork(); -+ if (child == -1) -+ _exit(2); -+ else if (child != 0) -+ _exit(0); -+ } - close(0); - close(1); - close(2); -@@ -1646,7 +1655,7 @@ bool CUtil::Command(const CStdStringArray& arrArgs, bool waitExit) - } - else - { -- if (waitExit) waitpid(child, &n, 0); -+ waitpid(child, &n, 0); - } - - return (waitExit) ? (WEXITSTATUS(n) == 0) : true; -diff --git a/xbmc/main/main.cpp b/xbmc/main/main.cpp -index 8fe4226..81181a0 100644 ---- a/xbmc/main/main.cpp -+++ b/xbmc/main/main.cpp -@@ -66,13 +66,6 @@ int main(int argc, char* argv[]) - if (setrlimit(RLIMIT_CORE, &rlim) == -1) - CLog::Log(LOGDEBUG, "Failed to set core size limit (%s)", strerror(errno)); - #endif -- // Prevent child processes from becoming zombies on exit if not waited upon. See also Util::Command -- struct sigaction sa; -- memset(&sa, 0, sizeof(sa)); -- -- sa.sa_flags = SA_NOCLDWAIT; -- sa.sa_handler = SIG_IGN; -- sigaction(SIGCHLD, &sa, NULL); - #endif - setlocale(LC_NUMERIC, "C"); - g_advancedSettings.Initialize(); --- -1.8.1.6 - - -From cc55dcbd5defc86375764896e4c09ad3e9e977b0 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 21 May 2013 21:16:16 +0200 -Subject: [PATCH 94/94] rendermanager: fix waitin gon buffer if all are - displayed - ---- - xbmc/cores/VideoRenderers/RenderManager.cpp | 22 +++++++--------------- - 1 file changed, 7 insertions(+), 15 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp -index bc764da..77f6e15 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -1065,21 +1065,6 @@ void CXBMCRenderManager::PrepareNextRender() - 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) -@@ -1137,6 +1122,13 @@ void CXBMCRenderManager::NotifyDisplayFlip() - int last = m_iDisplayedRenderBuffer; - m_iDisplayedRenderBuffer = (m_iCurrentRenderBuffer + m_iNumRenderBuffers - 1) % m_iNumRenderBuffers; - -+ // we have caught up with output so all buffers are re-usable -+ if (last != m_iDisplayedRenderBuffer -+ && m_iDisplayedRenderBuffer == m_iOutputRenderBuffer) -+ { -+ m_bAllRenderBuffersDisplayed = true; -+ } -+ - if (last != m_iDisplayedRenderBuffer - && m_iDisplayedRenderBuffer != m_iCurrentRenderBuffer) - { --- -1.8.1.6 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.10-disable-alt-tab.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.10-disable-alt-tab.patch deleted file mode 100644 index 2ee2b7a27..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-995.10-disable-alt-tab.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/xbmc/windowing/WinEventsX11.cpp b/xbmc/windowing/WinEventsX11.cpp -index ed31c04..34fcfae 100644 ---- a/xbmc/windowing/WinEventsX11.cpp -+++ b/xbmc/windowing/WinEventsX11.cpp -@@ -709,7 +709,6 @@ bool CWinEventsX11::ProcessShortcuts(XBMC_Event& event) - switch(event.key.keysym.sym) - { - case XBMCK_TAB: // ALT+TAB to minimize/hide -- g_application.Minimize(); - return true; - - default: diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.02-xbmc-revert-799d6ff03-setwakeup.sh.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.02-xbmc-revert-799d6ff03-setwakeup.sh.patch deleted file mode 100644 index b6ac52b11..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.02-xbmc-revert-799d6ff03-setwakeup.sh.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 7abb1f31a53cc0147ba6f5ed5fc796e2ac8584ff Mon Sep 17 00:00:00 2001 -From: Stefan Saraev -Date: Thu, 9 May 2013 21:11:47 +0300 -Subject: [PATCH] xbmc: revert 799d6ff03 (setwakeup.sh) - -this reverts upstream commit 799d6ff03 -https://github.com/xbmc/xbmc/commit/799d6ff03 ---- - xbmc/settings/GUISettings.cpp | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp -index 67aeec9..96f738c 100644 ---- a/xbmc/settings/GUISettings.cpp -+++ b/xbmc/settings/GUISettings.cpp -@@ -1001,7 +1001,7 @@ void CGUISettings::Initialize() - AddBool(pvrpwr, "pvrpowermanagement.enabled", 305, false); - AddSeparator(pvrpwr, "pvrpowermanagement.sep1"); - AddInt(pvrpwr, "pvrpowermanagement.backendidletime", 19244, 15, 0, 5, 360, SPIN_CONTROL_INT_PLUS, MASK_MINS, TEXT_OFF); -- AddString(pvrpwr, "pvrpowermanagement.setwakeupcmd", 19245, "", EDIT_CONTROL_INPUT, true); -+ AddString(pvrpwr, "pvrpowermanagement.setwakeupcmd", 19245, "/usr/bin/setwakeup.sh", EDIT_CONTROL_INPUT, true); - AddInt(pvrpwr, "pvrpowermanagement.prewakeup", 19246, 15, 0, 1, 60, SPIN_CONTROL_INT_PLUS, MASK_MINS, TEXT_OFF); - AddSeparator(pvrpwr, "pvrpowermanagement.sep2"); - AddBool(pvrpwr, "pvrpowermanagement.dailywakeup", 19247, false); --- -1.7.2.5 - diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.03-add_as.xml_busy_dialog_delay_control.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.03-add_as.xml_busy_dialog_delay_control.patch deleted file mode 100644 index 8300e1329..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-996.03-add_as.xml_busy_dialog_delay_control.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff -Naur xbmc-12.1.8/xbmc/cores/dvdplayer/DVDPlayer.cpp xbmc-12.1.8.patch/xbmc/cores/dvdplayer/DVDPlayer.cpp ---- xbmc-12.1.8/xbmc/cores/dvdplayer/DVDPlayer.cpp 2013-04-24 23:38:36.000000000 +0200 -+++ xbmc-12.1.8.patch/xbmc/cores/dvdplayer/DVDPlayer.cpp 2013-04-26 00:49:07.732011721 +0200 -@@ -470,7 +470,7 @@ - #endif - - Create(); -- if(!m_ready.WaitMSec(100)) -+ if(!m_ready.WaitMSec(g_advancedSettings.m_videoBusyDialogDelay_ms)) - { - CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY); - if(dialog) -diff -Naur xbmc-12.1.8/xbmc/cores/omxplayer/OMXPlayer.cpp xbmc-12.1.8.patch/xbmc/cores/omxplayer/OMXPlayer.cpp ---- xbmc-12.1.8/xbmc/cores/omxplayer/OMXPlayer.cpp 2013-04-24 23:38:36.000000000 +0200 -+++ xbmc-12.1.8.patch/xbmc/cores/omxplayer/OMXPlayer.cpp 2013-04-26 00:50:56.974691417 +0200 -@@ -474,7 +474,7 @@ - g_renderManager.PreInit(); - - Create(); -- if(!m_ready.WaitMSec(100)) -+ if(!m_ready.WaitMSec(g_advancedSettings.m_videoBusyDialogDelay_ms)) - { - CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY); - if(dialog) -diff -Naur xbmc-12.1.8/xbmc/settings/AdvancedSettings.cpp xbmc-12.1.8.patch/xbmc/settings/AdvancedSettings.cpp ---- xbmc-12.1.8/xbmc/settings/AdvancedSettings.cpp 2013-04-26 00:48:59.375036542 +0200 -+++ xbmc-12.1.8.patch/xbmc/settings/AdvancedSettings.cpp 2013-04-26 00:49:07.732011721 +0200 -@@ -111,6 +111,7 @@ - m_DXVAForceProcessorRenderer = true; - m_DXVANoDeintProcForProgressive = false; - m_videoFpsDetect = 1; -+ m_videoBusyDialogDelay_ms = 100; - m_videoDefaultLatency = 0.0; - m_videoDisableHi10pMultithreading = false; - -@@ -592,6 +593,10 @@ - //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps - XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2); - -+ // controls the delay, in milliseconds, until -+ // the busy dialog is shown when starting video playback. -+ XMLUtils::GetInt(pElement, "busydialogdelayms", m_videoBusyDialogDelay_ms, 0, 1000); -+ - // Store global display latency settings - TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency"); - if (pVideoLatency) -diff -Naur xbmc-12.1.8/xbmc/settings/AdvancedSettings.h xbmc-12.1.8.patch/xbmc/settings/AdvancedSettings.h ---- xbmc-12.1.8/xbmc/settings/AdvancedSettings.h 2013-04-26 00:48:59.383036518 +0200 -+++ xbmc-12.1.8.patch/xbmc/settings/AdvancedSettings.h 2013-04-26 00:49:07.732011721 +0200 -@@ -165,6 +165,7 @@ - bool m_DXVANoDeintProcForProgressive; - int m_videoFpsDetect; - bool m_videoDisableHi10pMultithreading; -+ int m_videoBusyDialogDelay_ms; - - CStdString m_videoDefaultPlayer; - CStdString m_videoDefaultDVDPlayer; diff --git a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-997.01-audio-engine-fix-buffer-access.patch b/packages/mediacenter/xbmc/patches/12.2.0/xbmc-997.01-audio-engine-fix-buffer-access.patch deleted file mode 100644 index 15e294c59..000000000 --- a/packages/mediacenter/xbmc/patches/12.2.0/xbmc-997.01-audio-engine-fix-buffer-access.patch +++ /dev/null @@ -1,746 +0,0 @@ -From 546fccdd835c5d4e2a1917839ed9d84bd4c53bc2 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Sat, 1 Jun 2013 03:10:19 +0200 -Subject: [PATCH 1/6] dvdplayer: clock was starting before expected - ---- - xbmc/cores/dvdplayer/DVDClock.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDClock.cpp b/xbmc/cores/dvdplayer/DVDClock.cpp -index 9eb744f..b8cceeb 100644 ---- a/xbmc/cores/dvdplayer/DVDClock.cpp -+++ b/xbmc/cores/dvdplayer/DVDClock.cpp -@@ -233,7 +233,8 @@ double CDVDClock::SystemToPlaying(int64_t system) - { - m_startClock = system; - m_systemUsed = m_systemFrequency; -- m_pauseClock = 0; -+ if(m_pauseClock) -+ m_pauseClock = m_startClock; - m_iDisc = 0; - m_bReset = false; - } --- -1.7.10.4 - - -From c047cc15cd5dcc35bd951e2992cc303b0cbc9b83 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Tue, 28 May 2013 01:00:19 +0200 -Subject: [PATCH 2/6] SoftAE: make sure we hold sink lock when we consume and - write to sink - -This make sure that sink delay and buffers are kept in line. - -Conflicts: - xbmc/cores/AudioEngine/Sinks/AESinkNULL.cpp ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 78 +++++++++----------- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h | 2 + - xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 6 +- - xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 4 - - xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp | 3 +- - xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp | 11 +++ - xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp | 16 +--- - 7 files changed, 52 insertions(+), 68 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -index 983cd9a..ec6cc38 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -@@ -1212,6 +1212,34 @@ bool CSoftAE::FinalizeSamples(float *buffer, unsigned int samples, bool hasAudio - return true; - } - -+unsigned int CSoftAE::WriteSink(CAEBuffer& src, uint8_t *data, bool hasAudio) -+{ -+ CExclusiveLock lock(m_sinkLock); /* lock to maintain delay consistency */ -+ while(m_sink) -+ { -+ int frames = m_sink->AddPackets(data, m_sinkFormat.m_frames, hasAudio); -+ -+ /* Return value of INT_MAX signals error in sink - restart */ -+ if (frames == INT_MAX) -+ { -+ CLog::Log(LOGERROR, "CSoftAE::WriteSink - sink error - reinit flagged"); -+ m_reOpen = true; -+ break; -+ } -+ -+ if (frames) -+ { -+ m_buffer.Shift(NULL, frames * m_sinkFormat.m_frameSize); -+ return frames; -+ } -+ -+ lock.Leave(); -+ Sleep((500 * m_sinkFormat.m_frames) / m_sinkFormat.m_sampleRate); -+ lock.Enter(); -+ } -+ return 0; -+} -+ - int CSoftAE::RunOutputStage(bool hasAudio) - { - const unsigned int needSamples = m_sinkFormat.m_frames * m_sinkFormat.m_channelLayout.Count(); -@@ -1222,7 +1250,6 @@ int CSoftAE::RunOutputStage(bool hasAudio) - void *data = m_buffer.Raw(needBytes); - hasAudio = FinalizeSamples((float*)data, needSamples, hasAudio); - -- int wroteFrames = 0; - if (m_convertFn) - { - const unsigned int convertedBytes = m_sinkFormat.m_frames * m_sinkFormat.m_frameSize; -@@ -1232,22 +1259,7 @@ int CSoftAE::RunOutputStage(bool hasAudio) - data = m_converted; - } - -- /* Output frames to sink */ -- if (m_sink) -- wroteFrames = m_sink->AddPackets((uint8_t*)data, m_sinkFormat.m_frames, hasAudio); -- -- /* Return value of INT_MAX signals error in sink - restart */ -- if (wroteFrames == INT_MAX) -- { -- CLog::Log(LOGERROR, "CSoftAE::RunOutputStage - sink error - reinit flagged"); -- wroteFrames = 0; -- m_reOpen = true; -- } -- -- if (wroteFrames) -- m_buffer.Shift(NULL, wroteFrames * m_sinkFormat.m_channelLayout.Count() * sizeof(float)); -- -- return wroteFrames; -+ return WriteSink(m_buffer, (uint8_t*)data, hasAudio); - } - - int CSoftAE::RunRawOutputStage(bool hasAudio) -@@ -1275,20 +1287,7 @@ int CSoftAE::RunRawOutputStage(bool hasAudio) - data = m_converted; - } - -- int wroteFrames = 0; -- if (m_sink) -- wroteFrames = m_sink->AddPackets((uint8_t *)data, m_sinkFormat.m_frames, hasAudio); -- -- /* Return value of INT_MAX signals error in sink - restart */ -- if (wroteFrames == INT_MAX) -- { -- CLog::Log(LOGERROR, "CSoftAE::RunRawOutputStage - sink error - reinit flagged"); -- wroteFrames = 0; -- m_reOpen = true; -- } -- -- m_buffer.Shift(NULL, wroteFrames * m_sinkFormat.m_frameSize); -- return wroteFrames; -+ return WriteSink(m_buffer, (uint8_t*)data, hasAudio); - } - - int CSoftAE::RunTranscodeStage(bool hasAudio) -@@ -1316,33 +1315,24 @@ int CSoftAE::RunTranscodeStage(bool hasAudio) - buffer = m_buffer.Raw(block); - - encodedFrames = m_encoder->Encode((float*)buffer, m_encoderFormat.m_frames); -- m_buffer.Shift(NULL, encodedFrames * m_encoderFormat.m_frameSize); - - uint8_t *packet; - unsigned int size = m_encoder->GetData(&packet); - -+ CExclusiveLock sinkLock(m_sinkLock); /* lock to maintain delay consistency */ -+ - /* if there is not enough space for another encoded packet enlarge the buffer */ - if (m_encodedBuffer.Free() < size) - m_encodedBuffer.ReAlloc(m_encodedBuffer.Used() + size); - -+ m_buffer.Shift(NULL, encodedFrames * m_encoderFormat.m_frameSize); - m_encodedBuffer.Push(packet, size); - } - - /* if we have enough data to write */ - if (m_encodedBuffer.Used() >= sinkBlock) -- { -- int wroteFrames = m_sink->AddPackets((uint8_t*)m_encodedBuffer.Raw(sinkBlock), m_sinkFormat.m_frames, hasAudio); -- -- /* Return value of INT_MAX signals error in sink - restart */ -- if (wroteFrames == INT_MAX) -- { -- CLog::Log(LOGERROR, "CSoftAE::RunTranscodeStage - sink error - reinit flagged"); -- wroteFrames = 0; -- m_reOpen = true; -- } -+ WriteSink(m_encodedBuffer, (uint8_t*)m_encodedBuffer.Raw(sinkBlock), hasAudio); - -- m_encodedBuffer.Shift(NULL, wroteFrames * m_sinkFormat.m_frameSize); -- } - return encodedFrames; - } - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -index 3ddf727..bb2769e 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -@@ -246,5 +246,7 @@ private: - - void RemoveStream(StreamList &streams, CSoftAEStream *stream); - void PrintSinks(); -+ -+ unsigned int WriteSink(CAEBuffer& src, uint8_t *data, bool hasAudio); - }; - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -index 1da026e..6a66859 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp -@@ -523,11 +523,7 @@ unsigned int CAESinkALSA::AddPackets(uint8_t *data, unsigned int frames, bool ha - } - - if ((unsigned int)ret < frames) -- { -- ret = snd_pcm_wait(m_pcm, m_timeout); -- if (ret < 0) -- HandleError("snd_pcm_wait", ret); -- } -+ return 0; - - ret = snd_pcm_writei(m_pcm, (void*)data, frames); - if (ret < 0) -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp -index 8f23b41..4853302 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp -@@ -209,10 +209,6 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t *data, unsigned int frames, b - break; - } - } -- // AddPackets runs under a non-idled AE thread we must block or sleep. -- // Trying to calc the optimal sleep is tricky so just a minimal sleep. -- Sleep(10); -- - return hasAudio ? write_frames:frames; - } - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp -index f6dc62f..00058ff 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp -@@ -384,7 +384,8 @@ unsigned int CAESinkDirectSound::AddPackets(uint8_t *data, unsigned int frames, - { - if (m_isDirtyDS) - return INT_MAX; -- Sleep(total * 1000 / m_AvgBytesPerSec); -+ else -+ return 0; - } - - while (len) -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp -index 970e236..664c761 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp -@@ -29,6 +29,7 @@ - #include - - #include -+#include - - #if defined(OSS4) || defined(TARGET_FREEBSD) - #include -@@ -320,6 +321,13 @@ bool CAESinkOSS::Initialize(AEAudioFormat &format, std::string &device) - return false; - } - -+ if (fcntl(m_fd, F_SETFL, fcntl(m_fd, F_GETFL, 0) | O_NONBLOCK) == -1) -+ { -+ close(m_fd); -+ CLog::Log(LOGERROR, "CAESinkOSS::Initialize - Failed to set non blocking writes"); -+ return false; -+ } -+ - format.m_sampleRate = oss_sr; - format.m_frameSize = (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3) * format.m_channelLayout.Count(); - format.m_frames = bi.fragsize / format.m_frameSize; -@@ -412,6 +420,9 @@ unsigned int CAESinkOSS::AddPackets(uint8_t *data, unsigned int frames, bool has - int wrote = write(m_fd, data, size); - if (wrote < 0) - { -+ if(errno == EAGAIN || errno == EWOULDBLOCK) -+ return 0; -+ - CLog::Log(LOGERROR, "CAESinkOSS::AddPackets - Failed to write"); - return INT_MAX; - } -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp -index f238d75..89116fa 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp -@@ -485,22 +485,10 @@ unsigned int CAESinkWASAPI::AddPackets(uint8_t *data, unsigned int frames, bool - #endif - - /* Wait for Audio Driver to tell us it's got a buffer available */ -- DWORD eventAudioCallback = WaitForSingleObject(m_needDataEvent, 1100); -+ DWORD eventAudioCallback = WaitForSingleObject(m_needDataEvent, 0); - -- if (eventAudioCallback != WAIT_OBJECT_0 || !&buf) -- { -- /* Event handle timed out - flag sink as dirty for re-initializing */ -- CLog::Log(LOGERROR, __FUNCTION__": Endpoint Buffer timed out"); -- if (g_advancedSettings.m_streamSilence) -- { -- m_isDirty = true; //flag new device or re-init needed -- Deinitialize(); -- m_running = false; -- return INT_MAX; -- } -- m_running = false; -+ if (eventAudioCallback != WAIT_OBJECT_0) - return 0; -- } - - if (!m_running) - return 0; --- -1.7.10.4 - - -From 35502583cb7cd56a59e68e1514a2fccb63b2a1a2 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Tue, 28 May 2013 01:03:08 +0200 -Subject: [PATCH 3/6] SoftAE: let SoftAEStream share SoftAE stream lock - -This avoids holding an internal stream lock, while soft ae -is trying to read out new frames and allow us to properly -hold lock while requesting delays. ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 2 +- - .../AudioEngine/Engines/SoftAE/SoftAEStream.cpp | 51 +++++++++++++------- - .../AudioEngine/Engines/SoftAE/SoftAEStream.h | 4 +- - 3 files changed, 37 insertions(+), 20 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -index ec6cc38..faf6ccc 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -@@ -775,7 +775,7 @@ IAEStream *CSoftAE::MakeStream(enum AEDataFormat dataFormat, unsigned int sample - ASSERT(encodedSampleRate); - - CSingleLock streamLock(m_streamLock); -- CSoftAEStream *stream = new CSoftAEStream(dataFormat, sampleRate, encodedSampleRate, channelLayout, options); -+ CSoftAEStream *stream = new CSoftAEStream(dataFormat, sampleRate, encodedSampleRate, channelLayout, options, m_streamLock); - m_newStreams.push_back(stream); - streamLock.Leave(); - // this is really needed here -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -index 4e8134b..12d00ea 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp -@@ -34,7 +34,8 @@ - - using namespace std; - --CSoftAEStream::CSoftAEStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options) : -+CSoftAEStream::CSoftAEStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options, CCriticalSection& lock) : -+ m_lock (lock ), - m_resampleRatio (1.0 ), - m_internalRatio (1.0 ), - m_convertBuffer (NULL ), -@@ -74,7 +75,8 @@ CSoftAEStream::CSoftAEStream(enum AEDataFormat dataFormat, unsigned int sampleRa - - void CSoftAEStream::InitializeRemap() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); -+ - if (!AE_IS_RAW(m_initDataFormat)) - { - /* re-init the remappers */ -@@ -96,7 +98,8 @@ void CSoftAEStream::InitializeRemap() - - void CSoftAEStream::Initialize() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); -+ - if (m_valid) - { - InternalFlush(); -@@ -213,14 +216,15 @@ void CSoftAEStream::Initialize() - - void CSoftAEStream::Destroy() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); -+ - m_valid = false; - m_delete = true; - } - - CSoftAEStream::~CSoftAEStream() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - - InternalFlush(); - if (m_convert) -@@ -241,6 +245,8 @@ CSoftAEStream::~CSoftAEStream() - - unsigned int CSoftAEStream::GetSpace() - { -+ CSingleLock lock(m_lock); -+ - if (!m_valid || m_draining) - return 0; - -@@ -252,7 +258,8 @@ unsigned int CSoftAEStream::GetSpace() - - unsigned int CSoftAEStream::AddData(void *data, unsigned int size) - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); -+ - if (!m_valid || size == 0 || data == NULL) - return 0; - -@@ -415,7 +422,7 @@ unsigned int CSoftAEStream::ProcessFrameBuffer() - - uint8_t* CSoftAEStream::GetFrame() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - - /* if we are fading, this runs even if we have underrun as it is time based */ - if (m_fadeRunning) -@@ -486,6 +493,8 @@ uint8_t* CSoftAEStream::GetFrame() - - double CSoftAEStream::GetDelay() - { -+ CSingleLock lock(m_lock); -+ - if (m_delete) - return 0.0; - -@@ -497,6 +506,8 @@ double CSoftAEStream::GetDelay() - - double CSoftAEStream::GetCacheTime() - { -+ CSingleLock lock(m_lock); -+ - if (m_delete) - return 0.0; - -@@ -508,6 +519,8 @@ double CSoftAEStream::GetCacheTime() - - double CSoftAEStream::GetCacheTotal() - { -+ CSingleLock lock(m_lock); -+ - if (m_delete) - return 0.0; - -@@ -519,6 +532,8 @@ double CSoftAEStream::GetCacheTotal() - - void CSoftAEStream::Pause() - { -+ CSingleLock lock(m_lock); -+ - if (m_paused) - return; - m_paused = true; -@@ -527,6 +542,8 @@ void CSoftAEStream::Pause() - - void CSoftAEStream::Resume() - { -+ CSingleLock lock(m_lock); -+ - if (!m_paused) - return; - m_paused = false; -@@ -536,20 +553,20 @@ void CSoftAEStream::Resume() - - void CSoftAEStream::Drain() - { -- CSharedLock lock(m_lock); -+ CSingleLock lock(m_lock); - m_draining = true; - } - - bool CSoftAEStream::IsDrained() - { -- CSharedLock lock(m_lock); -+ CSingleLock lock(m_lock); - return (m_draining && !m_packet && m_outBuffer.empty()); - } - - void CSoftAEStream::Flush() - { - CLog::Log(LOGDEBUG, "CSoftAEStream::Flush"); -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - InternalFlush(); - - /* internal flush does not do this as these samples are still valid if we are re-initializing */ -@@ -591,10 +608,10 @@ void CSoftAEStream::InternalFlush() - - double CSoftAEStream::GetResampleRatio() - { -+ CSingleLock lock(m_lock); - if (!m_resample) - return 1.0f; - -- CSharedLock lock(m_lock); - return m_ssrcData.src_ratio; - } - -@@ -603,7 +620,7 @@ bool CSoftAEStream::SetResampleRatio(double ratio) - if (!m_resample) - return false; - -- CSharedLock lock(m_lock); -+ CSingleLock lock(m_lock); - - int oldRatioInt = (int)std::ceil(m_ssrcData.src_ratio); - -@@ -624,7 +641,7 @@ bool CSoftAEStream::SetResampleRatio(double ratio) - - void CSoftAEStream::RegisterAudioCallback(IAudioCallback* pCallback) - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - m_vizBufferSamples = 0; - m_audioCallback = pCallback; - if (m_audioCallback) -@@ -633,7 +650,7 @@ void CSoftAEStream::RegisterAudioCallback(IAudioCallback* pCallback) - - void CSoftAEStream::UnRegisterAudioCallback() - { -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - m_audioCallback = NULL; - m_vizBufferSamples = 0; - } -@@ -644,7 +661,7 @@ void CSoftAEStream::FadeVolume(float from, float target, unsigned int time) - if (AE_IS_RAW(m_initDataFormat)) - return; - -- CExclusiveLock lock(m_lock); -+ CSingleLock lock(m_lock); - float delta = target - from; - m_fadeDirUp = target > from; - m_fadeTarget = target; -@@ -654,13 +671,13 @@ void CSoftAEStream::FadeVolume(float from, float target, unsigned int time) - - bool CSoftAEStream::IsFading() - { -- CSharedLock lock(m_lock); -+ CSingleLock lock(m_lock); - return m_fadeRunning; - } - - void CSoftAEStream::RegisterSlave(IAEStream *slave) - { -- CSharedLock lock(m_lock); -+ CSingleLock lock(m_lock); - m_slave = (CSoftAEStream*)slave; - } - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.h -index 7e93215..1b715fc 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.h -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.h -@@ -36,7 +36,7 @@ class CSoftAEStream : public IAEStream - { - protected: - friend class CSoftAE; -- CSoftAEStream(enum AEDataFormat format, unsigned int sampleRate, unsigned int encodedSamplerate, CAEChannelInfo channelLayout, unsigned int options); -+ CSoftAEStream(enum AEDataFormat format, unsigned int sampleRate, unsigned int encodedSamplerate, CAEChannelInfo channelLayout, unsigned int options, CCriticalSection& lock); - virtual ~CSoftAEStream(); - - void Initialize(); -@@ -91,7 +91,7 @@ private: - void InternalFlush(); - void CheckResampleBuffers(); - -- CSharedSection m_lock; -+ CCriticalSection& m_lock; - enum AEDataFormat m_initDataFormat; - unsigned int m_initSampleRate; - unsigned int m_initEncodedSampleRate; --- -1.7.10.4 - - -From 2fae6e49bf802e204e71e9016be6ba9c68262e46 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Wed, 29 May 2013 22:59:01 +0200 -Subject: [PATCH 4/6] softae: use correct number of bytes when consuming from - src buffer - ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 10 +++++----- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h | 2 +- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -index faf6ccc..991cb10 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -@@ -1212,7 +1212,7 @@ bool CSoftAE::FinalizeSamples(float *buffer, unsigned int samples, bool hasAudio - return true; - } - --unsigned int CSoftAE::WriteSink(CAEBuffer& src, uint8_t *data, bool hasAudio) -+unsigned int CSoftAE::WriteSink(CAEBuffer& src, int src_len, uint8_t *data, bool hasAudio) - { - CExclusiveLock lock(m_sinkLock); /* lock to maintain delay consistency */ - while(m_sink) -@@ -1229,7 +1229,7 @@ unsigned int CSoftAE::WriteSink(CAEBuffer& src, uint8_t *data, bool hasAudio) - - if (frames) - { -- m_buffer.Shift(NULL, frames * m_sinkFormat.m_frameSize); -+ m_buffer.Shift(NULL, src_len); - return frames; - } - -@@ -1259,7 +1259,7 @@ int CSoftAE::RunOutputStage(bool hasAudio) - data = m_converted; - } - -- return WriteSink(m_buffer, (uint8_t*)data, hasAudio); -+ return WriteSink(m_buffer, needBytes, (uint8_t*)data, hasAudio); - } - - int CSoftAE::RunRawOutputStage(bool hasAudio) -@@ -1287,7 +1287,7 @@ int CSoftAE::RunRawOutputStage(bool hasAudio) - data = m_converted; - } - -- return WriteSink(m_buffer, (uint8_t*)data, hasAudio); -+ return WriteSink(m_buffer, m_sinkBlockSize, (uint8_t*)data, hasAudio); - } - - int CSoftAE::RunTranscodeStage(bool hasAudio) -@@ -1331,7 +1331,7 @@ int CSoftAE::RunTranscodeStage(bool hasAudio) - - /* if we have enough data to write */ - if (m_encodedBuffer.Used() >= sinkBlock) -- WriteSink(m_encodedBuffer, (uint8_t*)m_encodedBuffer.Raw(sinkBlock), hasAudio); -+ WriteSink(m_encodedBuffer, sinkBlock, (uint8_t*)m_encodedBuffer.Raw(sinkBlock), hasAudio); - - return encodedFrames; - } -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -index bb2769e..62914bb 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -@@ -247,6 +247,6 @@ private: - void RemoveStream(StreamList &streams, CSoftAEStream *stream); - void PrintSinks(); - -- unsigned int WriteSink(CAEBuffer& src, uint8_t *data, bool hasAudio); -+ unsigned int WriteSink(CAEBuffer& src, int src_len, uint8_t *data, bool hasAudio); - }; - --- -1.7.10.4 - - -From 2e9cd3d009ca93a74624503d9769863415267148 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Wed, 29 May 2013 23:04:14 +0200 -Subject: [PATCH 5/6] softae: add fail safe to WriteSink to avoid deadlocking - on broken output - ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 13 ++++++++++++- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h | 1 + - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -index 991cb10..e4faf7b 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -@@ -64,6 +64,7 @@ CSoftAE::CSoftAE(): - m_softSuspend (false ), - m_softSuspendTimer (0 ), - m_sink (NULL ), -+ m_sinkBlockTime (0 ), - m_transcode (false ), - m_rawPassthrough (false ), - m_soundMode (AE_SOUND_OFF), -@@ -350,6 +351,7 @@ void CSoftAE::InternalOpenSink() - m_sinkFormatSampleRateMul = 1.0 / (double)newFormat.m_sampleRate; - m_sinkFormatFrameSizeMul = 1.0 / (double)newFormat.m_frameSize; - m_sinkBlockSize = newFormat.m_frames * newFormat.m_frameSize; -+ m_sinkBlockTime = 1000 * newFormat.m_frames / newFormat.m_sampleRate; - // check if sink controls volume, if so, init the volume. - m_sinkHandlesVolume = m_sink->HasVolume(); - if (m_sinkHandlesVolume) -@@ -1215,6 +1217,8 @@ bool CSoftAE::FinalizeSamples(float *buffer, unsigned int samples, bool hasAudio - unsigned int CSoftAE::WriteSink(CAEBuffer& src, int src_len, uint8_t *data, bool hasAudio) - { - CExclusiveLock lock(m_sinkLock); /* lock to maintain delay consistency */ -+ -+ XbmcThreads::EndTime timeout(m_sinkBlockTime * 2); - while(m_sink) - { - int frames = m_sink->AddPackets(data, m_sinkFormat.m_frames, hasAudio); -@@ -1233,8 +1237,15 @@ unsigned int CSoftAE::WriteSink(CAEBuffer& src, int src_len, uint8_t *data, bool - return frames; - } - -+ if(timeout.IsTimePast()) -+ { -+ CLog::Log(LOGERROR, "CSoftAE::WriteSink - sink blocked- reinit flagged"); -+ m_reOpen = true; -+ break; -+ } -+ - lock.Leave(); -- Sleep((500 * m_sinkFormat.m_frames) / m_sinkFormat.m_sampleRate); -+ Sleep(m_sinkBlockTime / 4); - lock.Enter(); - } - return 0; -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -index 62914bb..23e0ea3 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h -@@ -165,6 +165,7 @@ private: - double m_sinkFormatSampleRateMul; - double m_sinkFormatFrameSizeMul; - unsigned int m_sinkBlockSize; -+ unsigned int m_sinkBlockTime; - bool m_sinkHandlesVolume; - AEAudioFormat m_encoderFormat; - double m_encoderFrameSizeMul; --- -1.7.10.4 - - -From 7a81b2a0e9822688d9681756414b753815bf9e21 Mon Sep 17 00:00:00 2001 -From: Joakim Plate -Date: Sat, 1 Jun 2013 18:22:43 +0200 -Subject: [PATCH 6/6] softae: use passed buffer not something else when - consuming data - ---- - xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -index e4faf7b..e641335 100644 ---- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp -@@ -1233,7 +1233,7 @@ unsigned int CSoftAE::WriteSink(CAEBuffer& src, int src_len, uint8_t *data, bool - - if (frames) - { -- m_buffer.Shift(NULL, src_len); -+ src.Shift(NULL, src_len); - return frames; - } - --- -1.7.10.4 - diff --git a/tools/mkpkg/mkpkg_xbmc-frodo-oe b/tools/mkpkg/mkpkg_xbmc-frodo-oe new file mode 100755 index 000000000..56bd32b19 --- /dev/null +++ b/tools/mkpkg/mkpkg_xbmc-frodo-oe @@ -0,0 +1,81 @@ +#!/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 +################################################################################ + +PKG_NAME="xbmc" +PKG_VERSION="" +GIT_REPO="-b openelec-Frodo git://github.com/OpenELEC/xbmc.git" +DEST_DIR="$PKG_NAME-frodo-openelec" + +echo "getting sources..." + if [ ! -d $DEST_DIR-latest ]; then + git clone $GIT_REPO $DEST_DIR-latest + fi + + cd $DEST_DIR-latest + git pull + + echo "getting version..." + GIT_REV=`git log -n1 --format=%h` + echo $GIT_REV + cd .. + + if [ -z "$PKG_VERSION" ]; then + PKG_VERSION="12.2-$GIT_REV" + fi + +echo "copying sources..." + rm -rf $PKG_NAME-$PKG_VERSION + cp -R $DEST_DIR-latest $PKG_NAME-$PKG_VERSION + echo "$GIT_REV" > $PKG_NAME-$PKG_VERSION/VERSION + +echo "cleaning sources..." + rm -rf $PKG_NAME-$PKG_VERSION/.git + +echo "seperating theme..." + rm -rf $PKG_NAME-theme-Confluence-$PKG_VERSION + mv $PKG_NAME-$PKG_VERSION/addons/skin.confluence $PKG_NAME-theme-Confluence-$PKG_VERSION + +echo "cleaning sources..." + rm -rf $PKG_NAME-$PKG_VERSION/visualisations + rm -rf $PKG_NAME-$PKG_VERSION/lib/libSDL-* + rm -rf $PKG_NAME-$PKG_VERSION/lib/libcurl-* + rm -rf $PKG_NAME-$PKG_VERSION/project + + for i in "Changelog" "Fake\ Episode\ Maker" "MingwBuildEnvironment" \ + "PackageMaker" "Translator" "XBMCLive" "XprPack" \ + "HardwareConfigure" "Mach5" "osx" "UpdateThumbs.py" "XBMCTex"; do + rm -rf $PKG_NAME-$PKG_VERSION/tools/$i + done + + for i in dll a lib so bat; do + find $PKG_NAME-$PKG_VERSION -name *.$i -exec rm -rf {} ";" + done + + # bundled win32 binaries + rm -r $PKG_NAME-$PKG_VERSION/xbmc/visualizations/XBMCProjectM/win32 + +echo "packing sources..." + tar cvJf $PKG_NAME-$PKG_VERSION.tar.xz $PKG_NAME-$PKG_VERSION + tar cvJf $PKG_NAME-theme-Confluence-$PKG_VERSION.tar.xz $PKG_NAME-theme-Confluence-$PKG_VERSION + +echo "remove temporary sourcedir..." + rm -rf $PKG_NAME-$PKG_VERSION + rm -rf $PKG_NAME-theme-Confluence-$PKG_VERSION