From ad93bf1aec91759cb026918b1313521a0f80096e Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Wed, 25 Sep 2013 18:59:47 +0300 Subject: [PATCH] xbmc (Gotham): update to xbmc-13.alpha-7f45288 --- packages/mediacenter/xbmc/package.mk | 2 +- .../xbmc-990.25-BP-xbmc-PR3166.patch | 86 - .../13.alpha-2ef8929/xbmc-990.26-PR3210.patch | 151 - ...HONOPTIMIZE_with_external_Python-0.1.patch | 0 ...bmc-453-add_openelec.tv_RSS_news-0.1.patch | 0 ...add_as.xml_busy_dialog_delay_control.patch | 0 ...s-mark_our_wrapped_functions_as_used.patch | 0 .../xbmc-995.01-xvba_support-d646570.patch | 8625 +++-------------- .../xbmc-995.10-disable-alt-tab.patch | 0 9 files changed, 1121 insertions(+), 7743 deletions(-) delete mode 100644 packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.25-BP-xbmc-PR3166.patch delete mode 100644 packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.26-PR3210.patch rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch (100%) rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-453-add_openelec.tv_RSS_news-0.1.patch (100%) rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-602-add_as.xml_busy_dialog_delay_control.patch (100%) rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch (100%) rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-995.01-xvba_support-d646570.patch (62%) rename packages/mediacenter/xbmc/patches/{13.alpha-2ef8929 => 13.alpha-7f45288}/xbmc-995.10-disable-alt-tab.patch (100%) diff --git a/packages/mediacenter/xbmc/package.mk b/packages/mediacenter/xbmc/package.mk index af9eb704a5..84e97b7cc2 100644 --- a/packages/mediacenter/xbmc/package.mk +++ b/packages/mediacenter/xbmc/package.mk @@ -21,7 +21,7 @@ PKG_NAME="xbmc" PKG_VERSION="12.2-091cb29" if [ "$XBMC" = "master" ]; then - PKG_VERSION="13.alpha-2ef8929" + PKG_VERSION="13.alpha-7f45288" elif [ "$XBMC" = "xbmc-aml" ]; then PKG_VERSION="aml-frodo-d9119f2" fi diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.25-BP-xbmc-PR3166.patch b/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.25-BP-xbmc-PR3166.patch deleted file mode 100644 index 801d170d4e..0000000000 --- a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.25-BP-xbmc-PR3166.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 1501e49f96f75d12ef8071f30ca3338ea18f4ff4 Mon Sep 17 00:00:00 2001 -From: "Chris \"Koying\" Browet" -Date: Sat, 31 Aug 2013 03:04:48 +0200 -Subject: [PATCH] FIX: Consistenly look for fonts in special//home, then - special://xbmc - ---- - xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp | 10 ++++++++-- - xbmc/music/karaoke/karaokelyricstext.cpp | 4 +++- - xbmc/video/windows/GUIWindowFullScreen.cpp | 8 +++++++- - 3 files changed, 18 insertions(+), 4 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp -index 2a4efde..5d7b855 100644 ---- a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp -+++ b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp -@@ -20,6 +20,7 @@ - - #include "DVDSubtitlesLibass.h" - #include "DVDClock.h" -+#include "filesystem/File.h" - #include "filesystem/SpecialProtocol.h" - #include "settings/Settings.h" - #include "utils/log.h" -@@ -75,9 +76,14 @@ static void libass_log(int level, const char *fmt, va_list args, void *data) - if(!m_renderer) - return; - -- //Setting default font to the Arial in \media\fonts (used if FontConfig fails) -- strPath = "special://xbmc/media/Fonts/"; -+ //Setting default font to the Arial in \media\fonts (used if FontConfig fails) -+ strPath = "special://home/media/Fonts/"; - strPath += CSettings::Get().GetString("subtitles.font"); -+ if (!XFILE::CFile::Exists(strPath)) -+ { -+ strPath = "special://xbmc/media/Fonts/"; -+ strPath += CSettings::Get().GetString("subtitles.font"); -+ } - int fc = !CSettings::Get().GetBool("subtitles.overrideassfonts"); - - m_dll.ass_set_margins(m_renderer, 0, 0, 0, 0); -diff --git a/xbmc/music/karaoke/karaokelyricstext.cpp b/xbmc/music/karaoke/karaokelyricstext.cpp -index f04f4c5..f43a188 100644 ---- a/xbmc/music/karaoke/karaokelyricstext.cpp -+++ b/xbmc/music/karaoke/karaokelyricstext.cpp -@@ -139,7 +139,9 @@ bool CKaraokeLyricsText::InitGraphics() - if ( m_lyrics.empty() ) - return false; - -- CStdString fontPath = "special://xbmc/media/Fonts/" + CSettings::Get().GetString("karaoke.font"); -+ CStdString fontPath = "special://home/media/Fonts/" + CSettings::Get().GetString("karaoke.font"); -+ if (!XFILE::CFile::Exists(fontPath)) -+ fontPath = "special://xbmc/media/Fonts/" + CSettings::Get().GetString("karaoke.font"); - m_karaokeFont = g_fontManager.LoadTTF("__karaoke__", fontPath, - m_colorLyrics, 0, CSettings::Get().GetInt("karaoke.fontheight"), FONT_STYLE_BOLD ); - CGUIFont *karaokeBorder = g_fontManager.LoadTTF("__karaokeborder__", fontPath, -diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp -index 9c8526d..bd1e9ed 100644 ---- a/xbmc/video/windows/GUIWindowFullScreen.cpp -+++ b/xbmc/video/windows/GUIWindowFullScreen.cpp -@@ -56,6 +56,7 @@ - #include "pvr/channels/PVRChannelGroupsContainer.h" - #include "windowing/WindowingFactory.h" - #include "cores/IPlayer.h" -+#include "filesystem/File.h" - - #include - #include -@@ -401,8 +402,13 @@ bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) - { - CSingleLock lock (m_fontLock); - -- CStdString fontPath = "special://xbmc/media/Fonts/"; -+ CStdString fontPath = "special://home/media/Fonts/"; - fontPath += CSettings::Get().GetString("subtitles.font"); -+ if (!XFILE::CFile::Exists(fontPath)) -+ { -+ fontPath = "special://xbmc/media/Fonts/"; -+ fontPath += CSettings::Get().GetString("subtitles.font"); -+ } - - // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions. - RESOLUTION_INFO pal(720, 576, 0); --- -1.8.4 - diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.26-PR3210.patch b/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.26-PR3210.patch deleted file mode 100644 index 0260dce214..0000000000 --- a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.26-PR3210.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 67933a247943afe83bb885a5c3881bf03ce0b03b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 7 Sep 2013 18:32:58 +0100 -Subject: [PATCH 1/2] [rendercapture] Fix passthrough rendercapture interface - -The RenderCapture function doesn't behave correctly for passthough video renderers, -and in fact segfaults on Pi when setting a bookmark. - -There is no need to do a glReadPixels to get a video snapshot in the passthrough case, -so provide a shortcut. ---- - xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -index f9f5aa4..ee03b2f 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp -@@ -1421,6 +1421,14 @@ bool CLinuxRendererGLES::RenderCapture(CRenderCapture* capture) - if (!m_bValidated) - return false; - -+ // If rendered directly by the hardware -+ if (m_renderMethod & RENDER_BYPASS) -+ { -+ capture->BeginRender(); -+ capture->EndRender(); -+ return true; -+ } -+ - // save current video rect - CRect saveSize = m_destRect; - saveRotatedCoords();//backup current m_rotatedDestCoords --- -1.8.4 - - -From c02a7e15bfdba2743c9300fa8375cf22a908e8e7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 7 Sep 2013 18:33:32 +0100 -Subject: [PATCH 2/2] [rbp] Support grabbing just the video layer through - rendercapture - -As the bookmark snapshot doesn't want the OSD (and neither does boblight) -allow video, or video + GUI to be selectable. - -While we're there, making the GPU do the red/blue swap and stride packing saves some cpu. - -Requires updated firmware ---- - xbmc/linux/RBP.cpp | 37 ++++++++++--------------------------- - xbmc/linux/RBP.h | 2 +- - xbmc/utils/Screenshot.cpp | 2 +- - 3 files changed, 12 insertions(+), 29 deletions(-) - -diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp -index 21b1e8c..b68fce6 100644 ---- a/xbmc/linux/RBP.cpp -+++ b/xbmc/linux/RBP.cpp -@@ -89,7 +89,7 @@ void CRBP::GetDisplaySize(int &width, int &height) - vc_dispmanx_display_close(display ); - } - --unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue) -+unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only) - { - DISPMANX_DISPLAY_HANDLE_T display; - DISPMANX_RESOURCE_HANDLE_T resource; -@@ -97,6 +97,14 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - unsigned char *image = NULL; - uint32_t vc_image_ptr; - int stride; -+ uint32_t flags = 0; -+ -+ if (video_only) -+ flags |= DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL; -+ if (swap_red_blue) -+ flags |= DISPMANX_SNAPSHOT_SWAP_RED_BLUE; -+ if (!pstride) -+ flags |= DISPMANX_SNAPSHOT_PACK; - - display = vc_dispmanx_display_open( 0 /*screen*/ ); - stride = ((width + 15) & ~15) * 4; -@@ -106,37 +114,12 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw - { - resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr ); - -- vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)0); -+ vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags); - - vc_dispmanx_rect_set(&rect, 0, 0, width, height); - vc_dispmanx_resource_read_data(resource, &rect, image, stride); - vc_dispmanx_resource_delete( resource ); - vc_dispmanx_display_close(display ); -- -- // we need to save in BGRA order so Swap RGBA -> BGRA -- if (swap_red_blue) -- { -- for (int y = 0; y < height; y++) -- { -- unsigned char *p = image + y * stride; -- for (int x = 0; x < width; x++, p+=4) -- { -- unsigned char t = p[0]; -- p[0] = p[2]; -- p[2] = t; -- } -- } -- } -- // assume we need to pack image if caller doesn't want stride -- if (!pstride && stride > width*4) -- { -- for (int y = 0; y < height; y++) -- { -- unsigned char *in = image + y * stride; -- unsigned char *out = image + y * width * 4; -- memmove(out, in, width*4); -- } -- } - } - if (pstride) - *pstride = stride; -diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h -index 58cdf57..58b6f05 100644 ---- a/xbmc/linux/RBP.h -+++ b/xbmc/linux/RBP.h -@@ -51,7 +51,7 @@ class CRBP - int GetGpuMem() { return m_gpu_mem; } - void GetDisplaySize(int &width, int &height); - // stride can be null for packed output -- unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue); -+ unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); - - private: - DllBcmHost *m_DllBcmHost; -diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp -index 05404c9..824c003 100644 ---- a/xbmc/utils/Screenshot.cpp -+++ b/xbmc/utils/Screenshot.cpp -@@ -62,7 +62,7 @@ bool CScreenshotSurface::capture() - { - #if defined(TARGET_RASPBERRY_PI) - g_RBP.GetDisplaySize(m_width, m_height); -- m_buffer = g_RBP.CaptureDisplay(m_width, m_height, &m_stride, true); -+ m_buffer = g_RBP.CaptureDisplay(m_width, m_height, &m_stride, true, false); - if (!m_buffer) - return false; - #elif defined(HAS_DX) --- -1.8.4 - diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-453-add_openelec.tv_RSS_news-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-453-add_openelec.tv_RSS_news-0.1.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-602-add_as.xml_busy_dialog_delay_control.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-602-add_as.xml_busy_dialog_delay_control.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-602-add_as.xml_busy_dialog_delay_control.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-602-add_as.xml_busy_dialog_delay_control.patch diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-990.15-depends-mark_our_wrapped_functions_as_used.patch diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-995.01-xvba_support-d646570.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-995.01-xvba_support-d646570.patch similarity index 62% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-995.01-xvba_support-d646570.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-995.01-xvba_support-d646570.patch index c71f1cca3d..1741a94c75 100644 --- a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-995.01-xvba_support-d646570.patch +++ b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-995.01-xvba_support-d646570.patch @@ -1,7098 +1,7 @@ -From c543e00ea5e60aba45fdcb042bdfc47ae1896e8c Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 2 Aug 2013 18:55:56 +0200 -Subject: [PATCH 01/92] linuxrenderer: do not render if upload texture fails - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 39 ++++++++++++++++----------- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 16 +++++------ - 2 files changed, 31 insertions(+), 24 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 56b54cf..2f3ed4a 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -515,14 +515,14 @@ void CLinuxRendererGL::LoadPlane( YUVPLANE& plane, int type, unsigned flipindex - plane.flipindex = flipindex; - } - --void CLinuxRendererGL::UploadYV12Texture(int source) -+bool CLinuxRendererGL::UploadYV12Texture(int source) - { - YUVBUFFER& buf = m_buffers[source]; - YV12Image* im = &buf.image; - YUVFIELDS& fields = buf.fields; - - if (!(im->flags&IMAGE_FLAG_READY)) -- return; -+ return false; - bool deinterlacing; - if (m_currentField == FIELD_FULL) - deinterlacing = false; -@@ -587,6 +587,7 @@ void CLinuxRendererGL::UploadYV12Texture(int source) - CalculateTextureSourceRects(source, 3); - - glDisable(m_textureTarget); -+ return true; - } - - void CLinuxRendererGL::Reset() -@@ -1183,7 +1184,8 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - m_currentField = FIELD_FULL; - - // call texture load function -- (this->*m_textureUpload)(renderBuffer); -+ if (!(this->*m_textureUpload)(renderBuffer)) -+ return; - - if (m_renderMethod & RENDER_GLSL) - { -@@ -2026,14 +2028,14 @@ bool CLinuxRendererGL::CreateYV12Texture(int index) - //******************************************************************************************************** - // NV12 Texture loading, creation and deletion - //******************************************************************************************************** --void CLinuxRendererGL::UploadNV12Texture(int source) -+bool CLinuxRendererGL::UploadNV12Texture(int source) - { - YUVBUFFER& buf = m_buffers[source]; - YV12Image* im = &buf.image; - YUVFIELDS& fields = buf.fields; - - if (!(im->flags & IMAGE_FLAG_READY)) -- return; -+ return false; - bool deinterlacing; - if (m_currentField == FIELD_FULL) - deinterlacing = false; -@@ -2086,6 +2088,7 @@ void CLinuxRendererGL::UploadNV12Texture(int source) - CalculateTextureSourceRects(source, 3); - - glDisable(m_textureTarget); -+ return true; - } - - bool CLinuxRendererGL::CreateNV12Texture(int index) -@@ -2338,11 +2341,12 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index) - return true; - } - --void CLinuxRendererGL::UploadVDPAUTexture(int index) -+bool CLinuxRendererGL::UploadVDPAUTexture(int index) - { - #ifdef HAVE_LIBVDPAU - glPixelStorei(GL_UNPACK_ALIGNMENT,1); //what's this for? - #endif -+ return true; - } - - -@@ -2406,7 +2410,7 @@ bool CLinuxRendererGL::CreateVAAPITexture(int index) - return true; - } - --void CLinuxRendererGL::UploadVAAPITexture(int index) -+bool CLinuxRendererGL::UploadVAAPITexture(int index) - { - #ifdef HAVE_LIBVA - YUVPLANE &plane = m_buffers[index].fields[0][0]; -@@ -2414,7 +2418,7 @@ void CLinuxRendererGL::UploadVAAPITexture(int index) - VAStatus status; - - if(!va.surface) -- return; -+ return false; - - if(va.display && va.surface->m_display != va.display) - { -@@ -2426,7 +2430,7 @@ void CLinuxRendererGL::UploadVAAPITexture(int index) - CSingleLock lock(*va.display); - - if(va.display->lost()) -- return; -+ return false; - - if(!va.surfglx) - { -@@ -2439,7 +2443,7 @@ void CLinuxRendererGL::UploadVAAPITexture(int index) - if(status != VA_STATUS_SUCCESS) - { - CLog::Log(LOGERROR, "CLinuxRendererGL::UploadVAAPITexture - failed to create vaapi glx surface (%d)", status); -- return; -+ return false; - } - va.surfglx = VAAPI::CSurfaceGLPtr(new VAAPI::CSurfaceGL(surface, va.display)); - } -@@ -2487,12 +2491,13 @@ void CLinuxRendererGL::UploadVAAPITexture(int index) - CLog::Log(LOGERROR, "CLinuxRendererGL::UploadVAAPITexture - failed to copy surface to glx %d - %s", status, vaErrorStr(status)); - - #endif -+ return true; - } - - //******************************************************************************************************** - // CoreVideoRef Texture creation, deletion, copying + clearing - //******************************************************************************************************** --void CLinuxRendererGL::UploadCVRefTexture(int index) -+bool CLinuxRendererGL::UploadCVRefTexture(int index) - { - #ifdef TARGET_DARWIN - CVBufferRef cvBufferRef = m_buffers[index].cvBufferRef; -@@ -2554,6 +2559,7 @@ void CLinuxRendererGL::UploadCVRefTexture(int index) - glDisable(m_textureTarget); - - #endif -+ return true; - } - - void CLinuxRendererGL::DeleteCVRefTexture(int index) -@@ -2615,14 +2621,14 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) - return true; - } - --void CLinuxRendererGL::UploadYUV422PackedTexture(int source) -+bool CLinuxRendererGL::UploadYUV422PackedTexture(int source) - { - YUVBUFFER& buf = m_buffers[source]; - YV12Image* im = &buf.image; - YUVFIELDS& fields = buf.fields; - - if (!(im->flags & IMAGE_FLAG_READY)) -- return; -+ return false; - - bool deinterlacing; - if (m_currentField == FIELD_FULL) -@@ -2659,7 +2665,7 @@ void CLinuxRendererGL::UploadYUV422PackedTexture(int source) - CalculateTextureSourceRects(source, 3); - - glDisable(m_textureTarget); -- -+ return true; - } - - void CLinuxRendererGL::DeleteYUV422PackedTexture(int index) -@@ -3045,14 +3051,14 @@ void CLinuxRendererGL::SetupRGBBuffer() - m_rgbBuffer = new BYTE[m_rgbBufferSize]; - } - --void CLinuxRendererGL::UploadRGBTexture(int source) -+bool CLinuxRendererGL::UploadRGBTexture(int source) - { - YUVBUFFER& buf = m_buffers[source]; - YV12Image* im = &buf.image; - YUVFIELDS& fields = buf.fields; - - if (!(im->flags&IMAGE_FLAG_READY)) -- return; -+ return false; - - bool deinterlacing; - if (m_currentField == FIELD_FULL) -@@ -3155,6 +3161,7 @@ void CLinuxRendererGL::UploadRGBTexture(int source) - CalculateTextureSourceRects(source, 3); - - glDisable(m_textureTarget); -+ return true; - } - - void CLinuxRendererGL::SetTextureFilter(GLenum method) -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index b986d93..b5c4dec 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -178,35 +178,35 @@ class CLinuxRendererGL : public CBaseRenderer - void UpdateVideoFilter(); - - // textures -- void (CLinuxRendererGL::*m_textureUpload)(int index); -+ bool (CLinuxRendererGL::*m_textureUpload)(int index); - void (CLinuxRendererGL::*m_textureDelete)(int index); - bool (CLinuxRendererGL::*m_textureCreate)(int index); - -- void UploadYV12Texture(int index); -+ bool UploadYV12Texture(int index); - void DeleteYV12Texture(int index); - bool CreateYV12Texture(int index); - -- void UploadNV12Texture(int index); -+ bool UploadNV12Texture(int index); - void DeleteNV12Texture(int index); - bool CreateNV12Texture(int index); - -- void UploadVDPAUTexture(int index); -+ bool UploadVDPAUTexture(int index); - void DeleteVDPAUTexture(int index); - bool CreateVDPAUTexture(int index); - -- void UploadVAAPITexture(int index); -+ bool UploadVAAPITexture(int index); - void DeleteVAAPITexture(int index); - bool CreateVAAPITexture(int index); - -- void UploadCVRefTexture(int index); -+ bool UploadCVRefTexture(int index); - void DeleteCVRefTexture(int index); - bool CreateCVRefTexture(int index); - -- void UploadYUV422PackedTexture(int index); -+ bool UploadYUV422PackedTexture(int index); - void DeleteYUV422PackedTexture(int index); - bool CreateYUV422PackedTexture(int index); - -- void UploadRGBTexture(int index); -+ bool UploadRGBTexture(int index); - void ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsigned flipIndexBuf); - void ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, unsigned flipIndexPlaneBot, unsigned flipIndexBuf); - void SetupRGBBuffer(); --- -1.8.4 - - -From c2bb58454a75ab806da153a9c0b3447d2854847d Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sat, 7 Apr 2012 09:19:00 +0200 -Subject: [PATCH 02/92] vdpau: redesign - ---- - language/English/strings.po | 21 +- - system/settings/settings.xml | 10 + - system/shaders/yuv2rgb_basic.glsl | 12 + - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 218 +- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 12 +- - 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 | 6 +- - .../DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 1 - - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 3926 +++++++++++++++----- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 681 +++- - xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 1 + - xbmc/settings/AdvancedSettings.cpp | 8 +- - xbmc/settings/AdvancedSettings.h | 4 +- - xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 2 +- - xbmc/windowing/X11/WinSystemX11.h | 1 + - 19 files changed, 3679 insertions(+), 1236 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index acaa021..ef92431 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5791,7 +5791,17 @@ msgctxt "#13436" - msgid "Allow hardware acceleration (libstagefright)" - msgstr "" - --#empty strings from id 13437 to 13499 -+#: system/settings/settings.xml -+msgctxt "#13437" -+msgid "Allow Vdpau OpenGL interop" -+msgstr "" -+ -+#: system/settings/settings.xml -+msgctxt "#13438" -+msgid "Allow Vdpau OpenGL interop YUV" -+msgstr "" -+ -+#empty strings from id 13439 to 13499 - - #: system/settings/settings.xml - msgctxt "#13500" -@@ -6874,7 +6884,7 @@ msgid "Software Blend" - msgstr "" - - msgctxt "#16325" --msgid "Auto - ION Optimized" -+msgid "VDPAU - Bob" - msgstr "" - - #empty strings from id 16326 to 16399 -@@ -14186,7 +14196,12 @@ msgctxt "#36420" - msgid "No info available yet." - msgstr "" - --#empty strings from id 36421 to 36499 -+#: system/settings/settings.xml -+msgctxt "#36421" -+msgid "Bypassing VDPAU mixer saves resources on low power systems but slightly reduces picture quality" -+msgstr "" -+ -+#empty strings from id 36422 to 36499 - #end reservation - - #: system/settings/settings.xml -diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 56710c7..44a247f 100644 ---- a/system/settings/settings.xml -+++ b/system/settings/settings.xml -@@ -375,6 +375,16 @@ - 2 - true - -+ -+ HAVE_LIBVDPAU -+ 2 -+ true -+ -+ -+ true -+ -+ -+ - - HAVE_LIBVA - 2 -diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl -index 2ce65a1..92b9be7 100644 ---- a/system/shaders/yuv2rgb_basic.glsl -+++ b/system/shaders/yuv2rgb_basic.glsl -@@ -69,6 +69,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 2f3ed4a..42b47e5 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -698,6 +698,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); - -@@ -778,11 +790,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; - } - -@@ -1109,6 +1116,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; -@@ -1551,17 +1564,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[FIELD_FULL][0]; - - glEnable(m_textureTarget); - glActiveTextureARB(GL_TEXTURE0); -- glBindTexture(m_textureTarget, plane.id); - -- vdpau->BindPixmap(); -+ glBindTexture(m_textureTarget, plane.id); - - // make sure we know the correct texture size - GetPlaneTextureSize(plane); -@@ -1623,8 +1631,6 @@ void CLinuxRendererGL::RenderVDPAU(int index, int field) - if (m_pVideoFilterShader) - m_pVideoFilterShader->Disable(); - -- vdpau->ReleasePixmap(); -- - glBindTexture (m_textureTarget, 0); - glDisable(m_textureTarget); - #endif -@@ -2305,12 +2311,10 @@ void CLinuxRendererGL::DeleteNV12Texture(int index) - void CLinuxRendererGL::DeleteVDPAUTexture(int index) - { - #ifdef HAVE_LIBVDPAU -- YUVPLANE &plane = m_buffers[index].fields[0][0]; -+ YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0]; - - SAFE_RELEASE(m_buffers[index].vdpau); - -- if(plane.id && glIsTexture(plane.id)) -- glDeleteTextures(1, &plane.id); - plane.id = 0; - #endif - } -@@ -2320,7 +2324,7 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index) - #ifdef HAVE_LIBVDPAU - YV12Image &im = m_buffers[index].image; - YUVFIELDS &fields = m_buffers[index].fields; -- YUVPLANE &plane = fields[0][0]; -+ YUVPLANE &plane = fields[FIELD_FULL][0]; - - DeleteVDPAUTexture(index); - -@@ -2335,7 +2339,7 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index) - plane.pixpertex_x = 1; - plane.pixpertex_y = 1; - -- glGenTextures(1, &plane.id); -+ plane.id = 1; - - #endif - return true; -@@ -2344,11 +2348,163 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index) - bool CLinuxRendererGL::UploadVDPAUTexture(int index) - { - #ifdef HAVE_LIBVDPAU -- glPixelStorei(GL_UNPACK_ALIGNMENT,1); //what's this for? -+ VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau; -+ -+ unsigned int flipindex = m_buffers[index].flipindex; -+ YV12Image &im = m_buffers[index].image; -+ YUVFIELDS &fields = m_buffers[index].fields; -+ YUVPLANE &plane = fields[FIELD_FULL][0]; -+ -+ if (!vdpau || !vdpau->valid) -+ { -+ return false; -+ } -+ -+ plane.id = vdpau->texture[0]; -+ -+ 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; -+ } -+ - #endif - return true; - } - -+void CLinuxRendererGL::DeleteVDPAUTexture420(int index) -+{ -+#ifdef HAVE_LIBVDPAU -+ YUVFIELDS &fields = m_buffers[index].fields; -+ -+ SAFE_RELEASE(m_buffers[index].vdpau); -+ -+ fields[0][0].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; -+ } -+ -+ plane.id = 1; -+ -+#endif -+ return true; -+} -+ -+bool 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; -+ -+ if (!vdpau || !vdpau->valid) -+ { -+ return false; -+ } -+ -+ im.height = vdpau->texHeight; -+ im.width = vdpau->texWidth; -+ -+ // YUV -+ for (int f = FIELD_TOP; f<=FIELD_BOT ; f++) -+ { -+ YUVPLANES &planes = fields[f]; -+ -+ planes[0].texwidth = im.width; -+ planes[0].texheight = im.height >> 1; -+ -+ 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[1][2].id = vdpau->texture[2]; -+ fields[2][0].id = vdpau->texture[1]; -+ fields[2][1].id = vdpau->texture[3]; -+ fields[2][2].id = vdpau->texture[3]; -+ -+ glEnable(m_textureTarget); -+ for (int f = FIELD_TOP; f <= FIELD_BOT; 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(); -+ } -+ } -+ CalculateTextureSourceRects(index, 3); -+ glDisable(m_textureTarget); -+ -+#endif -+ return true; -+} - - void CLinuxRendererGL::DeleteVAAPITexture(int index) - { -@@ -3274,12 +3430,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; - } -@@ -3372,14 +3529,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; -@@ -3424,6 +3574,7 @@ void CLinuxRendererGL::UnBindPbo(YUVBUFFER& buff) - unsigned int CLinuxRendererGL::GetProcessorSize() - { - if(m_format == RENDER_FMT_VDPAU -+ || m_format == RENDER_FMT_VDPAU_420 - || m_format == RENDER_FMT_VAAPI - || m_format == RENDER_FMT_CVBREF) - return 1; -@@ -3432,11 +3583,12 @@ unsigned int CLinuxRendererGL::GetProcessorSize() - } - - #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 b5c4dec..8daf72c 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -39,12 +39,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)) -@@ -143,7 +142,7 @@ class CLinuxRendererGL : public CBaseRenderer - virtual unsigned int GetProcessorSize(); - - #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); -@@ -194,6 +193,10 @@ class CLinuxRendererGL : public CBaseRenderer - void DeleteVDPAUTexture(int index); - bool CreateVDPAUTexture(int index); - -+ bool UploadVDPAUTexture420(int index); -+ void DeleteVDPAUTexture420(int index); -+ bool CreateVDPAUTexture420(int index); -+ - bool UploadVAAPITexture(int index); - void DeleteVAAPITexture(int index); - bool CreateVAAPITexture(int index); -@@ -220,6 +223,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 -@@ -280,7 +284,7 @@ class CLinuxRendererGL : public CBaseRenderer - GLuint pbo[MAX_PLANES]; - - #ifdef HAVE_LIBVDPAU -- CVDPAU* vdpau; -+ VDPAU::CVdpauRenderPicture *vdpau; - #endif - #ifdef HAVE_LIBVA - VAAPI::CHolder& vaapi; -diff --git a/xbmc/cores/VideoRenderers/RenderFormats.h b/xbmc/cores/VideoRenderers/RenderFormats.h -index 29d45e0..3b09194 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 0d32715..fbc2aae 100644 ---- a/xbmc/cores/VideoRenderers/RenderManager.cpp -+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp -@@ -917,7 +917,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 00fe4c3..28596cf 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 ad1940c..48302ff 100644 ---- a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp -+++ b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp -@@ -214,6 +214,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 a16ac4b..87edaa5 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; -@@ -57,7 +57,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 b09ac29..143675a 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp -@@ -75,11 +75,11 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx - while(*cur != PIX_FMT_NONE) - { - #ifdef HAVE_LIBVDPAU -- if(CVDPAU::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("videoplayer.usevdpau")) -+ if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("videoplayer.usevdpau")) - { - 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; -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -index c509339..2287031 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h -@@ -29,7 +29,6 @@ - #include "DllAvFilter.h" - #include "DllPostProc.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 f830f61..c10c7ea 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -33,11 +33,16 @@ - #include "settings/MediaSettings.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}, -@@ -51,14 +56,7 @@ - {"MPEG4_PART2_ASP", VDP_DECODER_PROFILE_MPEG4_PART2_ASP}, - #endif - }; --const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CVDPAU::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} --}; -+const size_t decoder_profile_count = sizeof(decoder_profiles)/sizeof(CDecoder::Desc); - - static struct SInterlaceMapping - { -@@ -69,114 +67,34 @@ - , {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} - }; - -+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} -+ - //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() --{ -- 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; -+//----------------------------------------------------------------------------- -+// CVDPAU -+//----------------------------------------------------------------------------- - -- m_glPixmap = 0; -- m_Pixmap = 0; -- if (!glXBindTexImageEXT) -- glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); -- if (!glXReleaseTexImageEXT) -- glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXReleaseTexImageEXT"); -+CDecoder::CDecoder() : m_vdpauOutput(&m_inMsgEvent) -+{ -+ m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; -+ m_vdpauConfig.videoSurfaces = &m_videoSurfaces; -+ m_vdpauConfig.videoSurfaceSec = &m_videoSurfaceSec; - -- totalAvailableOutputSurfaces = 0; -- outputSurface = presentSurface = VDP_INVALID_HANDLE; -- 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; -- past[0] = NULL; -- past[1] = NULL; -- current = NULL; -- future = NULL; -- tmpNoiseReduction = 0.0f; -- tmpSharpness = 0.0f; -- vdp_get_proc_address = NULL; -- vdp_device_destroy = NULL; -- vdp_video_surface_create = NULL; -- vdp_video_surface_destroy = NULL; -- vdp_video_surface_put_bits_y_cb_cr = NULL; -- vdp_video_surface_get_bits_y_cb_cr = NULL; -- vdp_output_surface_put_bits_y_cb_cr = NULL; -- vdp_output_surface_put_bits_native = NULL; -- vdp_output_surface_create = NULL; -- vdp_output_surface_destroy = NULL; -- vdp_output_surface_get_bits_native = NULL; -- vdp_output_surface_render_output_surface = NULL; -- vdp_output_surface_put_bits_indexed = NULL; -- vdp_video_mixer_create = NULL; -- vdp_video_mixer_set_feature_enables = NULL; -- vdp_video_mixer_query_parameter_support = NULL; -- vdp_video_mixer_query_feature_support = NULL; -- vdp_video_mixer_destroy = NULL; -- vdp_video_mixer_render = NULL; -+ m_vdpauConfigured = false; - m_hwContext.bitstream_buffers_allocated = 0; -+ m_DisplayState = VDPAU_OPEN; - } - --bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) -+bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) - { - if(avctx->coded_width == 0 - || avctx->coded_height == 0) -@@ -184,6 +102,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 ((avctx->codec_id == AV_CODEC_ID_MPEG4) && !g_advancedSettings.m_videoAllowMpeg4VDPAU) - return false; -@@ -198,8 +118,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; - } - } -@@ -208,8 +126,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(); - -@@ -227,28 +146,26 @@ 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 */ - memset(&m_hwContext, 0, sizeof(AVVDPAUContext)); -- m_hwContext.render = CVDPAU::Render; -+ m_hwContext.render = CDecoder::Render; - m_hwContext.bitstream_buffers_allocated = 0; -- 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; - avctx->hwaccel_context = &m_hwContext; - avctx->thread_count = 1; -@@ -259,17 +176,22 @@ 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__); - -+ g_Windowing.Unregister(this); -+ -+ CSingleLock lock(m_DecoderSection); -+ - FiniVDPAUOutput(); - FiniVDPAUProcs(); -+ m_vdpauOutput.Dispose(); - - while (!m_videoSurfaces.empty()) - { -@@ -286,192 +208,114 @@ void CVDPAU::Close() - m_dllAvUtil.av_freep(&m_hwContext.bitstream_buffers); - } - -- g_Windowing.Unregister(this); - 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); -+ return 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; - } - -@@ -485,16 +329,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(); -@@ -509,7 +350,7 @@ int CVDPAU::Check(AVCodecContext* avctx) - return 0; - } - --bool CVDPAU::IsVDPAUFormat(PixelFormat format) -+bool CDecoder::IsVDPAUFormat(PixelFormat format) - { - if (format == AV_PIX_FMT_VDPAU) - return true; -@@ -517,90 +358,28 @@ bool CVDPAU::IsVDPAUFormat(PixelFormat format) - 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_video_mixer_create(vdp_device, -- m_feature_count, -- m_features, -- ARSIZE(parameters), -- parameters, -- parameter_values, -- &videoMixer); -- CheckStatus(vdp_st, __LINE__); -- -- SetHWUpscaling(); -- } -- -- if (tmpBrightness != CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness || -- tmpContrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast) -- { -- SetColor(); -- tmpBrightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness; -- tmpContrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast; -- } -- if (tmpNoiseReduction != CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction) -- { -- tmpNoiseReduction = CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction; -- SetNoiseReduction(); -- } -- if (tmpSharpness != CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness) -- { -- tmpSharpness = CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness; -- SetSharpness(); -- } -- if ( tmpDeintMode != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode || -- tmpDeintGUI != CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod || -- (tmpDeintGUI == VS_INTERLACEMETHOD_AUTO && tmpDeint != AutoInterlaceMethod())) -- { -- tmpDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -- tmpDeintGUI = CMediaSettings::Get().GetCurrentVideoSettings().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 (CSettings::Get().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) -@@ -609,162 +388,12 @@ bool CVDPAU::Supports(EINTERLACEMETHOD method) - return false; - } - --EINTERLACEMETHOD CVDPAU::AutoInterlaceMethod() --{ -- return VS_INTERLACEMETHOD_VDPAU_TEMPORAL; --} -- --void CVDPAU::SetColor() --{ -- VdpStatus vdp_st; -- -- if (tmpBrightness != CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness) -- m_Procamp.brightness = (float)((CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness)-50) / 100; -- if (tmpContrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast) -- m_Procamp.contrast = (float)((CMediaSettings::Get().GetCurrentVideoSettings().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 (CSettings::Get().GetBool("videoscreen.limitedrange")) -- { -- 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 (!CMediaSettings::Get().GetCurrentVideoSettings().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[] = { &CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction }; -- CLog::Log(LOGNOTICE,"Setting Noise Reduction to %f",CMediaSettings::Get().GetCurrentVideoSettings().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 (!CMediaSettings::Get().GetCurrentVideoSettings().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[] = { &CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness }; -- CLog::Log(LOGNOTICE,"Setting Sharpness to %f",CMediaSettings::Get().GetCurrentVideoSettings().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 = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -- EINTERLACEMETHOD method = CMediaSettings::Get().GetCurrentVideoSettings().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; - -@@ -774,151 +403,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() - { -- 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; -+ if (m_vdpauConfig.vdpDevice == VDP_INVALID_HANDLE || !m_vdpauConfigured) return; - - CLog::Log(LOGNOTICE, " (VDPAU) %s", __FUNCTION__); - -+ // uninit output -+ m_vdpauOutput.Dispose(); -+ m_vdpauConfigured = false; -+ - VdpStatus vdp_st; - -- vdp_st = vdp_decoder_destroy(decoder); -+ vdp_st = m_vdpauConfig.vdpProcs.vdp_decoder_destroy(m_vdpauConfig.vdpDecoder); - if (CheckStatus(vdp_st, __LINE__)) - return; -- decoder = VDP_INVALID_HANDLE; -+ m_vdpauConfig.vdpDecoder = VDP_INVALID_HANDLE; - -- for (unsigned int i = 0; i < m_videoSurfaces.size(); ++i) -+ 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) - { - 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__)) -@@ -926,10 +519,9 @@ void CVDPAU::FiniVDPAUOutput() - } - } - -- --void CVDPAU::ReadFormatOf( AVCodecID codec -- , VdpDecoderProfile &vdp_decoder_profile -- , VdpChromaType &vdp_chroma_type) -+void CDecoder::ReadFormatOf( AVCodecID codec -+ , VdpDecoderProfile &vdp_decoder_profile -+ , VdpChromaType &vdp_chroma_type) - { - switch (codec) - { -@@ -941,7 +533,7 @@ void CVDPAU::ReadFormatOf( AVCodecID codec - vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; -- case AV_CODEC_ID_H264: -+ case AV_CODEC_ID_H264: - vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; -@@ -953,12 +545,10 @@ void CVDPAU::ReadFormatOf( AVCodecID codec - vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED; - vdp_chroma_type = VDP_CHROMA_TYPE_420; - break; --#if (defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP) - case AV_CODEC_ID_MPEG4: - 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; -@@ -966,170 +556,87 @@ void CVDPAU::ReadFormatOf( AVCodecID codec - } - } - -- --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->codec_id, 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->codec_id, vdp_decoder_profile, m_vdpauConfig.vdpChromaType); - - if(avctx->codec_id == AV_CODEC_ID_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; -+ if (success) -+ { -+ CVdpauConfig *data; -+ data = (CVdpauConfig*)reply->data; -+ if (data) -+ { -+ m_vdpauConfig.usePixmaps = data->usePixmaps; -+ } -+ } -+ 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:"); -@@ -1139,7 +646,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) - { -@@ -1148,13 +655,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) - -@@ -1178,7 +685,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); -@@ -1205,34 +712,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; -+ } - } - } - -@@ -1241,21 +747,22 @@ int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) - { - // create a new surface - VdpDecoderProfile profile; -- ReadFormatOf(avctx->codec_id, profile, vdp->vdp_chroma_type); -+ ReadFormatOf(avctx->codec_id, 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); -@@ -1274,18 +781,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; -@@ -1293,15 +788,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) -@@ -1310,6 +806,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; - -@@ -1323,29 +821,26 @@ void CVDPAU::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) - render->state &= ~FF_VDPAU_STATE_USED_FOR_REFERENCE; - } - --VdpStatus CVDPAU::Render(VdpDecoder decoder, VdpVideoSurface target, -- VdpPictureInfo const *picture_info, -- uint32_t bitstream_buffer_count, -- VdpBitstreamBuffer const * bitstream_buffers) -+VdpStatus CDecoder::Render( VdpDecoder decoder, VdpVideoSurface target, -+ VdpPictureInfo const *picture_info, -+ uint32_t bitstream_buffer_count, -+ VdpBitstreamBuffer const * bitstream_buffers) - { - return VDP_STATUS_OK; - } - --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]) -@@ -1375,67 +870,50 @@ void CVDPAU::FFDrawSlice(struct AVCodecContext *s, - if(s->codec_id == AV_CODEC_ID_H264) - max_refs = vdp->m_hwContext.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 *)&(vdp->m_hwContext.info), - vdp->m_hwContext.bitstream_buffers_used, - vdp->m_hwContext.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 = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -- EINTERLACEMETHOD method = CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod; -- if (method == VS_INTERLACEMETHOD_AUTO) -- method = AutoInterlaceMethod(); -- - if(pFrame) - { // we have a new frame from decoder - -- vdpau_render_state * render = (vdpau_render_state*)pFrame->data[2]; -- if(!render) // old style ffmpeg gave data on plane 0 -- render = (vdpau_render_state*)pFrame->data[0]; -+ vdpau_render_state * 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)) -@@ -1444,258 +922,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(); -+ } -+ -+ m_bufferStats.Get(decoded, processed, render); - -- if (mode == VS_DEINTERLACEMODE_FORCE -- || (mode == VS_DEINTERLACEMODE_AUTO && m_DVDVideoPics.front().iFlags & DVP_FLAG_INTERLACED)) -+ 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_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; -- } -+ CSingleLock lock(m_DecoderSection); - -- *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(); -- -- 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) - { -@@ -1713,4 +1099,2508 @@ 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(); -+} -+ -+bool CMixer::IsActive() -+{ -+ return IsRunning(); -+} -+ -+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 = NULL; -+ Protocol *port = NULL; -+ 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) -+{ -+ 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 != CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness || -+ m_Contrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast) -+ { -+ SetColor(); -+ m_Brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness; -+ m_Contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast; -+ } -+ if (m_NoiseReduction != CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction) -+ { -+ m_NoiseReduction = CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction; -+ SetNoiseReduction(); -+ } -+ if (m_Sharpness != CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness) -+ { -+ m_Sharpness = CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness; -+ SetSharpness(); -+ } -+ if (m_DeintMode != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode || -+ m_Deint != CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod) -+ { -+ m_DeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode; -+ m_Deint = CMediaSettings::Get().GetCurrentVideoSettings().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 != CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness) -+ m_Procamp.brightness = (float)((CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness)-50) / 100; -+ if (m_Contrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast) -+ m_Procamp.contrast = (float)((CMediaSettings::Get().GetCurrentVideoSettings().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 (CSettings::Get().GetBool("videoscreen.limitedrange")) -+ { -+ 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 (!CMediaSettings::Get().GetCurrentVideoSettings().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[] = { &CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction }; -+ CLog::Log(LOGNOTICE,"Setting Noise Reduction to %f",CMediaSettings::Get().GetCurrentVideoSettings().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 (!CMediaSettings::Get().GetCurrentVideoSettings().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[] = { &CMediaSettings::Get().GetCurrentVideoSettings().m_Sharpness }; -+ CLog::Log(LOGNOTICE,"Setting Sharpness to %f",CMediaSettings::Get().GetCurrentVideoSettings().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 = CMediaSettings::Get().GetCurrentVideoSettings().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 = CMediaSettings::Get().GetCurrentVideoSettings().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 = CSettings::Get().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 = CSettings::Get().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 = CMediaSettings::Get().GetCurrentVideoSettings().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; -+} -+ -+//----------------------------------------------------------------------------- -+// Buffer Pool -+//----------------------------------------------------------------------------- -+ -+VdpauBufferPool::VdpauBufferPool() -+{ -+ CVdpauRenderPicture *pic; -+ for (unsigned int i = 0; i < NUM_RENDER_PICS; i++) -+ { -+ pic = new CVdpauRenderPicture(renderPicSec); -+ allRenderPics.push_back(pic); -+ } -+} -+ -+VdpauBufferPool::~VdpauBufferPool() -+{ -+ CVdpauRenderPicture *pic; -+ for (unsigned int i = 0; i < NUM_RENDER_PICS; i++) -+ { -+ pic = allRenderPics[i]; -+ delete pic; -+ } -+ allRenderPics.clear(); -+} -+ -+//----------------------------------------------------------------------------- -+// 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; -+ -+ for (unsigned int i = 0; i < m_bufferPool.allRenderPics.size(); ++i) -+ { -+ m_bufferPool.freeRenderPics.push_back(i); -+ } -+} -+ -+void COutput::Start() -+{ -+ Create(); -+} -+ -+COutput::~COutput() -+{ -+ Dispose(); -+ -+ m_bufferPool.freeRenderPics.clear(); -+ m_bufferPool.usedRenderPics.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, &m_config, sizeof(m_config)); -+ } -+ 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(); -+ PreCleanup(); -+ 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: -+ 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 = NULL; -+ Protocol *port = NULL; -+ 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() -+{ -+ if (m_mixer.IsActive()) -+ { -+ 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) -+ { -+ CVdpauRenderPicture *pic = m_bufferPool.allRenderPics[*it]; -+ if (pic->DVDPic.format == RENDER_FMT_VDPAU_420) -+ { -+ std::map::iterator it2; -+ it2 = m_bufferPool.glVideoSurfaceMap.find(pic->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 = NULL; -+ -+ 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(i); -+ 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; -+ int idx = m_bufferPool.notVisiblePixmaps.front(); -+ VdpauBufferPool::Pixmaps *pixmap = &m_bufferPool.pixmaps[idx]; -+ 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) -+ { -+ int idx = m_bufferPool.freeRenderPics.front(); -+ retPic = m_bufferPool.allRenderPics[idx]; -+ m_bufferPool.freeRenderPics.pop_front(); -+ m_bufferPool.usedRenderPics.push_back(idx); -+ 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()) -+ { -+ int idx = m_bufferPool.freeRenderPics.front(); -+ retPic = m_bufferPool.allRenderPics[idx]; -+ m_bufferPool.freeRenderPics.pop_front(); -+ m_bufferPool.usedRenderPics.push_back(idx); -+ 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; -+ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) -+ { -+ if (m_bufferPool.allRenderPics[*it] == pic) -+ { -+ break; -+ } -+ } -+ -+ if (it == m_bufferPool.usedRenderPics.end()) -+ { -+ CLog::Log(LOGWARNING, "COutput::ProcessReturnPicture - pic not found"); -+ return; -+ } -+ m_bufferPool.freeRenderPics.push_back(*it); -+ m_bufferPool.usedRenderPics.erase(it); -+ 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; -+ unsigned 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.allRenderPics[m_bufferPool.usedRenderPics[i]]->valid = false; -+ } -+} -+ -+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; -+ CVdpauRenderPicture *pic; -+ for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) -+ { -+ pic = m_bufferPool.allRenderPics[*it]; -+ if ((pic->sourceIdx == m_bufferPool.outputSurfaces[i]) && pic->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) -+ { -+ 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 = !CSettings::Get().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; -+ CSettings::Get().SetBool("videoplayer.usevdpauinterop",false); -+ CSettings::Get().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 (unsigned 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 (unsigned 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; -+ -+ 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 e760f28..aae4173 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-2013 Team XBMC - * http://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,124 +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"; } -- -- virtual unsigned GetAllowedReferences() { return 2; /* this is a lie, we can only do one, but we block on decode to get the surface */ } -- -- 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); -- static VdpStatus Render(VdpDecoder decoder, VdpVideoSurface target, -- VdpPictureInfo const *picture_info, -- uint32_t bitstream_buffer_count, -- VdpBitstreamBuffer const * bitstream_buffers); -- -- 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); -- -- void CheckFeatures(); -- void SetColor(); -- void SetNoiseReduction(); -- void SetSharpness(); -- void SetDeinterlacing(); -- void SetHWUpscaling(); -+#include "threads/Thread.h" -+#include "utils/ActorProtocol.h" - -- 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; -+using namespace Actor; - -- 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; -@@ -164,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; -@@ -185,65 +113,470 @@ 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; -+}; -+ -+//----------------------------------------------------------------------------- -+// VDPAU data structs -+//----------------------------------------------------------------------------- - -- VdpDecoder decoder; -- VdpVideoMixer videoMixer; -- VdpRect outRect; -- VdpRect outRectVid; -+class CDecoder; - -- 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); -+/** -+ * Buffer statistics used to control number of frames in queue -+ */ - -- 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; -+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 codecFlags; -+ 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 flags) { CSingleLock l(m_sec); latency = time; codecFlags = flags; } -+ void GetParams(uint64_t &lat, int &flags) { CSingleLock l(m_sec); lat = latency; flags = codecFlags; } -+ 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: -+ CVdpauRenderPicture(CCriticalSection §ion) -+ : renderPicSection(section), refCount(0) {} -+ 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(); -+ bool IsActive(); -+ 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 -+{ -+ VdpauBufferPool(); -+ virtual ~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; -+ }; -+ std::vector allRenderPics; -+ unsigned short numOutputSurfaces; -+ std::vector pixmaps; -+ std::vector outputSurfaces; -+ std::deque notVisiblePixmaps; -+ 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 PreCleanup(); -+ 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 unsigned GetAllowedReferences() { return 5; } -+ -+ 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); -+ static VdpStatus Render( VdpDecoder decoder, VdpVideoSurface target, -+ VdpPictureInfo const *picture_info, -+ uint32_t bitstream_buffer_count, -+ VdpBitstreamBuffer const * bitstream_buffers); -+ -+ 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( AVCodecID codec - , VdpDecoderProfile &decoder_profile - , VdpChromaType &chroma_type); - -- std::vector m_videoSurfaces; -- AVVDPAUContext m_hwContext; -- 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 -@@ -254,9 +587,25 @@ 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; -+ AVVDPAUContext m_hwContext; -+ 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 bcfd27c..d35751c 100644 ---- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -992,6 +992,7 @@ static std::string GetRenderFormatName(ERenderFormat format) - case RENDER_FMT_UYVY422: return "UYVY"; - case RENDER_FMT_YUYV422: return "YUY2"; - case RENDER_FMT_VDPAU: return "VDPAU"; -+ case RENDER_FMT_VDPAU_420: return "VDPAU_420"; - case RENDER_FMT_DXVA: return "DXVA"; - case RENDER_FMT_VAAPI: return "VAAPI"; - case RENDER_FMT_OMXEGL: return "OMXEGL"; -diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index 374393d..f47a80b 100644 ---- a/xbmc/settings/AdvancedSettings.cpp -+++ b/xbmc/settings/AdvancedSettings.cpp -@@ -160,7 +160,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; -@@ -168,6 +168,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; -@@ -592,7 +594,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); -@@ -601,6 +603,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* pStagefrightElem = pElement->FirstChildElement("stagefright"); - if (pStagefrightElem) -diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h -index 1de9af7..0d792af 100644 ---- a/xbmc/settings/AdvancedSettings.h -+++ b/xbmc/settings/AdvancedSettings.h -@@ -157,6 +157,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - int m_videoPercentSeekBackwardBig; - CStdString m_videoPPFFmpegDeint; - CStdString m_videoPPFFmpegPostProc; -+ bool m_videoVDPAUtelecine; -+ bool m_videoVDPAUdeintSkipChromaHD; - bool m_musicUseTimeSeeking; - int m_musicTimeSeekForward; - int m_musicTimeSeekBackward; -@@ -172,7 +174,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler - 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/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -index a27aed3..8f30248 100644 ---- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp -@@ -108,7 +108,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 a0f7bba..b6b6ec4 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.4 - - -From bb2b78823eddcfe6735f5d7706a52327c6c3658c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 09:52:17 +0100 -Subject: [PATCH 03/92] vdpau: make interop gl default and remove setting, - rename and intvert interop yuv - ---- - language/English/strings.po | 9 ++------- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 17 ++++++++++------- - 2 files changed, 12 insertions(+), 14 deletions(-) - -diff --git a/language/English/strings.po b/language/English/strings.po -index ef92431..b6eee02 100644 ---- a/language/English/strings.po -+++ b/language/English/strings.po -@@ -5793,15 +5793,10 @@ msgstr "" - - #: system/settings/settings.xml - msgctxt "#13437" --msgid "Allow Vdpau OpenGL interop" -+msgid "Prefer VDPAU Video Mixer" - msgstr "" - --#: system/settings/settings.xml --msgctxt "#13438" --msgid "Allow Vdpau OpenGL interop YUV" --msgstr "" -- --#empty strings from id 13439 to 13499 -+#empty strings from id 13438 to 13499 - - #: system/settings/settings.xml - msgctxt "#13500" -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index c10c7ea..41defb6 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -374,12 +374,15 @@ bool CDecoder::Supports(EINTERLACEMETHOD method) - || method == VS_INTERLACEMETHOD_AUTO) - return true; - -- if (CSettings::Get().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) -@@ -1869,7 +1872,7 @@ void CMixer::SetDeinterlacing() - - SetDeintSkipChroma(); - -- m_config.useInteropYuv = CSettings::Get().GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !CSettings::Get().GetBool("videoplayer.usevdpaumixer"); - } - - void CMixer::SetDeintSkipChroma() -@@ -2061,7 +2064,7 @@ void CMixer::Init() - m_vdpError = false; - - m_config.upscale = g_advancedSettings.m_videoVDPAUScaling; -- m_config.useInteropYuv = CSettings::Get().GetBool("videoplayer.usevdpauinteropyuv"); -+ m_config.useInteropYuv = !CSettings::Get().GetBool("videoplayer.usevdpaumixer"); - - CreateVdpauMixer(); - } -@@ -2171,11 +2174,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 - { -@@ -3288,7 +3292,7 @@ bool COutput::GLInit() - glVDPAUGetSurfaceivNV = NULL; - #endif - -- m_config.usePixmaps = !CSettings::Get().GetBool("videoplayer.usevdpauinterop"); -+ m_config.usePixmaps = false; - - #ifdef GL_NV_vdpau_interop - if (glewIsSupported("GL_NV_vdpau_interop")) -@@ -3320,8 +3324,7 @@ bool COutput::GLInit() - #endif - { - m_config.usePixmaps = true; -- CSettings::Get().SetBool("videoplayer.usevdpauinterop",false); -- CSettings::Get().SetBool("videoplayer.usevdpauinteropyuv",false); -+ CSettings::Get().SetBool("videoplayer.usevdpaumixer",true); - } - if (!glXBindTexImageEXT) - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *) "glXBindTexImageEXT"); --- -1.8.4 - - -From 06848e8c20883f45cb7cdc84e9530dc685c19da4 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 12 Dec 2012 20:28:49 +0100 -Subject: [PATCH 04/92] 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 41defb6..8a31cd1 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -934,6 +934,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)); - -@@ -1544,10 +1545,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() -@@ -1558,11 +1555,13 @@ void CMixer::CheckFeatures() - m_Upscale = m_config.upscale; - } - if (m_Brightness != CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness || -- m_Contrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast) -+ m_Contrast != CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast || -+ m_ColorMatrix != m_mixerInput[1].DVDPic.color_matrix) - { - SetColor(); - m_Brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness; - m_Contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast; -+ m_ColorMatrix = m_mixerInput[1].DVDPic.color_matrix; - } - if (m_NoiseReduction != CMediaSettings::Get().GetCurrentVideoSettings().m_NoiseReduction) - { -@@ -1713,13 +1712,27 @@ void CMixer::SetColor() - m_Procamp.contrast = (float)((CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast)+50) / 100; - - VdpColorStandard colorStandard; --// if(vid_height >= 600 || vid_width > 1024) -- if(m_config.surfaceWidth > 1000) -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_709, &m_CSCMatrix); -- else -- colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -- //vdp_st = vdp_generate_csc_matrix(&m_Procamp, VDP_COLOR_STANDARD_ITUR_BT_601, &m_CSCMatrix); -+ switch(m_mixerInput[1].DVDPic.color_matrix) -+ { -+ case AVCOL_SPC_BT709: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ break; -+ case AVCOL_SPC_BT470BG: -+ case AVCOL_SPC_SMPTE170M: -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ break; -+ case AVCOL_SPC_SMPTE240M: -+ colorStandard = VDP_COLOR_STANDARD_SMPTE_240M; -+ break; -+ case AVCOL_SPC_FCC: -+ case AVCOL_SPC_UNSPECIFIED: -+ case AVCOL_SPC_RGB: -+ default: -+ if(m_config.surfaceWidth > 1000) -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_709; -+ else -+ colorStandard = VDP_COLOR_STANDARD_ITUR_BT_601; -+ } - - VdpVideoMixerAttribute attributes[] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX }; - if (CSettings::Get().GetBool("videoscreen.limitedrange")) -@@ -2060,6 +2073,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 aae4173..8845a16 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -337,6 +337,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.4 - - -From 6fa723db3a2892f04c69153e71d9c379523d873c Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Sun, 27 Jan 2013 12:10:19 +0100 -Subject: [PATCH 05/92] 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 8a31cd1..6d982a7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2151,8 +2151,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.4 - - -From 8ee700bbcbb04ee7f169809a5119bf9ad37cb21e Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 12:14:15 +0200 -Subject: [PATCH 06/92] 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 42b47e5..daadcd6 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -1212,7 +1212,8 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - break; - - case RQ_MULTIPASS: -- RenderMultiPass(renderBuffer, m_currentField); -+ RenderToFBO(renderBuffer, m_currentField); -+ RenderFromFBO(); - VerifyGLState(); - break; - } -@@ -1335,12 +1336,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 8daf72c..b086bae 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -217,7 +217,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.4 - - -From a07e6cc04e50d655fa84b524788bcea73dda86e3 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Tue, 25 Sep 2012 13:20:47 +0200 -Subject: [PATCH 07/92] linuxrenderer: implement progressive weave for vdpau - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 56 +++++++++++++++++++-------- - xbmc/cores/VideoRenderers/LinuxRendererGL.h | 4 +- - 2 files changed, 42 insertions(+), 18 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index daadcd6..1dbb670 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -698,18 +698,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); - -@@ -1207,13 +1195,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; - } -@@ -1336,7 +1332,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]; - -@@ -1438,6 +1434,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); -@@ -1556,6 +1554,32 @@ void CLinuxRendererGL::RenderFromFBO() - VerifyGLState(); - } - -+void CLinuxRendererGL::RenderProgressiveWeave(int index, int field) -+{ -+ bool scale = (int)m_sourceHeight != m_destRect.Height() || -+ (int)m_sourceWidth != m_destRect.Width(); -+ -+ if (m_fbo.fbo.IsSupported() && (scale || 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 b086bae..966733e 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -217,12 +217,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.4 - - -From 46c43a9cb30c3cb91affbba2e65398b0bb144140 Mon Sep 17 00:00:00 2001 -From: xbmc -Date: Wed, 6 Mar 2013 07:35:10 +0100 -Subject: [PATCH 08/92] 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 6d982a7..9ac8186 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2198,13 +2198,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); -+ -+ CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod = VS_INTERLACEMETHOD_AUTO; - } - } - else --- -1.8.4 - - -From 66c57b07b74e18a8d810adc5981ea653ee24689f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 14 Jun 2013 09:23:22 +0200 -Subject: [PATCH 09/92] vdpau: calculate timestamp of second field when doing - deinterlacing - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 9ac8186..369a19e 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -2321,7 +2321,15 @@ void CMixer::ProcessPicture() - futu_surfaces[0] = m_mixerInput[1].render->surface; - futu_surfaces[1] = m_mixerInput[1].render->surface; - -- m_processPicture.DVDPic.pts = DVD_NOPTS_VALUE; -+ if (m_mixerInput[0].DVDPic.pts != DVD_NOPTS_VALUE && -+ m_mixerInput[1].DVDPic.pts != DVD_NOPTS_VALUE) -+ { -+ m_processPicture.DVDPic.pts = m_mixerInput[1].DVDPic.pts + -+ (m_mixerInput[0].DVDPic.pts - -+ m_mixerInput[1].DVDPic.pts) / 2; -+ } -+ else -+ m_processPicture.DVDPic.pts = DVD_NOPTS_VALUE; - m_processPicture.DVDPic.dts = DVD_NOPTS_VALUE; - } - m_processPicture.DVDPic.iRepeatPicture = 0.0; --- -1.8.4 - - -From 312628992e0479f46a2dd9af367d6c2d61bee2c9 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 2 Aug 2013 13:57:47 +0200 -Subject: [PATCH 10/92] vdpau: comment some features that will be added later - ---- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 369a19e..ae7cce7 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -938,7 +938,8 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) - m_bufferStats.IncDecoded(); - m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); - -- m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); -+ //TODO -+ // m_codecControl = pic.DVDPic.iFlags & (DVP_FLAG_DRAIN | DVP_FLAG_NO_POSTPROC); - } - - int retval = 0; -@@ -993,7 +994,8 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) - msg->Release(); - } - -- if ((m_codecControl & DVP_FLAG_DRAIN)) -+ // TODO -+ if (1) //(m_codecControl & DVP_FLAG_DRAIN)) - { - if (decoded + processed + render < 4) - { -@@ -2140,7 +2142,8 @@ void CMixer::InitCycle() - int flags; - m_config.stats->GetParams(latency, flags); - latency = (latency*1000)/CurrentHostFrequency(); -- if (flags & DVP_FLAG_NO_POSTPROC) -+ // TODO -+ if (0) //flags & DVP_FLAG_NO_POSTPROC) - SetPostProcFeatures(false); - else - SetPostProcFeatures(true); -@@ -2151,7 +2154,8 @@ void CMixer::InitCycle() - EINTERLACEMETHOD method = GetDeinterlacingMethod(); - bool interlaced = m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_INTERLACED; - -- if (!(flags & DVP_FLAG_NO_POSTPROC) && -+ // TODO -+ if (//!(flags & DVP_FLAG_NO_POSTPROC) && - (mode == VS_DEINTERLACEMODE_FORCE || - (mode == VS_DEINTERLACEMODE_AUTO && interlaced))) - { -@@ -2173,7 +2177,8 @@ void CMixer::InitCycle() - m_config.stats->SetCanSkipDeint(true); - } - -- if (m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) -+ // TODO -+ if (0) //m_mixerInput[1].DVDPic.iFlags & DVP_FLAG_DROPDEINT) - { - m_mixersteps = 1; - } --- -1.8.4 - - -From 01419202b77b5c8ce1ea6167bd6673a4ac8fc2ad Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 6 Aug 2013 10:37:37 +0200 -Subject: [PATCH 11/92] renderer: protect against div by zero - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 1dbb670..fb065ea 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -445,6 +445,13 @@ void CLinuxRendererGL::CalculateTextureSourceRects(int source, int num_planes) - p.rect.y2 /= 1 << im->cshift_y; - } - -+ // protect against division by zero -+ if (p.texheight == 0 || p.texwidth == 0 || -+ p.pixpertex_x == 0 || p.pixpertex_y == 0) -+ { -+ continue; -+ } -+ - p.height /= p.pixpertex_y; - p.rect.y1 /= p.pixpertex_y; - p.rect.y2 /= p.pixpertex_y; --- -1.8.4 - - -From 5c47161e2dee63228fe0dbba9229693f9366881f Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Fri, 9 Aug 2013 09:52:46 +0200 -Subject: [PATCH 12/92] vdpau: add fence for detecting when a buffer can be - reused - ---- - xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 11 ++ - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 162 +++++++++++++++++++++++-- - xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 8 +- - 3 files changed, 167 insertions(+), 14 deletions(-) - -diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index fb065ea..7bfd892 100644 ---- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -@@ -1245,6 +1245,17 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) - RenderSoftware(renderBuffer, m_currentField); - VerifyGLState(); - } -+ -+#ifdef HAVE_LIBVDPAU -+ if (m_format == RENDER_FMT_VDPAU || m_format == RENDER_FMT_VDPAU_420) -+ { -+ YUVBUFFER &buf = m_buffers[renderBuffer]; -+ if (buf.vdpau) -+ { -+ buf.vdpau->Sync(); -+ } -+ } -+#endif - } - - void CLinuxRendererGL::RenderSinglePass(int index, int field) -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index ae7cce7..2a8b6a4 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -@@ -1144,6 +1144,23 @@ void CVdpauRenderPicture::ReturnUnused() - if (vdpau) - vdpau->ReturnRenderPicture(this); - } -+ -+void CVdpauRenderPicture::Sync() -+{ -+#ifdef GL_ARB_sync -+ CSingleLock lock(renderPicSection); -+ if (usefence) -+ { -+ if(glIsSync(fence)) -+ { -+ glDeleteSync(fence); -+ fence = None; -+ } -+ fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -+ } -+#endif -+} -+ - //----------------------------------------------------------------------------- - // Mixer - //----------------------------------------------------------------------------- -@@ -2531,7 +2548,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - case COutputDataProtocol::RETURNPIC: - CVdpauRenderPicture *pic; - pic = *((CVdpauRenderPicture**)msg->data); -- ProcessReturnPicture(pic); -+ QueueReturnPicture(pic); - return; - default: - break; -@@ -2622,7 +2639,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - case COutputDataProtocol::RETURNPIC: - CVdpauRenderPicture *pic; - pic = *((CVdpauRenderPicture**)msg->data); -- ProcessReturnPicture(pic); -+ QueueReturnPicture(pic); - m_controlPort.SendInMessage(COutputControlProtocol::STATS); - m_state = O_TOP_CONFIGURED_WORK; - m_extTimeout = 0; -@@ -2654,6 +2671,15 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - switch (signal) - { - case COutputControlProtocol::TIMEOUT: -+ if (ProcessSyncPicture()) -+ m_extTimeout = 10; -+ else -+ m_extTimeout = 100; -+ if (HasWork()) -+ { -+ m_state = O_TOP_CONFIGURED_WORK; -+ m_extTimeout = 0; -+ } - return; - default: - break; -@@ -2682,7 +2708,7 @@ void COutput::StateMachine(int signal, Protocol *port, Message *msg) - else - { - m_state = O_TOP_CONFIGURED_IDLE; -- m_extTimeout = 100; -+ m_extTimeout = 0; - } - return; - default: -@@ -2845,7 +2871,7 @@ void COutput::Flush() - { - CVdpauRenderPicture *pic; - pic = *((CVdpauRenderPicture**)msg->data); -- ProcessReturnPicture(pic); -+ QueueReturnPicture(pic); - } - msg->Release(); - } -@@ -2856,7 +2882,7 @@ void COutput::Flush() - { - CVdpauRenderPicture *pic; - pic = *((CVdpauRenderPicture**)msg->data); -- ProcessReturnPicture(pic); -+ QueueReturnPicture(pic); - } - } - -@@ -2984,7 +3010,7 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() - return retPic; - } - --void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) -+void COutput::QueueReturnPicture(CVdpauRenderPicture *pic) - { - std::deque::iterator it; - for (it = m_bufferPool.usedRenderPics.begin(); it != m_bufferPool.usedRenderPics.end(); ++it) -@@ -2997,17 +3023,84 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) - - if (it == m_bufferPool.usedRenderPics.end()) - { -- CLog::Log(LOGWARNING, "COutput::ProcessReturnPicture - pic not found"); -+ CLog::Log(LOGWARNING, "COutput::QueueReturnPicture - pic not found"); - return; - } -- m_bufferPool.freeRenderPics.push_back(*it); -- m_bufferPool.usedRenderPics.erase(it); -- if (!pic->valid) -+ -+ // check if already queued -+ std::deque::iterator it2 = find(m_bufferPool.syncRenderPics.begin(), -+ m_bufferPool.syncRenderPics.end(), -+ *it); -+ if (it2 == m_bufferPool.syncRenderPics.end()) - { -- CLog::Log(LOGDEBUG, "COutput::%s - return of invalid render pic", __FUNCTION__); -- return; -+ m_bufferPool.syncRenderPics.push_back(*it); - } - -+ ProcessSyncPicture(); -+} -+ -+bool COutput::ProcessSyncPicture() -+{ -+ CVdpauRenderPicture *pic; -+ bool busy = false; -+ -+ std::deque::iterator it; -+ for (it = m_bufferPool.syncRenderPics.begin(); it != m_bufferPool.syncRenderPics.end(); ) -+ { -+ pic = m_bufferPool.allRenderPics[*it]; -+ -+#ifdef GL_ARB_sync -+ if (pic->usefence) -+ { -+ if (glIsSync(pic->fence)) -+ { -+ GLint state; -+ GLsizei length; -+ glGetSynciv(pic->fence, GL_SYNC_STATUS, 1, &length, &state); -+ if(state == GL_SIGNALED) -+ { -+ glDeleteSync(pic->fence); -+ pic->fence = None; -+ } -+ else -+ { -+ busy = true; -+ ++it; -+ continue; -+ } -+ } -+ } -+#endif -+ -+ m_bufferPool.freeRenderPics.push_back(*it); -+ -+ std::deque::iterator it2 = find(m_bufferPool.usedRenderPics.begin(), -+ m_bufferPool.usedRenderPics.end(), -+ *it); -+ if (it2 == m_bufferPool.usedRenderPics.end()) -+ { -+ CLog::Log(LOGERROR, "COutput::ProcessSyncPicture - pic not found in queue"); -+ } -+ else -+ { -+ m_bufferPool.usedRenderPics.erase(it2); -+ } -+ it = m_bufferPool.syncRenderPics.erase(it); -+ -+ if (pic->valid) -+ { -+ ProcessReturnPicture(pic); -+ } -+ else -+ { -+ CLog::Log(LOGDEBUG, "COutput::%s - return of invalid render pic", __FUNCTION__); -+ } -+ } -+ return busy; -+} -+ -+void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) -+{ - if (m_config.usePixmaps) - { - m_bufferPool.pixmaps[pic->sourceIdx].used = false; -@@ -3156,10 +3249,43 @@ void COutput::ReleaseBufferPool() - } - m_bufferPool.outputSurfaces.clear(); - -+ // wait for all fences -+ XbmcThreads::EndTime timeout(1000); -+ for (int i = 0; i < m_bufferPool.allRenderPics.size(); i++) -+ { -+ CVdpauRenderPicture *pic = m_bufferPool.allRenderPics[i]; -+ if (pic->usefence) -+ { -+#ifdef GL_ARB_sync -+ while (glIsSync(pic->fence)) -+ { -+ GLint state; -+ GLsizei length; -+ glGetSynciv(pic->fence, GL_SYNC_STATUS, 1, &length, &state); -+ if(state == GL_SIGNALED || timeout.IsTimePast()) -+ { -+ glDeleteSync(pic->fence); -+ } -+ else -+ { -+ Sleep(5); -+ } -+ } -+ pic->fence = None; -+#endif -+ } -+ } -+ if (timeout.IsTimePast()) -+ { -+ CLog::Log(LOGERROR, "COutput::%s - timeout waiting for fence", __FUNCTION__); -+ } -+ ProcessSyncPicture(); -+ - // invalidate all used render pictures - for (unsigned int i = 0; i < m_bufferPool.usedRenderPics.size(); ++i) - { -- m_bufferPool.allRenderPics[m_bufferPool.usedRenderPics[i]]->valid = false; -+ CVdpauRenderPicture *pic = m_bufferPool.allRenderPics[m_bufferPool.usedRenderPics[i]]; -+ pic->valid = false; - } - } - -@@ -3169,6 +3295,7 @@ void COutput::PreCleanup() - VdpStatus vdp_st; - - m_mixer.Dispose(); -+ ProcessSyncPicture(); - - CSingleLock lock(m_bufferPool.renderPicSec); - for (unsigned int i = 0; i < m_bufferPool.outputSurfaces.size(); ++i) -@@ -3375,6 +3502,15 @@ bool COutput::GLInit() - CLog::Log(LOGNOTICE, "VDPAU::COutput: vdpau gl interop initialized"); - } - #endif -+ -+#ifdef GL_ARB_sync -+ bool hasfence = glewIsSupported("GL_ARB_sync"); -+ for (unsigned int i = 0; i < m_bufferPool.allRenderPics.size(); i++) -+ { -+ m_bufferPool.allRenderPics[i]->usefence = hasfence; -+ } -+#endif -+ - return true; - } - -diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -index 8845a16..c555d2d 100644 ---- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h -@@ -224,7 +224,8 @@ class CVdpauRenderPicture - friend class COutput; - public: - CVdpauRenderPicture(CCriticalSection §ion) -- : renderPicSection(section), refCount(0) {} -+ : renderPicSection(section), refCount(0) { fence = None; } -+ void Sync(); - DVDVideoPicture DVDPic; - int texWidth, texHeight; - CRect crop; -@@ -236,6 +237,8 @@ class CVdpauRenderPicture - long Release(); - private: - void ReturnUnused(); -+ bool usefence; -+ GLsync fence; - int refCount; - CCriticalSection &renderPicSection; - }; -@@ -391,6 +394,7 @@ struct VdpauBufferPool - std::queue processedPics; - std::deque usedRenderPics; - std::deque freeRenderPics; -+ std::deque syncRenderPics; - CCriticalSection renderPicSec; - }; - -@@ -450,7 +454,9 @@ class COutput : private CThread - void StateMachine(int signal, Protocol *port, Message *msg); - bool HasWork(); - CVdpauRenderPicture *ProcessMixerPicture(); -+ void QueueReturnPicture(CVdpauRenderPicture *pic); - void ProcessReturnPicture(CVdpauRenderPicture *pic); -+ bool ProcessSyncPicture(); - int FindFreePixmap(); - bool Init(); - bool Uninit(); --- -1.8.4 - - -From 380d726629dfd0bf60a5fba37e6a58b85fd76b97 Mon Sep 17 00:00:00 2001 +From e4c04286f7a715f3b2fdf16e5fff545aa2d7147a Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:34:39 +0200 -Subject: [PATCH 13/92] videoplayer: adapt lateness detection and dropping to +Subject: [PATCH 01/82] videoplayer: adapt lateness detection and dropping to buffering --- @@ -7673,10 +582,10 @@ index f8ad541..186e271 100644 1.8.4 -From 2d3787a518d16986f750c66e202ad788bf3ddc06 Mon Sep 17 00:00:00 2001 +From 957a83b681f869db35c7eff99b483e4f4838588f Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 2 Sep 2012 16:05:21 +0200 -Subject: [PATCH 14/92] video player: present correct pts to user for a/v sync +Subject: [PATCH 02/82] video player: present correct pts to user for a/v sync (after buffering in renderer) --- @@ -7744,10 +653,10 @@ index 186e271..59c7f09 100644 1.8.4 -From 0ac0a2f67c114867829e9ede034119de84a28d2e Mon Sep 17 00:00:00 2001 +From f58727e4cc2ab204a6408dbd8e9b1da23a63b88e Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 16 Feb 2013 18:25:53 +0100 -Subject: [PATCH 15/92] videoplayer: some rework and documentation +Subject: [PATCH 03/82] videoplayer: some rework and documentation --- .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 29 ++++++++++++++++++++-- @@ -7858,10 +767,10 @@ index 99c8b3c..be3d511 100644 1.8.4 -From d15e6e051b103b54be94cb5bed22ab632cb90a3b Mon Sep 17 00:00:00 2001 +From 3983ce0a7132c02d21983d9c239c34245b84bbfa Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 1 Jun 2013 11:21:19 +0200 -Subject: [PATCH 16/92] renderer: bump buffers to 5 +Subject: [PATCH 04/82] renderer: bump buffers to 5 --- xbmc/cores/VideoRenderers/BaseRenderer.h | 2 +- @@ -7884,10 +793,10 @@ index a61d3cf..df5fe0e 100644 1.8.4 -From 67e266be8f0c5f9912dd5a9d5a6967128fc81e62 Mon Sep 17 00:00:00 2001 +From 02c2746a6096758504dc98105589cb21f706ab4e Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:41:31 +0200 -Subject: [PATCH 17/92] videoplayer: update frametime, it might change due to +Subject: [PATCH 05/82] videoplayer: update frametime, it might change due to fps detection --- @@ -7911,10 +820,10 @@ index be3d511..dbbd11b 100644 1.8.4 -From e49cfe51e884f0b8f9a5277e6add5250ae14e8d7 Mon Sep 17 00:00:00 2001 +From 2bb1264b23191714e60082986a1b7c3c4e79af6a Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:43:06 +0200 -Subject: [PATCH 18/92] videoplayer: give streams with invalid fps a chance for +Subject: [PATCH 06/82] videoplayer: give streams with invalid fps a chance for fps detection --- @@ -7938,10 +847,10 @@ index dbbd11b..eb443af 100644 1.8.4 -From 5fc718526a0184f77a8ef7322595decd2ca26fa4 Mon Sep 17 00:00:00 2001 +From afbbc6e71376ce16435ee131ed8ec803ce84a26a Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 28 May 2012 10:49:05 +0200 -Subject: [PATCH 19/92] dvdplayer: allow rewinding at end of stream, do a seek +Subject: [PATCH 07/82] dvdplayer: allow rewinding at end of stream, do a seek after rewind --- @@ -7949,10 +858,10 @@ Subject: [PATCH 19/92] dvdplayer: allow rewinding at end of stream, do a seek 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index d12121f..06c9439 100644 +index 26b18ed..77bd12c 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1559,7 +1559,7 @@ void CDVDPlayer::HandlePlaySpeed() +@@ -1552,7 +1552,7 @@ void CDVDPlayer::HandlePlaySpeed() } else if (m_CurrentVideo.id >= 0 @@ -7961,7 +870,7 @@ index d12121f..06c9439 100644 && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() && m_SpeedState.lasttime != GetTime()) { -@@ -2225,6 +2225,12 @@ void CDVDPlayer::HandleMessages() +@@ -2218,6 +2218,12 @@ void CDVDPlayer::HandleMessages() pvrinputstream->Pause( speed == 0 ); } @@ -7978,10 +887,10 @@ index d12121f..06c9439 100644 1.8.4 -From 238cb63d3eb28211f36021b94a153e44de694b9e Mon Sep 17 00:00:00 2001 +From 72a9c0292d824f862b8440fb63f53e089d9f481a Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:22:05 +0200 -Subject: [PATCH 20/92] X11: ditch SDL for video and window events +Subject: [PATCH 08/82] X11: ditch SDL for video and window events --- xbmc/Application.cpp | 2 +- @@ -7997,10 +906,10 @@ Subject: [PATCH 20/92] X11: ditch SDL for video and window events create mode 100644 xbmc/windowing/WinEventsX11.h diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index 534e55f..becf35d 100644 +index a10fc2c..6440244 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -855,7 +855,7 @@ bool CApplication::CreateGUI() +@@ -849,7 +849,7 @@ bool CApplication::CreateGUI() uint32_t sdlFlags = 0; @@ -9465,10 +2374,10 @@ index b6b6ec4..448a1bb 100644 1.8.4 -From 13fac052710a7fd9ad7a6ef8397e208715e68c9b Mon Sep 17 00:00:00 2001 +From 27163ec89e9e29bbfd4e73bbd3f4340628ae9c7e Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:24:22 +0200 -Subject: [PATCH 21/92] X11: Add xbmc icon +Subject: [PATCH 09/82] X11: Add xbmc icon --- xbmc/windowing/X11/WinSystemX11.cpp | 126 +++++++++++++++++++++++++++++++++++- @@ -9657,10 +2566,10 @@ index 448a1bb..e618268 100644 1.8.4 -From a9cedcc951e0d03c7e554d34a651699be781d2fe Mon Sep 17 00:00:00 2001 +From 756b3df5563047c459a1274097fda0a9fb0f1141 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 20 May 2012 14:11:26 +0200 -Subject: [PATCH 22/92] X11: add SDL joystick until we have a better solution +Subject: [PATCH 10/82] X11: add SDL joystick until we have a better solution --- xbmc/windowing/WinEventsX11.cpp | 26 ++++++++++++++++++++++++++ @@ -9714,10 +2623,10 @@ index 5a8bbb8..5bc1de0 100644 1.8.4 -From 11bf4ce1953a74f46d6248acef73486bccadbec9 Mon Sep 17 00:00:00 2001 +From bb04311fa550a579a896765072a3d5fb9ae3f88d Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 12:35:55 +0200 -Subject: [PATCH 23/92] X11: factor out code handling device reset notification +Subject: [PATCH 11/82] X11: factor out code handling device reset notification --- xbmc/windowing/X11/WinSystemX11.cpp | 22 ++++++++++++++-------- @@ -9780,10 +2689,10 @@ index e618268..c4d4b76 100644 1.8.4 -From 8d2ab76083ab6183f89609176533bc70d0043e24 Mon Sep 17 00:00:00 2001 +From ae2554a15c9413469a9bbbc0c59ff6f6df28d9c4 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 15:02:00 +0200 -Subject: [PATCH 24/92] X11: move xrandr events to WinEventsX11 +Subject: [PATCH 12/82] X11: move xrandr events to WinEventsX11 --- xbmc/windowing/WinEventsX11.cpp | 42 +++++++++++++++++++++++++++++++++++++ @@ -9927,10 +2836,10 @@ index c5938af..9f74dd5 100644 1.8.4 -From 5e46a38bb3bd40e5e0dfe1d07e82dbb3a8e0a061 Mon Sep 17 00:00:00 2001 +From 3545c26f76c480dced97cd66bdb1a35d51a2fc34 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 12 Apr 2012 15:43:56 +0200 -Subject: [PATCH 25/92] xrandr: remove method RestoreState +Subject: [PATCH 13/82] xrandr: remove method RestoreState --- xbmc/windowing/X11/WinSystemX11.cpp | 13 +++++++++++-- @@ -10009,10 +2918,10 @@ index 0aec487..00b49dc 100644 1.8.4 -From 37bc363a851bf63b7b695e6a102191664ca48672 Mon Sep 17 00:00:00 2001 +From 1ecbd36afe65238b39d323b7ce0c34fc6d87bfce Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 20 May 2012 13:17:10 +0200 -Subject: [PATCH 26/92] xrandr: observe orientation +Subject: [PATCH 14/82] xrandr: observe orientation --- xbmc/windowing/X11/WinSystemX11.cpp | 89 ++++++++++++++++++++++++++++++------- @@ -10227,10 +3136,10 @@ index 00b49dc..508604d 100644 1.8.4 -From ea847955f0e918add5d2f5cc7507441da33b71ed Mon Sep 17 00:00:00 2001 +From 61823373c52b128b6de314bb0d409a60f2fb8a80 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:54:15 +0200 -Subject: [PATCH 27/92] xrandr: allow getting info for multiple screen's +Subject: [PATCH 15/82] xrandr: allow getting info for multiple screen's Refactored by: Joakim Plate --- @@ -10405,10 +3314,10 @@ index 508604d..d37838a 100644 1.8.4 -From 41daa63aa0b5c3c6a6ccf6274a0f712e2d4924ab Mon Sep 17 00:00:00 2001 +From 60f4a15c7cdefd32fffd924eacd0666504985ffe Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:44:00 +0200 -Subject: [PATCH 28/92] X11: fix multi-head setups +Subject: [PATCH 16/82] X11: fix multi-head setups --- language/English/strings.po | 4 +- @@ -10423,7 +3332,7 @@ Subject: [PATCH 28/92] X11: fix multi-head setups 9 files changed, 229 insertions(+), 116 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index b6eee02..4ea1c4e 100644 +index 63ea425..d027047 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -1003,7 +1003,9 @@ msgctxt "#245" @@ -10438,10 +3347,10 @@ index b6eee02..4ea1c4e 100644 msgctxt "#247" msgid "Scripts" diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 44a247f..f99703f 100644 +index a22138c..47e8145 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml -@@ -1865,6 +1865,15 @@ +@@ -1844,6 +1844,15 @@
@@ -10457,7 +3366,7 @@ index 44a247f..f99703f 100644 0 0 -@@ -1886,6 +1895,7 @@ +@@ -1865,6 +1874,7 @@ -1 @@ -10465,7 +3374,7 @@ index 44a247f..f99703f 100644 -@@ -1903,6 +1913,7 @@ +@@ -1882,6 +1892,7 @@ -1 @@ -10592,7 +3501,7 @@ index cc4002b..d80f1dc 100644 protected: CDisplaySettings(); diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp -index 0ff415c..3573ef5 100644 +index ef9904b..5f18b57 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -380,6 +380,7 @@ void CSettings::Uninitialize() @@ -10603,7 +3512,7 @@ index 0ff415c..3573ef5 100644 m_settingsManager->UnregisterSettingOptionsFiller("shutdownstates"); m_settingsManager->UnregisterSettingOptionsFiller("startupwindows"); m_settingsManager->UnregisterSettingOptionsFiller("streamlanguages"); -@@ -687,6 +688,7 @@ void CSettings::InitializeOptionFillers() +@@ -690,6 +691,7 @@ void CSettings::InitializeOptionFillers() m_settingsManager->RegisterSettingOptionsFiller("screens", CDisplaySettings::SettingOptionsScreensFiller); m_settingsManager->RegisterSettingOptionsFiller("stereoscopicmodes", CDisplaySettings::SettingOptionsStereoscopicModesFiller); m_settingsManager->RegisterSettingOptionsFiller("preferedstereoscopicviewmodes", CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller); @@ -10611,7 +3520,7 @@ index 0ff415c..3573ef5 100644 m_settingsManager->RegisterSettingOptionsFiller("shutdownstates", CPowerManager::SettingOptionsShutdownStatesFiller); m_settingsManager->RegisterSettingOptionsFiller("startupwindows", ADDON::CSkinInfo::SettingOptionsStartupWindowsFiller); m_settingsManager->RegisterSettingOptionsFiller("streamlanguages", CLangInfo::SettingOptionsStreamLanguagesFiller); -@@ -714,6 +716,9 @@ void CSettings::InitializeConditions() +@@ -717,6 +719,9 @@ void CSettings::InitializeConditions() #ifdef HAS_GL m_settingsManager->AddCondition("has_gl"); #endif @@ -10621,7 +3530,7 @@ index 0ff415c..3573ef5 100644 #ifdef HAS_GLES m_settingsManager->AddCondition("has_gles"); #endif -@@ -856,6 +861,7 @@ void CSettings::InitializeISettingCallbacks() +@@ -858,6 +863,7 @@ void CSettings::InitializeISettingCallbacks() settingSet.insert("videoscreen.screen"); settingSet.insert("videoscreen.resolution"); settingSet.insert("videoscreen.screenmode"); @@ -11177,10 +4086,10 @@ index 0727bb9..b1eb278 100644 1.8.4 -From d9f545829aa5c2d9031ffb622391672002525ca1 Mon Sep 17 00:00:00 2001 +From 9cc9888a21456d10bdcb1115ea995cc50e0a788d Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:36:32 +0200 -Subject: [PATCH 29/92] X11: remove all DefaultScreen and RootWindow macros +Subject: [PATCH 17/82] X11: remove all DefaultScreen and RootWindow macros --- xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- @@ -11248,10 +4157,10 @@ index 095012f..60a6878 100644 1.8.4 -From 12f9362c17fc135ead21dd56db24b6d4d3571798 Mon Sep 17 00:00:00 2001 +From 83e64a5b9240df8baf08f563ed2d4e7c176490ea Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 11:45:22 +0200 -Subject: [PATCH 30/92] X11: remove all DefaultScreen and RootWindow macros +Subject: [PATCH 18/82] X11: remove all DefaultScreen and RootWindow macros (VideoRefClock) Note this is on a separate display connection. @@ -11323,10 +4232,10 @@ index 5bf3656..0b9e7b3 100644 1.8.4 -From edbc516af04507858d4aba14ac20ce09e669e462 Mon Sep 17 00:00:00 2001 +From 3217e010b12d414bbd8f98f295ff988af94cd09f Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 20 Jun 2012 17:37:11 +0200 -Subject: [PATCH 31/92] X11: recreate gl context after output has changed +Subject: [PATCH 19/82] X11: recreate gl context after output has changed --- xbmc/windowing/X11/WinSystemX11.cpp | 24 ++++++++++++++---------- @@ -11477,10 +4386,10 @@ index 60a6878..d6ba80a 100644 1.8.4 -From 7df8409e1df2ef664801446955bd17da53047af6 Mon Sep 17 00:00:00 2001 +From f52bf5bc1ee7c289aa5c6ef81d55c0a4d59774f9 Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:06:25 +0200 -Subject: [PATCH 32/92] X11: hook video reference clock in windowing +Subject: [PATCH 20/82] X11: hook video reference clock in windowing --- xbmc/video/VideoReferenceClock.cpp | 71 +++++++++++++++++++++++++++----------- @@ -11685,10 +4594,10 @@ index dd65a1b..afd71fc 100644 1.8.4 -From 6728f3c34dce4c1359e4572f5f2b33170f809929 Mon Sep 17 00:00:00 2001 +From 0ad0334d0b8b799124b839fa6b253f9299623dc6 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 21 Jun 2012 17:26:51 +0200 -Subject: [PATCH 33/92] X11: fix video calibrations +Subject: [PATCH 21/82] X11: fix video calibrations --- xbmc/windowing/WinSystem.h | 1 + @@ -11780,10 +4689,10 @@ index 05aa60e..95672d1 100644 1.8.4 -From 2bd0c10cd40582e29fdfeee4ccf2b541dc798d6f Mon Sep 17 00:00:00 2001 +From 6092a321c93928629f1c529d012b2faf63eec52e Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:00:26 +0200 -Subject: [PATCH 34/92] X11: deactivate screen saver on startup +Subject: [PATCH 22/82] X11: deactivate screen saver on startup --- xbmc/windowing/X11/WinSystemX11.cpp | 29 +++++++++++++++++++++++++++++ @@ -11853,10 +4762,10 @@ index 95672d1..51ac314 100644 1.8.4 -From 223176fc738c23565a313aedc28a6b99b6200751 Mon Sep 17 00:00:00 2001 +From 08386bdb60bdb4c3ea91b040e89cba31bb5ac1bf Mon Sep 17 00:00:00 2001 From: FernetMenta Date: Thu, 5 Jul 2012 12:10:09 +0200 -Subject: [PATCH 35/92] X11: change method of going full-screen +Subject: [PATCH 23/82] X11: change method of going full-screen --- xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- @@ -11900,10 +4809,10 @@ index 14a4307..66b91fd 100644 1.8.4 -From fe6fd2dd1a49256216d2d9f71ceda5a7e9fe1d6f Mon Sep 17 00:00:00 2001 +From f194e4d032660d9d9b4ffbac415f7fea53dbafa3 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 28 Jun 2012 19:12:39 +0200 -Subject: [PATCH 36/92] X11: reset key repeat and key modifier on focus lost +Subject: [PATCH 24/82] X11: reset key repeat and key modifier on focus lost and gain --- @@ -11935,10 +4844,10 @@ index c58067b..c9f8a20 100644 1.8.4 -From fea5a39655a61f34aab292bfafc44ef1e7d17452 Mon Sep 17 00:00:00 2001 +From 00aa48473e99ae9c7065ab5c4f4672dfdcd51d49 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 14:18:46 +0200 -Subject: [PATCH 37/92] X11: replace custom utf8 to unicode with charset +Subject: [PATCH 25/82] X11: replace custom utf8 to unicode with charset convertor (squash to x11 events) --- @@ -12155,10 +5064,10 @@ index 6100933..72955ad 100644 1.8.4 -From fbe6b58b3083ff053c263ee4feffdb05f6e8e101 Mon Sep 17 00:00:00 2001 +From c77d0ee7db73a1746af8edd1ec03ef5669a30284 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 Jul 2012 14:23:54 +0200 -Subject: [PATCH 38/92] X11: fixed invalid usage of sizeof() (squash into x11 +Subject: [PATCH 26/82] X11: fixed invalid usage of sizeof() (squash into x11 changes) --- @@ -12222,10 +5131,10 @@ index 72955ad..102a076 100644 1.8.4 -From c63fd140616c676ff388930bf8cfceb4ca032ad8 Mon Sep 17 00:00:00 2001 +From c9904aa8b90b5a0a8ec61f6e01b967eb107c4ceb Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 9 Jun 2012 18:23:53 +0200 -Subject: [PATCH 39/92] add missing keys to xbmc keytable +Subject: [PATCH 27/82] add missing keys to xbmc keytable --- xbmc/input/XBMC_keytable.cpp | 2 ++ @@ -12248,10 +5157,10 @@ index b430f55..246164b 100644 1.8.4 -From ea60694d30c2e06a6f8824c01294f36fbcc73392 Mon Sep 17 00:00:00 2001 +From aa899a6ccd76d9ffea62be7b7f785893958ede9f Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 16 Mar 2012 15:57:51 +0100 -Subject: [PATCH 40/92] videorefclock: temp deactivate of nv settings +Subject: [PATCH 28/82] videorefclock: temp deactivate of nv settings --- xbmc/video/VideoReferenceClock.cpp | 2 +- @@ -12274,10 +5183,10 @@ index 3bd8133..59f924c 100644 1.8.4 -From 5298be8d4ea65f0ddb7af1342032171cdb8257fc Mon Sep 17 00:00:00 2001 +From 4374654579db502b8f808be89e745847e651dfc8 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 20 Aug 2012 09:09:09 +0200 -Subject: [PATCH 41/92] videorefclock: ask graphics context for refresh rate +Subject: [PATCH 29/82] videorefclock: ask graphics context for refresh rate --- xbmc/video/VideoReferenceClock.cpp | 3 ++- @@ -12308,10 +5217,10 @@ index 59f924c..2f8bc69 100644 1.8.4 -From b79979f1f1f8edbf67f60b6766d6a9957ff78c87 Mon Sep 17 00:00:00 2001 +From f97fba2c14c1bc6b6b10ac8a4a4591f0820e2670 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 9 Jul 2012 14:00:18 +0200 -Subject: [PATCH 42/92] X11: fix icon texture after +Subject: [PATCH 30/82] X11: fix icon texture after cc5ed3c2474084ebc0373a3046410e6f766e03f4 --- @@ -12419,10 +5328,10 @@ index 66b91fd..b00eddc 100644 1.8.4 -From 44c2bbd0460ae8c00b744192891245d96dc67414 Mon Sep 17 00:00:00 2001 +From 542b60783ed968813df20765f0013974b18bf7f0 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 10 Jul 2012 11:14:12 +0200 -Subject: [PATCH 43/92] X11: check for window manager +Subject: [PATCH 31/82] X11: check for window manager --- xbmc/windowing/X11/WinSystemX11.cpp | 74 ++++++++++++++++++++++++++++++++++++- @@ -12543,10 +5452,10 @@ index 51ac314..ce3c289 100644 1.8.4 -From 27a40a3b1bd2c8492c033e293d99b8053e0e0ab1 Mon Sep 17 00:00:00 2001 +From 8f528dac73c34eba5931d27545018ff972490cfc Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 12 Jul 2012 11:11:47 +0200 -Subject: [PATCH 44/92] X11: dont set window on xrandr if no mode available +Subject: [PATCH 32/82] X11: dont set window on xrandr if no mode available --- xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++----- @@ -12583,10 +5492,10 @@ index 05279ad..9697cbb 100644 1.8.4 -From 312891e420e7cecd1a0ecfd10ea61f72dd5c2f22 Mon Sep 17 00:00:00 2001 +From f4bfc84aa5ea90754a349a2d44b8a01b519db569 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 26 Jul 2012 09:34:28 +0200 -Subject: [PATCH 45/92] X11: fix crash after a resolution change on startup +Subject: [PATCH 33/82] X11: fix crash after a resolution change on startup --- xbmc/windowing/X11/WinSystemX11.cpp | 3 ++- @@ -12610,10 +5519,10 @@ index 9697cbb..868071c 100644 1.8.4 -From e784d3b2ea5b4e7c5fd9af33462cfc71cca5c66d Mon Sep 17 00:00:00 2001 +From bfb99f9de6da60bc7bf6c2af4185d1e98db9a11a Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 15 Sep 2012 18:27:29 +0200 -Subject: [PATCH 46/92] X11: lock graphics context in NotifyXRREvent +Subject: [PATCH 34/82] X11: lock graphics context in NotifyXRREvent --- xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ @@ -12636,10 +5545,10 @@ index 868071c..9ff947c 100644 1.8.4 -From e4f4ab1cbc25c049107f255b6628932ec0ee67fa Mon Sep 17 00:00:00 2001 +From dd1c7aa36b98b7a01f034d542dd645c6113595dd Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 8 Oct 2011 16:45:13 +0200 -Subject: [PATCH 47/92] ffmpeg: add xvba hwaccel, co-author fritsch +Subject: [PATCH 35/82] ffmpeg: add xvba hwaccel, co-author fritsch --- lib/ffmpeg/configure | 11 ++ @@ -12827,7 +5736,7 @@ index e231b08..6fcd2a0 100644 AV_PIX_FMT_NONE }; diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c -index 85f2372..4f09c67 100644 +index 1cab49f..62ac8fb 100644 --- a/lib/ffmpeg/libavcodec/h264.c +++ b/lib/ffmpeg/libavcodec/h264.c @@ -81,6 +81,9 @@ @@ -13546,10 +6455,10 @@ index 1c00ac4..6437e29 100644 1.8.4 -From 43f0fe351754159238f7e6b8810605821fa64199 Mon Sep 17 00:00:00 2001 +From c12a4c06a6b09be474b495abbb1293bc9b5a1100 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 12 Apr 2012 12:09:31 +0200 -Subject: [PATCH 48/92] xvba: add decoder, co-author fritsch +Subject: [PATCH 36/82] xvba: add decoder, co-author fritsch --- configure.in | 47 + @@ -13574,7 +6483,7 @@ Subject: [PATCH 48/92] xvba: add decoder, co-author fritsch create mode 100644 xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.h diff --git a/configure.in b/configure.in -index 0337705..1b88d24 100644 +index 4127c9d..dfea1ee 100644 --- a/configure.in +++ b/configure.in @@ -150,6 +150,8 @@ vaapi_not_found="== Could not find libva. VAAPI support disabled. ==" @@ -13599,7 +6508,7 @@ index 0337705..1b88d24 100644 AC_ARG_ENABLE([vtbdecoder], [AS_HELP_STRING([--enable-vtbdecoder], -@@ -1808,6 +1816,37 @@ else +@@ -1822,6 +1830,37 @@ else USE_CRYSTALHD=0 fi @@ -13637,7 +6546,7 @@ index 0337705..1b88d24 100644 # VTBDecoder if test "x$use_vtbdecoder" != "xno"; then if test "$host_vendor" = "apple" ; then -@@ -2019,6 +2058,12 @@ else +@@ -2033,6 +2072,12 @@ else final_message="$final_message\n CrystalHD:\tNo" fi @@ -13650,7 +6559,7 @@ index 0337705..1b88d24 100644 if test "x$use_vtbdecoder" != "xno"; then final_message="$final_message\n VTBDecoder:\tYes" else -@@ -2503,6 +2548,7 @@ AC_SUBST(USE_OPENGLES) +@@ -2523,6 +2568,7 @@ AC_SUBST(USE_OPENGLES) AC_SUBST(USE_VDPAU) AC_SUBST(USE_VAAPI) AC_SUBST(USE_CRYSTALHD) @@ -13658,7 +6567,7 @@ index 0337705..1b88d24 100644 AC_SUBST(USE_LIBSMBCLIENT) AC_SUBST(USE_LIBNFS) AC_SUBST(USE_LIBAFPCLIENT) -@@ -2685,6 +2731,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [ +@@ -2705,6 +2751,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` \ @@ -13667,7 +6576,7 @@ index 0337705..1b88d24 100644 --enable-pthreads \ --enable-runtime-cpudetect \ diff --git a/language/English/strings.po b/language/English/strings.po -index 4ea1c4e..5c7defd 100644 +index d027047..03bb374 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -5798,7 +5798,12 @@ msgctxt "#13437" @@ -13698,7 +6607,7 @@ index 4ea1c4e..5c7defd 100644 msgctxt "#16400" msgid "Post-processing" diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index f99703f..879c518 100644 +index 47e8145..0426ff2 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -410,6 +410,11 @@ @@ -13714,7 +6623,7 @@ index f99703f..879c518 100644 HAS_GL 4 diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp -index 7bfd892..696c3f1 100644 +index e562102..82e3545 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -65,6 +65,9 @@ @@ -13880,7 +6789,7 @@ index 7bfd892..696c3f1 100644 void CLinuxRendererGL::RenderSoftware(int index, int field) { // used for textues uploaded from rgba or CVPixelBuffers. -@@ -2814,6 +2912,87 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) +@@ -2812,6 +2910,87 @@ bool CLinuxRendererGL::CreateCVRefTexture(int index) return true; } @@ -13968,7 +6877,7 @@ index 7bfd892..696c3f1 100644 bool CLinuxRendererGL::UploadYUV422PackedTexture(int source) { YUVBUFFER& buf = m_buffers[source]; -@@ -3389,6 +3568,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3387,6 +3566,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (m_renderMethod & RENDER_VAAPI) return false; @@ -13978,7 +6887,7 @@ index 7bfd892..696c3f1 100644 return (m_renderMethod & RENDER_GLSL) || (m_renderMethod & RENDER_ARB) || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3402,6 +3584,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3400,6 +3582,9 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (m_renderMethod & RENDER_VAAPI) return false; @@ -13988,7 +6897,7 @@ index 7bfd892..696c3f1 100644 return (m_renderMethod & RENDER_GLSL) || (m_renderMethod & RENDER_ARB) || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE); -@@ -3425,7 +3610,8 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) +@@ -3423,7 +3608,8 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature) if (feature == RENDERFEATURE_NONLINSTRETCH) { if (((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT)) || @@ -13998,7 +6907,7 @@ index 7bfd892..696c3f1 100644 return true; } -@@ -3497,6 +3683,16 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) +@@ -3495,6 +3681,16 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) return false; } @@ -14015,7 +6924,7 @@ index 7bfd892..696c3f1 100644 #ifdef TARGET_DARWIN // YADIF too slow for HD but we have no methods to fall back // to something that works so just turn it off. -@@ -3546,7 +3742,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) +@@ -3544,7 +3740,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) return false; if ((glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL)) || @@ -14024,7 +6933,7 @@ index 7bfd892..696c3f1 100644 { // spline36 and lanczos3 are only allowed through advancedsettings.xml if(method != VS_SCALINGMETHOD_SPLINE36 -@@ -3613,7 +3809,8 @@ unsigned int CLinuxRendererGL::GetProcessorSize() +@@ -3611,7 +3807,8 @@ unsigned int CLinuxRendererGL::GetProcessorSize() if(m_format == RENDER_FMT_VDPAU || m_format == RENDER_FMT_VDPAU_420 || m_format == RENDER_FMT_VAAPI @@ -14034,7 +6943,7 @@ index 7bfd892..696c3f1 100644 return 1; else return 0; -@@ -3649,4 +3846,14 @@ void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) +@@ -3647,4 +3844,14 @@ void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef, int index) } #endif @@ -14050,10 +6959,10 @@ index 7bfd892..696c3f1 100644 + #endif diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -index 966733e..0377fcf 100644 +index 3311ee6..bb6baad 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h -@@ -44,6 +44,8 @@ +@@ -43,6 +43,8 @@ namespace Shaders { class BaseVideoFilterShader; } namespace VAAPI { struct CHolder; } namespace VDPAU { class CVdpauRenderPicture; } @@ -14062,7 +6971,7 @@ index 966733e..0377fcf 100644 #undef ALIGN #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1)) -@@ -89,6 +91,7 @@ enum RenderMethod +@@ -88,6 +90,7 @@ enum RenderMethod RENDER_POT=0x10, RENDER_VAAPI=0x20, RENDER_CVREF = 0x40, @@ -14070,7 +6979,7 @@ index 966733e..0377fcf 100644 }; enum RenderQuality -@@ -150,7 +153,9 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -149,7 +152,9 @@ class CLinuxRendererGL : public CBaseRenderer #ifdef TARGET_DARWIN virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index); #endif @@ -14081,7 +6990,7 @@ index 966733e..0377fcf 100644 virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255); // Feature support -@@ -205,6 +210,10 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -204,6 +209,10 @@ class CLinuxRendererGL : public CBaseRenderer void DeleteCVRefTexture(int index); bool CreateCVRefTexture(int index); @@ -14092,7 +7001,7 @@ index 966733e..0377fcf 100644 bool UploadYUV422PackedTexture(int index); void DeleteYUV422PackedTexture(int index); bool CreateYUV422PackedTexture(int index); -@@ -224,6 +233,7 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -223,6 +232,7 @@ class CLinuxRendererGL : public CBaseRenderer void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware @@ -14100,7 +7009,7 @@ index 966733e..0377fcf 100644 struct { -@@ -291,6 +301,9 @@ class CLinuxRendererGL : public CBaseRenderer +@@ -290,6 +300,9 @@ class CLinuxRendererGL : public CBaseRenderer #ifdef TARGET_DARWIN_OSX struct __CVBuffer *cvBufferRef; #endif @@ -17015,10 +9924,10 @@ index eb443af..c2808c3 100644 } return "UNKNOWN"; diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp -index 3573ef5..c774042 100644 +index 5f18b57..6d4a084 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp -@@ -757,6 +757,9 @@ void CSettings::InitializeConditions() +@@ -760,6 +760,9 @@ void CSettings::InitializeConditions() #ifdef HAVE_LIBVDPAU m_settingsManager->AddCondition("have_libvdpau"); #endif @@ -17057,20 +9966,20 @@ index 8f30248..db58075 100644 1.8.4 -From 3b15c3cfd8fbe0c999fa2479b62e90c155685f96 Mon Sep 17 00:00:00 2001 +From fc11ff33241c4e19098e4e51520fb7a4a0d41ee4 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 16 Jun 2012 12:46:30 +0200 -Subject: [PATCH 49/92] xvba: do not use vaapi if xvba is present +Subject: [PATCH 37/82] 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 2d59b09..aa83875 100644 +index 3facfce..298bcad 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp -@@ -261,6 +261,15 @@ void CDecoder::Close() +@@ -269,6 +269,15 @@ void CDecoder::Close() bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces) { @@ -17090,10 +9999,10 @@ index 2d59b09..aa83875 100644 1.8.4 -From c8fce53172c241c8309e55c54c591ec1ce6afc15 Mon Sep 17 00:00:00 2001 +From 78b85202ec4867eea3aff0952a9339e7be3562a7 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 23 Aug 2012 19:39:49 +0200 -Subject: [PATCH 50/92] ffmpeg: add av_find_default_stream_index to interface +Subject: [PATCH 38/82] ffmpeg: add av_find_default_stream_index to interface --- lib/DllAvFormat.h | 4 ++++ @@ -17139,10 +10048,10 @@ index 0016c0b..3514856 100644 1.8.4 -From f0f1bf20f0442fa843063b04e19c5ed8f0514fb2 Mon Sep 17 00:00:00 2001 +From 6e71dad1bfe0a9f1c40ed2002e89e653311e25df Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 20 Aug 2012 16:06:39 +0200 -Subject: [PATCH 51/92] dvdplayer: observe pts counter overflow +Subject: [PATCH 39/82] dvdplayer: observe pts counter overflow --- .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 198 ++++++++++++++++++++- @@ -17429,10 +10338,10 @@ index aef5ab1..35abbdf 100644 1.8.4 -From 35effd70277b899bd40c3083094a8dcd51e878de Mon Sep 17 00:00:00 2001 +From d06d724d4fa90c59f092cfb4a343fdf1d59209c4 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 2 Oct 2012 13:02:10 +0200 -Subject: [PATCH 52/92] dvdplayer: avoid short screen flicker caused by +Subject: [PATCH 40/82] dvdplayer: avoid short screen flicker caused by unnecessary reconfigure of renderer --- @@ -17465,10 +10374,10 @@ index c2808c3..5d487f4 100644 1.8.4 -From ed58faaede557555b23ba6c16b81233e151bd340 Mon Sep 17 00:00:00 2001 +From 2eca3120f6cfdaad4569c43f1a141ad8d081b4d9 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 11 Oct 2012 12:05:50 +0200 -Subject: [PATCH 53/92] vdpau: advanced settings for auto deinterlacing +Subject: [PATCH 41/82] vdpau: advanced settings for auto deinterlacing --- xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++---- @@ -17477,7 +10386,7 @@ Subject: [PATCH 53/92] vdpau: advanced settings for auto deinterlacing 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 2a8b6a4..87c0319 100644 +index adf7413..733f4f8 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp @@ -1827,10 +1827,10 @@ EINTERLACEMETHOD CMixer::GetDeinterlacingMethod(bool log /* = false */) @@ -17496,7 +10405,7 @@ index 2a8b6a4..87c0319 100644 if (deint != -1) { diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp -index f47a80b..bc3b588 100644 +index 1e162f9..2a0c9f3 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -168,6 +168,8 @@ void CAdvancedSettings::Initialize() @@ -17508,7 +10417,7 @@ index f47a80b..bc3b588 100644 m_videoVDPAUtelecine = false; m_videoVDPAUdeintSkipChromaHD = false; m_DXVACheckCompatibility = false; -@@ -603,6 +605,8 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) +@@ -608,6 +610,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); @@ -17534,10 +10443,10 @@ index 0d792af..b7b7a80 100644 1.8.4 -From dba4c650cf55a92ee60ccce57d9de4bbc204a6d3 Mon Sep 17 00:00:00 2001 +From 0cb7cfdf3c8160140f4b024dac1ed81dd5f460e1 Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 2 Nov 2012 13:20:03 +0100 -Subject: [PATCH 54/92] player: fix rewind +Subject: [PATCH 42/82] player: fix rewind --- xbmc/cores/dvdplayer/DVDMessage.h | 5 ++++- @@ -17585,10 +10494,10 @@ index 2ea8b8f..e8274f9 100644 class CDVDMsgPlayerSeekChapter : public CDVDMsg diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 06c9439..1ca0de2 100644 +index 77bd12c..f6da821 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1560,11 +1560,13 @@ void CDVDPlayer::HandlePlaySpeed() +@@ -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 @@ -17603,7 +10512,7 @@ index 06c9439..1ca0de2 100644 // check how much off clock video is when ff/rw:ing // a problem here is that seeking isn't very accurate // and since the clock will be resynced after seek -@@ -1583,7 +1585,7 @@ void CDVDPlayer::HandlePlaySpeed() +@@ -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); @@ -17612,7 +10521,7 @@ index 06c9439..1ca0de2 100644 } } } -@@ -2071,7 +2073,7 @@ void CDVDPlayer::HandleMessages() +@@ -2064,7 +2066,7 @@ void CDVDPlayer::HandleMessages() else m_StateInput.dts = start; @@ -17621,7 +10530,7 @@ index 06c9439..1ca0de2 100644 } else CLog::Log(LOGWARNING, "error while seeking"); -@@ -2210,9 +2212,10 @@ void CDVDPlayer::HandleMessages() +@@ -2203,9 +2205,10 @@ void CDVDPlayer::HandleMessages() double offset; offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp; offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL; @@ -17633,7 +10542,7 @@ index 06c9439..1ca0de2 100644 m_State.timestamp = CDVDClock::GetAbsoluteClock(); } -@@ -2228,7 +2231,8 @@ void CDVDPlayer::HandleMessages() +@@ -2221,7 +2224,8 @@ void CDVDPlayer::HandleMessages() // do a seek after rewind, clock is not in sync with current pts if (m_playSpeed < 0 && speed >= 0) { @@ -17643,7 +10552,7 @@ index 06c9439..1ca0de2 100644 } // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE -@@ -3180,7 +3184,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) +@@ -3173,7 +3177,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers) return true; } @@ -17652,7 +10561,7 @@ index 06c9439..1ca0de2 100644 { double startpts; if(accurate) -@@ -3192,19 +3196,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3185,19 +3189,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) if(startpts != DVD_NOPTS_VALUE) startpts -= m_offset_pts; @@ -17680,7 +10589,7 @@ index 06c9439..1ca0de2 100644 m_CurrentTeletext.dts = DVD_NOPTS_VALUE; m_CurrentTeletext.startpts = startpts; -@@ -3248,7 +3256,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) +@@ -3241,7 +3249,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) m_CurrentTeletext.started = false; } @@ -17752,10 +10661,10 @@ index 59c7f09..65dea76 100644 1.8.4 -From cbd0f850b81dd1d87c1eae20ad74032b398ef913 Mon Sep 17 00:00:00 2001 +From c71a8c0a1bcc49f402fb920e2c734418ccd1e0ee Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 23 Nov 2012 17:41:12 +0100 -Subject: [PATCH 55/92] xrandr: fix query for multiple screens +Subject: [PATCH 43/82] xrandr: fix query for multiple screens --- xbmc/windowing/X11/XRandR.cpp | 10 ++++++---- @@ -17796,10 +10705,10 @@ index 9e181f2..ce0a02b 100644 1.8.4 -From 566f77b7443d382ab8eaaa0dc2b95d5b1bf40c30 Mon Sep 17 00:00:00 2001 +From 28a58658085c0a5b93f9b10566f9e4b1569e6e5c Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 2 Dec 2012 15:46:55 +0100 -Subject: [PATCH 56/92] X11: add debug log to print out refresh after xrr event +Subject: [PATCH 44/82] X11: add debug log to print out refresh after xrr event --- xbmc/windowing/X11/WinSystemX11.cpp | 6 ++++++ @@ -17826,10 +10735,10 @@ index 9ff947c..a3394e6 100644 1.8.4 -From 354fb1cb9d3a8d334861d2e7c3422ea27c5c6de7 Mon Sep 17 00:00:00 2001 +From 964924739b69e9055908c2d14bbb0d2ad8231155 Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 11 Dec 2012 11:08:13 +0100 -Subject: [PATCH 57/92] X11: dont call XCloseDisplay on shutdown, it crashes +Subject: [PATCH 45/82] X11: dont call XCloseDisplay on shutdown, it crashes when powered doen by cec on ATI --- @@ -17854,10 +10763,10 @@ index a3394e6..b941c14 100644 1.8.4 -From 66b9c4ac765253621bb307413a433186c1c09746 Mon Sep 17 00:00:00 2001 +From 1b2eb4d8ec970323707e50089cb262a627a7c1d9 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 58/92] x11: support for multiple x screens +Subject: [PATCH 46/82] x11: support for multiple x screens --- xbmc/windowing/X11/XRandR.cpp | 2 +- @@ -17880,10 +10789,10 @@ index ce0a02b..aa27d2b 100644 1.8.4 -From c7445a98c106f462ead06e7e7d46eb034d42d998 Mon Sep 17 00:00:00 2001 +From 50d467842061e56ccd357c73f0dbb3228384a00e Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 24 Dec 2012 16:02:42 +0100 -Subject: [PATCH 59/92] pvr: increase changes counter of stream on stream +Subject: [PATCH 47/82] pvr: increase changes counter of stream on stream change, cosmetics after dd307930d39d92f145a01a16600cd00e01ec39be --- @@ -17917,10 +10826,10 @@ index b96d520..df89f6f 100644 1.8.4 -From 2efbf1cc2c374a55763a1e14baaed315caf7bdfa Mon Sep 17 00:00:00 2001 +From 2282f99c5b031cf7d2f6e6a19bd528eab922c7c4 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 17 Jan 2013 16:03:22 +0100 -Subject: [PATCH 60/92] X11: add keymapping for XF86XK_Sleep +Subject: [PATCH 48/82] X11: add keymapping for XF86XK_Sleep --- xbmc/windowing/WinEventsX11.cpp | 1 + @@ -17942,10 +10851,10 @@ index 4a5aab4..da5d412 100644 1.8.4 -From 10e5e5457e8670bc5c4a7287657d3fccf8a2c3e6 Mon Sep 17 00:00:00 2001 +From 2a917d493a6dcb010eda16b4db205852ad6d3c34 Mon Sep 17 00:00:00 2001 From: xbmc Date: Mon, 21 Jan 2013 09:00:19 +0100 -Subject: [PATCH 61/92] X11: remove toggle full screen after resume +Subject: [PATCH 49/82] X11: remove toggle full screen after resume --- xbmc/powermanagement/PowerManager.cpp | 5 ----- @@ -17971,10 +10880,10 @@ index 2033574..c79bbc1 100644 1.8.4 -From cb9093718cda92031c7e940b219d15dfb274a239 Mon Sep 17 00:00:00 2001 +From 494566734dc681c81323430a24cd6f21e113816f Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 23 Jan 2013 17:03:02 +0100 -Subject: [PATCH 62/92] xrandr: set screen on mode change command +Subject: [PATCH 50/82] xrandr: set screen on mode change command --- xbmc/windowing/X11/XRandR.cpp | 2 +- @@ -17997,10 +10906,10 @@ index aa27d2b..67bf6ca 100644 1.8.4 -From 073d43dc107541c24481945f5acf8cb427f5e704 Mon Sep 17 00:00:00 2001 +From 1b5dc127b82ecc786a50b5ec4c2d2bdc732e9a03 Mon Sep 17 00:00:00 2001 From: xbmc Date: Wed, 23 Jan 2013 17:03:39 +0100 -Subject: [PATCH 63/92] X11: recreate glx context when output changes +Subject: [PATCH 51/82] X11: recreate glx context when output changes --- xbmc/windowing/X11/WinSystemX11.cpp | 6 +++--- @@ -18051,10 +10960,10 @@ index ce3c289..311e4cc 100644 1.8.4 -From 083ce98319c0c9b849e16efc469f374651e1bd12 Mon Sep 17 00:00:00 2001 +From 32b3c966846654f9d7bdd49ff2e5be25dc07a2cf Mon Sep 17 00:00:00 2001 From: xbmc Date: Fri, 14 Dec 2012 14:19:15 +0100 -Subject: [PATCH 64/92] pvr: do not show selection dialog for a single menu +Subject: [PATCH 52/82] pvr: do not show selection dialog for a single menu hook --- @@ -18092,10 +11001,10 @@ index aab6345..a880778 100644 1.8.4 -From e859d3f125a8824b65b10136436078e36cbd7b8b Mon Sep 17 00:00:00 2001 +From 86ed24b95f66616f2f4398ae59ff0fc3ed51a5f8 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 3 Feb 2013 08:17:16 +0100 -Subject: [PATCH 65/92] X11: use default screen parameters if no output +Subject: [PATCH 53/82] X11: use default screen parameters if no output connected --- @@ -18199,10 +11108,10 @@ index c84e793..5215f4d 100644 1.8.4 -From e7621880632371b72b295e8e9a6ccd24c72e11a9 Mon Sep 17 00:00:00 2001 +From b2cb0e1edd322fb0472de973133c667c77a98790 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 23 Mar 2013 15:13:32 +0100 -Subject: [PATCH 66/92] X11: create parent window +Subject: [PATCH 54/82] X11: create parent window --- xbmc/windowing/X11/WinSystemX11.cpp | 69 +++++++++++++++++++++++-------------- @@ -18468,10 +11377,10 @@ index 311e4cc..49365a8 100644 1.8.4 -From 625665f08a3c7232d95b9b2c1e281dff98b2281e Mon Sep 17 00:00:00 2001 +From f9aa6b012a2c77d41f24ed4ccc2d0f8a17222528 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 24 Mar 2013 12:30:12 +0100 -Subject: [PATCH 67/92] X11: use system key repeat rate instead of hardcoded +Subject: [PATCH 55/82] X11: use system key repeat rate instead of hardcoded one, taken from 58fd64b194e38b73b5f3132744bab35e994e7441 --- @@ -18673,10 +11582,10 @@ index 102a076..5b1f3fa 100644 1.8.4 -From 68254ec1769a18a4f56dde4ad849f26fad9532fb Mon Sep 17 00:00:00 2001 +From 9535bb8a20beb85fb9fdda60fe53a04661bf385f Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 24 Mar 2013 16:04:48 +0100 -Subject: [PATCH 68/92] linux: use CLOCK_MONOTONIC_RAW as this is not subject +Subject: [PATCH 56/82] linux: use CLOCK_MONOTONIC_RAW as this is not subject to NTP --- @@ -18714,20 +11623,20 @@ index c06b8c5..4390d2e 100644 1.8.4 -From e496631276113a87beb9ea30eee4f14902ba3907 Mon Sep 17 00:00:00 2001 +From 50a35896c28f54d2773e9eeced2b14ab2e7e194c Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 28 Mar 2013 15:18:53 +0100 -Subject: [PATCH 69/92] OMXPlayer: some caching fixes for pvr +Subject: [PATCH 57/82] OMXPlayer: some caching fixes for pvr --- xbmc/cores/omxplayer/OMXPlayer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index 12122e5..982b0a3 100644 +index 5efe74c..073c40a 100644 --- a/xbmc/cores/omxplayer/OMXPlayer.cpp +++ b/xbmc/cores/omxplayer/OMXPlayer.cpp -@@ -2472,7 +2472,8 @@ void COMXPlayer::HandleMessages() +@@ -2465,7 +2465,8 @@ void COMXPlayer::HandleMessages() m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true)); m_playSpeed = speed; @@ -18741,20 +11650,20 @@ index 12122e5..982b0a3 100644 1.8.4 -From ba73fd38ab94f7f81c1c1690e411dda228f619da Mon Sep 17 00:00:00 2001 +From 8cecb2207d37e3d00e2397bbb24210ad064efd57 Mon Sep 17 00:00:00 2001 From: xbmc Date: Thu, 28 Mar 2013 20:50:59 +0100 -Subject: [PATCH 70/92] fix incorrect display of fps when dr kicks in +Subject: [PATCH 58/82] fix incorrect display of fps when dr kicks in --- xbmc/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp -index becf35d..dd9d1e1 100644 +index 6440244..6dfa529 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp -@@ -2193,10 +2193,11 @@ void CApplication::Render() +@@ -2186,10 +2186,11 @@ void CApplication::Render() if (frameTime < singleFrameTime) Sleep(singleFrameTime - frameTime); } @@ -18771,10 +11680,10 @@ index becf35d..dd9d1e1 100644 1.8.4 -From 9eb4af8e626e9ebbf7f2846e3267cc07be903cf7 Mon Sep 17 00:00:00 2001 +From 4d742d884faf8df3c11be52a6072ff2b272e2bc4 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 13 Apr 2013 08:32:06 +0200 -Subject: [PATCH 71/92] X11: fix mouse coverage +Subject: [PATCH 59/82] X11: fix mouse coverage --- xbmc/windowing/X11/WinSystemX11.cpp | 11 ++++++++--- @@ -18840,10 +11749,10 @@ index 49365a8..924af1d 100644 1.8.4 -From 3fee0a2c4a652327a858f59ed25eb31f91f333f2 Mon Sep 17 00:00:00 2001 +From e4977a0310d6400aeb2561424b93f9cd67fa1163 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Wed, 8 May 2013 13:14:58 +0200 -Subject: [PATCH 72/92] X11: fix incorrectly used screen num in desktop +Subject: [PATCH 60/82] X11: fix incorrectly used screen num in desktop resolution --- @@ -18878,10 +11787,10 @@ index 186a28e..66955b8 100644 1.8.4 -From 47f0800857719e51489d733178a0790bac64c3da Mon Sep 17 00:00:00 2001 +From f4129ebd74140b9a35341b1ae7bbc310f98dd7dc Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Thu, 9 May 2013 12:07:09 +0200 -Subject: [PATCH 73/92] X11: do not overwrite user selected monitor with +Subject: [PATCH 61/82] X11: do not overwrite user selected monitor with fallback --- @@ -19006,10 +11915,10 @@ index 924af1d..2fb9e0f 100644 1.8.4 -From 4796ca401d76704a4f45a70bb473e3176d0557a3 Mon Sep 17 00:00:00 2001 +From 86ef774e333463b8f33f03f83575e581464077e0 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 12 May 2013 10:50:30 +0200 -Subject: [PATCH 74/92] xrandr: add turn on/off to wrapper +Subject: [PATCH 62/82] xrandr: add turn on/off to wrapper --- xbmc/windowing/X11/XRandR.cpp | 78 +++++++++++++++++++++++++++++++++++++++---- @@ -19175,10 +12084,10 @@ index d37838a..059062f 100644 1.8.4 -From 2837feba0c6dc8ab40a4ecc387fe2d1958685a19 Mon Sep 17 00:00:00 2001 +From 1e16699885ce90e2b71f9b47a30e38358e5b9859 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 19 May 2013 12:55:35 +0200 -Subject: [PATCH 75/92] xrandr: add GetPreferredMode to wrapper +Subject: [PATCH 63/82] xrandr: add GetPreferredMode to wrapper --- xbmc/windowing/X11/XRandR.cpp | 23 +++++++++++++++++++++++ @@ -19235,10 +12144,10 @@ index 059062f..ab7cc63 100644 1.8.4 -From 6ec9d5af504822f1f37f8571b3f350d920182b5d Mon Sep 17 00:00:00 2001 +From 633043eff1445f8d1b86eb3a7195eb9002a5d6e4 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 11 May 2013 17:12:12 +0200 -Subject: [PATCH 76/92] X11: multi-head improvement - poll for desired output +Subject: [PATCH 64/82] X11: multi-head improvement - poll for desired output if we do not get an xrr event --- @@ -19253,7 +12162,7 @@ Subject: [PATCH 76/92] X11: multi-head improvement - poll for desired output 8 files changed, 105 insertions(+), 12 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 5c7defd..76f56bb 100644 +index 03bb374..e972c5f 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -6258,7 +6258,7 @@ msgctxt "#14071" @@ -19280,10 +12189,10 @@ index 5c7defd..76f56bb 100644 #: xbmc/dialogs/GUIDialogFavourites.cpp msgctxt "#15015" diff --git a/system/settings/settings.xml b/system/settings/settings.xml -index 879c518..a48ad60 100644 +index 0426ff2..0a69e02 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml -@@ -1879,6 +1879,11 @@ +@@ -1858,6 +1858,11 @@ @@ -19295,7 +12204,7 @@ index 879c518..a48ad60 100644 0 0 -@@ -1930,6 +1935,7 @@ +@@ -1909,6 +1914,7 @@ @@ -19519,10 +12428,10 @@ index 4809821..1ad26b2 100644 1.8.4 -From dd3e11e1c6847ccee4b101c2632c7c5bccea2dbf Mon Sep 17 00:00:00 2001 +From cda408e90650ba90f47ea9cbee2a869dbe584bdc Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Wed, 15 May 2013 09:14:34 +0200 -Subject: [PATCH 77/92] X11: ignore mouse move event form other windows +Subject: [PATCH 65/82] X11: ignore mouse move event form other windows --- xbmc/windowing/WinEventsX11.cpp | 4 +++- @@ -19554,10 +12463,10 @@ index 6ddaead..e4451fe 100644 1.8.4 -From 34b584412f5113e90e52bd7d9f587d94564b7ea8 Mon Sep 17 00:00:00 2001 +From 3054287536df2549990f9f98bca2836955c1bf96 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Tue, 11 Jun 2013 16:20:29 +0200 -Subject: [PATCH 78/92] renderer: allow some lateness within vblank interval +Subject: [PATCH 66/82] renderer: allow some lateness within vblank interval --- xbmc/cores/VideoRenderers/RenderManager.cpp | 12 ++++++++++-- @@ -19617,10 +12526,10 @@ index befd851..27283ec 100644 1.8.4 -From 868b40722fca1e7bd6a722ba4f35368371fefd04 Mon Sep 17 00:00:00 2001 +From b8dde359e5ebc7734b6258ec18f072ffc761e223 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sun, 16 Jun 2013 13:22:58 +0200 -Subject: [PATCH 79/92] X11: another fix for mouse coverage +Subject: [PATCH 67/82] X11: another fix for mouse coverage --- xbmc/windowing/WinEventsX11.cpp | 6 ++++-- @@ -19653,10 +12562,10 @@ index e4451fe..582b9f5 100644 1.8.4 -From d171700fd3030c9e26f0491192a781fe1f2390fb Mon Sep 17 00:00:00 2001 +From c178f2b13f1c05086590cb29a1668779cfea959c Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 5 Jul 2013 12:14:00 +0200 -Subject: [PATCH 80/92] X11: set windows class name +Subject: [PATCH 68/82] X11: set windows class name --- xbmc/windowing/X11/WinSystemX11.cpp | 9 ++++++++- @@ -19698,17 +12607,17 @@ index 7e4b637..44e40a3 100644 1.8.4 -From 4b6cb92761b437f73161a1823086c1e5e9308f35 Mon Sep 17 00:00:00 2001 +From c0207d6302458e8ac54d5c60cb53225dbcf731c9 Mon Sep 17 00:00:00 2001 From: spiff Date: Tue, 16 Jul 2013 14:34:04 +0200 -Subject: [PATCH 81/92] fixed: typo +Subject: [PATCH 69/82] fixed: typo --- language/English/strings.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/English/strings.po b/language/English/strings.po -index 76f56bb..72be5e1 100644 +index e972c5f..91a68f2 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -6392,7 +6392,7 @@ msgstr "" @@ -19724,17 +12633,17 @@ index 76f56bb..72be5e1 100644 1.8.4 -From 9a82876013f47330a78228bd66e258c09fb7925b Mon Sep 17 00:00:00 2001 +From 43713c05a9f37cd667cb3b388b5b10648cabbdcd Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Thu, 25 Jul 2013 17:18:13 +0200 -Subject: [PATCH 82/92] ActiveAE: slightly reduce buffer size +Subject: [PATCH 70/82] ActiveAE: slightly reduce buffer size --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 3f0254d..59847ae 100644 +index 753829a..dae90a9 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -30,8 +30,8 @@ @@ -19752,10 +12661,10 @@ index 3f0254d..59847ae 100644 1.8.4 -From a6505bde2ff740013906bbdfa43c9fdd27c5e7b0 Mon Sep 17 00:00:00 2001 +From bb041249c55db4afe41807b36a985b95d46cb02b Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 4 Aug 2013 10:11:16 +0200 -Subject: [PATCH 83/92] Revert "vdpau: comment some features that will be added +Subject: [PATCH 71/82] Revert "vdpau: comment some features that will be added later" This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf. @@ -19764,7 +12673,7 @@ This reverts commit e00b4f65864d623ab4d2e9e5c06db138e661f1cf. 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp -index 87c0319..2f9e631 100644 +index 733f4f8..33bd873 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp @@ -938,8 +938,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) @@ -19821,10 +12730,10 @@ index 87c0319..2f9e631 100644 1.8.4 -From be2a89452d7d7576eb3a01a95271e59653cb0c26 Mon Sep 17 00:00:00 2001 +From 6266114d7981e5e297bddde16a61ed6201c46636 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 9 Aug 2013 18:01:40 +0200 -Subject: [PATCH 84/92] X11: fix keysyms +Subject: [PATCH 72/82] X11: fix keysyms --- xbmc/windowing/WinEventsX11.cpp | 2 +- @@ -19847,10 +12756,10 @@ index 582b9f5..ca31278 100644 1.8.4 -From 37103f278cdb0926eda8917fec3023fd54750ef5 Mon Sep 17 00:00:00 2001 +From 9f05dee2cc63aef157d0565a80b8ea3bc76be0ff Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 9 Aug 2013 18:42:36 +0200 -Subject: [PATCH 85/92] X11: fix keysym for non-IM +Subject: [PATCH 73/82] X11: fix keysym for non-IM --- xbmc/windowing/WinEventsX11.cpp | 2 +- @@ -19873,10 +12782,10 @@ index ca31278..db50d3c 100644 1.8.4 -From 451d4174afc90f874c6323d84b03720b43aad2b7 Mon Sep 17 00:00:00 2001 +From 0f06cc527109d59dfb9ff5434df47bcad8706469 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 10 Aug 2013 11:18:16 +0200 -Subject: [PATCH 86/92] add some missing multi media keys +Subject: [PATCH 74/82] add some missing multi media keys --- system/keymaps/keyboard.xml | 3 +++ @@ -19931,10 +12840,10 @@ index ee6bb69..364b45a 100644 1.8.4 -From 1dd1ed9be27574166cea7d3a7eeb838ec64a672a Mon Sep 17 00:00:00 2001 +From 64ced14e215f4cf45f73bf901155c2a3e86d975d Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 10 Aug 2013 15:32:06 +0200 -Subject: [PATCH 87/92] CWinSystemBase: keep RES_DESKTOP untouched at pos 0, +Subject: [PATCH 75/82] CWinSystemBase: keep RES_DESKTOP untouched at pos 0, fixes toggle fullscreen --- @@ -19969,10 +12878,10 @@ index bad5c95..b789134 100644 1.8.4 -From 4c2a00eb2464698ec2a279b3455ca610be0509d7 Mon Sep 17 00:00:00 2001 +From 1b33ccc3e07e9fba5f38a9bd0a36781e49968fc0 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sat, 10 Aug 2013 15:53:45 +0200 -Subject: [PATCH 88/92] X11: squash multi +Subject: [PATCH 76/82] X11: squash multi --- xbmc/windowing/X11/WinSystemX11.cpp | 2 +- @@ -19995,10 +12904,10 @@ index 44e40a3..a00481e 100644 1.8.4 -From 93607d509812396eb0b989593c4a3cc65afa6f2d Mon Sep 17 00:00:00 2001 +From 4f496d9af238bae7091af207ce297ce3e017d1ca Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Tue, 3 Sep 2013 20:46:17 +0200 -Subject: [PATCH 89/92] X11: do not poll default monitor +Subject: [PATCH 77/82] X11: do not poll default monitor --- xbmc/windowing/X11/WinSystemX11.cpp | 2 +- @@ -20021,237 +12930,943 @@ index a00481e..58ee352 100644 1.8.4 -From 615c1fe2ff904cdb9ebcd8edc0b2c42c3cd6218c Mon Sep 17 00:00:00 2001 +From 6036ca0665c788a9b15e9fecdd97ec229e9266d9 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker -Date: Mon, 9 Sep 2013 12:13:15 +0200 -Subject: [PATCH 90/92] ffmpeg backport: h264: do not discard NAL_SEI when - skipping frames +Date: Thu, 12 Sep 2013 22:28:50 +0200 +Subject: [PATCH 78/82] vdpau: exit gfx lock in OnLostDevice and OnResetDevice --- - lib/ffmpeg/libavcodec/h264.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 8 ++++++++ + 1 file changed, 8 insertions(+) -diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c -index 4f09c67..62ac8fb 100644 ---- a/lib/ffmpeg/libavcodec/h264.c -+++ b/lib/ffmpeg/libavcodec/h264.c -@@ -4529,8 +4529,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, - first_slice = hx->nal_unit_type; - } +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 33bd873..f318216 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -289,6 +289,8 @@ void CDecoder::OnLostDevice() + { + CLog::Log(LOGNOTICE,"CVDPAU::OnLostDevice event"); -- // FIXME do not discard SEI id -- if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0) -+ if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0 && h->nal_unit_type != NAL_SEI) - continue; ++ int count = g_graphicsContext.exit(); ++ + CSingleLock lock(m_DecoderSection); + FiniVDPAUOutput(); + FiniVDPAUProcs(); +@@ -296,12 +298,16 @@ void CDecoder::OnLostDevice() + m_DisplayState = VDPAU_LOST; + lock.Leave(); + m_DisplayEvent.Reset(); ++ ++ g_graphicsContext.restore(count); + } - again: + void CDecoder::OnResetDevice() + { + CLog::Log(LOGNOTICE,"CVDPAU::OnResetDevice event"); + ++ int count = g_graphicsContext.exit(); ++ + CSingleLock lock(m_DecoderSection); + if (m_DisplayState == VDPAU_LOST) + { +@@ -309,6 +315,8 @@ void CDecoder::OnResetDevice() + lock.Leave(); + m_DisplayEvent.Set(); + } ++ ++ g_graphicsContext.restore(count); + } + + int CDecoder::Check(AVCodecContext* avctx) -- 1.8.4 -From 452bb4cfee19f8d619007c6091a8786188ed4fc9 Mon Sep 17 00:00:00 2001 +From 46cb4d836341ad714ebdbbc9b5c27c6a38db8d67 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker -Date: Sun, 8 Sep 2013 20:02:17 +0200 -Subject: [PATCH 91/92] ActiveAE: fix toggling stereo upmix for spdif +Date: Tue, 17 Sep 2013 18:21:43 +0200 +Subject: [PATCH 79/82] vdpau: increase timeout for display event, some systems + are too slow switching refresh rate --- - .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 44 +++++++++++++--------- - xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h | 4 +- - 2 files changed, 29 insertions(+), 19 deletions(-) + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 59847ae..4fa3a2d 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -796,13 +796,9 @@ void CActiveAE::Process() - } - } - --void CActiveAE::Configure(AEAudioFormat *desiredFmt) -+AEAudioFormat CActiveAE::GetInputFormat(AEAudioFormat *desiredFmt) - { -- bool initSink = false; -- -- AEAudioFormat sinkInputFormat, inputFormat; -- AEAudioFormat oldInternalFormat = m_internalFormat; -- bool updateMode = true; -+ AEAudioFormat inputFormat; - - if (m_streams.empty()) +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index f318216..605d83b 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -330,7 +330,7 @@ int CDecoder::Check(AVCodecContext* avctx) + if (state == VDPAU_LOST) { -@@ -822,16 +818,28 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) - // keep format when having multiple streams - else if (m_streams.size() > 1 && m_silenceBuffers == NULL) - { -- inputFormat = m_sinkRequestFormat; -- updateMode = false; -+ inputFormat = m_inputFormat; - } - else - { - inputFormat = m_streams.front()->m_format; -+ m_inputFormat = inputFormat; - } + CLog::Log(LOGNOTICE,"CVDPAU::Check waiting for display reset event"); +- if (!m_DisplayEvent.WaitMSec(2000)) ++ if (!m_DisplayEvent.WaitMSec(4000)) + { + CLog::Log(LOGERROR, "CVDPAU::Check - device didn't reset in reasonable time"); + state = VDPAU_RESET; +-- +1.8.4 + + +From d81a07332411952623a1b5f053b01ab2166a31e7 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sat, 21 Sep 2013 14:17:09 +0200 +Subject: [PATCH 80/82] vdpau: drop old ffmpeg vdpau_render_state + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 392 ++++++++++++++----------- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h | 39 ++- + 2 files changed, 244 insertions(+), 187 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index 605d83b..e0784c4 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -80,6 +80,152 @@ + void* CDecoder::dl_handle; -+ return inputFormat; + //----------------------------------------------------------------------------- ++// VDPAU Video Surface states ++//----------------------------------------------------------------------------- ++ ++#define SURFACE_USED_FOR_REFERENCE 0x01 ++#define SURFACE_USED_FOR_RENDER 0x02 ++ ++void CVideoSurfaces::AddSurface(VdpVideoSurface surf) ++{ ++ CSingleLock lock(m_section); ++ m_state[surf] = SURFACE_USED_FOR_REFERENCE; +} + -+void CActiveAE::Configure(AEAudioFormat *desiredFmt) ++void CVideoSurfaces::ClearReference(VdpVideoSurface surf) +{ -+ bool initSink = false; ++ CSingleLock lock(m_section); ++ if (m_state.find(surf) == m_state.end()) ++ { ++ CLog::Log(LOGWARNING, "CVideoSurfaces::ClearReference - surface invalid"); ++ return; ++ } ++ m_state[surf] &= ~SURFACE_USED_FOR_REFERENCE; ++ if (m_state[surf] == 0) ++ { ++ m_freeSurfaces.push_back(surf); ++ } ++} + -+ AEAudioFormat sinkInputFormat, inputFormat; -+ AEAudioFormat oldInternalFormat = m_internalFormat; ++bool CVideoSurfaces::MarkRender(VdpVideoSurface surf) ++{ ++ CSingleLock lock(m_section); ++ if (m_state.find(surf) == m_state.end()) ++ { ++ CLog::Log(LOGWARNING, "CVideoSurfaces::MarkRender - surface invalid"); ++ return false; ++ } ++ std::list::iterator it; ++ it = std::find(m_freeSurfaces.begin(), m_freeSurfaces.end(), surf); ++ if (it != m_freeSurfaces.end()) ++ { ++ CLog::Log(LOGWARNING, "CVideoSurfaces::MarkRender - surface invalid 2"); ++ return false; ++ } ++ m_state[surf] |= SURFACE_USED_FOR_RENDER; ++ return true; ++} + -+ inputFormat = GetInputFormat(desiredFmt); ++void CVideoSurfaces::ClearRender(VdpVideoSurface surf) ++{ ++ CSingleLock lock(m_section); ++ if (m_state.find(surf) == m_state.end()) ++ { ++ CLog::Log(LOGWARNING, "CVideoSurfaces::ClearRender - surface invalid"); ++ return; ++ } ++ m_state[surf] &= ~SURFACE_USED_FOR_RENDER; ++ if (m_state[surf] == 0) ++ { ++ m_freeSurfaces.push_back(surf); ++ } ++} + - m_sinkRequestFormat = inputFormat; -- ApplySettingsToFormat(m_sinkRequestFormat, m_settings, updateMode); -+ ApplySettingsToFormat(m_sinkRequestFormat, m_settings, (int*)&m_mode); - std::string device = AE_IS_RAW(m_sinkRequestFormat.m_dataFormat) ? m_settings.passthoughdevice : m_settings.device; - std::string driver; - CAESinkFactory::ParseDevice(device, driver); -@@ -1202,10 +1210,10 @@ void CActiveAE::ChangeResamplers() ++bool CVideoSurfaces::IsValid(VdpVideoSurface surf) ++{ ++ CSingleLock lock(m_section); ++ if (m_state.find(surf) != m_state.end()) ++ return true; ++ else ++ return false; ++} ++ ++VdpVideoSurface CVideoSurfaces::GetFree(VdpVideoSurface surf) ++{ ++ CSingleLock lock(m_section); ++ if (m_state.find(surf) != m_state.end()) ++ { ++ std::list::iterator it; ++ it = std::find(m_freeSurfaces.begin(), m_freeSurfaces.end(), surf); ++ if (it == m_freeSurfaces.end()) ++ { ++ CLog::Log(LOGWARNING, "CVideoSurfaces::GetFree - surface not free"); ++ } ++ else ++ { ++ m_freeSurfaces.erase(it); ++ m_state[surf] = SURFACE_USED_FOR_REFERENCE; ++ return surf; ++ } ++ } ++ ++ if (!m_freeSurfaces.empty()) ++ { ++ VdpVideoSurface freeSurf = m_freeSurfaces.front(); ++ m_freeSurfaces.pop_front(); ++ m_state[freeSurf] = SURFACE_USED_FOR_REFERENCE; ++ return freeSurf; ++ } ++ ++ return VDP_INVALID_HANDLE; ++} ++ ++VdpVideoSurface CVideoSurfaces::GetAtIndex(int idx) ++{ ++ if (idx >= m_state.size()) ++ return VDP_INVALID_HANDLE; ++ ++ std::map::iterator it = m_state.begin(); ++ for(int i = 0; i < idx; i++) ++ ++it; ++ return it->first; ++} ++ ++VdpVideoSurface CVideoSurfaces::RemoveNext(bool skiprender) ++{ ++ CSingleLock lock(m_section); ++ VdpVideoSurface surf; ++ std::map::iterator it; ++ for(it = m_state.begin(); it != m_state.end(); ++it) ++ { ++ if (skiprender && it->second & SURFACE_USED_FOR_RENDER) ++ continue; ++ surf = it->first; ++ m_state.erase(surf); ++ ++ std::list::iterator it2; ++ it2 = std::find(m_freeSurfaces.begin(), m_freeSurfaces.end(), surf); ++ if (it2 != m_freeSurfaces.end()) ++ m_freeSurfaces.erase(it2); ++ return surf; ++ } ++ return VDP_INVALID_HANDLE; ++} ++ ++void CVideoSurfaces::Reset() ++{ ++ CSingleLock lock(m_section); ++ m_freeSurfaces.clear(); ++ m_state.clear(); ++} ++ ++int CVideoSurfaces::Size() ++{ ++ CSingleLock lock(m_section); ++ return m_state.size(); ++} ++ ++//----------------------------------------------------------------------------- + // CVDPAU + //----------------------------------------------------------------------------- + +@@ -87,7 +233,6 @@ + { + m_vdpauConfig.vdpDevice = VDP_INVALID_HANDLE; + m_vdpauConfig.videoSurfaces = &m_videoSurfaces; +- m_vdpauConfig.videoSurfaceSec = &m_videoSurfaceSec; + + m_vdpauConfigured = false; + m_hwContext.bitstream_buffers_allocated = 0; +@@ -164,6 +309,7 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int + m_hwContext.render = CDecoder::Render; + m_hwContext.bitstream_buffers_allocated = 0; + avctx->get_buffer = CDecoder::FFGetBuffer; ++ avctx->reget_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; +@@ -193,16 +339,6 @@ void CDecoder::Close() + FiniVDPAUProcs(); + m_vdpauOutput.Dispose(); + +- while (!m_videoSurfaces.empty()) +- { +- vdpau_render_state *render = m_videoSurfaces.back(); +- m_videoSurfaces.pop_back(); +- if (render->bitstream_buffers_allocated) +- m_dllAvUtil.av_freep(&render->bitstream_buffers); +- render->bitstream_buffers_allocated = 0; +- free(render); +- } +- + if (m_hwContext.bitstream_buffers_allocated) + { + m_dllAvUtil.av_freep(&m_hwContext.bitstream_buffers); +@@ -239,14 +375,10 @@ long CDecoder::Release() + m_DisplayState = VDPAU_ERROR; + } + +- for(unsigned int i = 0; i < m_videoSurfaces.size(); ++i) ++ VdpVideoSurface surf; ++ while((surf = m_videoSurfaces.RemoveNext(true)) != VDP_INVALID_HANDLE) + { +- 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; +- } ++ m_vdpauConfig.vdpProcs.vdp_video_surface_destroy(surf); + } } + return IHardwareDecoder::Release(); +@@ -514,20 +646,16 @@ void CDecoder::FiniVDPAUOutput() + return; + m_vdpauConfig.vdpDecoder = VDP_INVALID_HANDLE; + +- CSingleLock lock(m_videoSurfaceSec); +- CLog::Log(LOGDEBUG, "CVDPAU::FiniVDPAUOutput destroying %d video surfaces", (int)m_videoSurfaces.size()); ++ CLog::Log(LOGDEBUG, "CVDPAU::FiniVDPAUOutput destroying %d video surfaces", m_videoSurfaces.Size()); + +- for(unsigned int i = 0; i < m_videoSurfaces.size(); ++i) ++ VdpVideoSurface surf; ++ while((surf = m_videoSurfaces.RemoveNext()) != VDP_INVALID_HANDLE) + { +- vdpau_render_state *render = m_videoSurfaces[i]; +- if (render->surface != VDP_INVALID_HANDLE) +- { +- vdp_st = m_vdpauConfig.vdpProcs.vdp_video_surface_destroy(render->surface); +- render->surface = VDP_INVALID_HANDLE; +- } ++ m_vdpauConfig.vdpProcs.vdp_video_surface_destroy(surf); + if (CheckStatus(vdp_st, __LINE__)) + return; + } ++ m_videoSurfaces.Reset(); } --void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, bool setmode) -+void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode) - { -- if (setmode) -- m_mode = MODE_PCM; -+ if (mode) -+ *mode = MODE_PCM; + void CDecoder::ReadFormatOf( AVCodecID codec +@@ -696,33 +824,6 @@ void CDecoder::SpewHardwareAvailable() //CopyrighVDPAUt (c) 2008 Wladimir J. va - // raw pass through - if (m_settings.mode != AUDIO_ANALOG && AE_IS_RAW(format.m_dataFormat)) -@@ -1218,8 +1226,8 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett - { - CLog::Log(LOGERROR, "CActiveAE::ApplySettingsToFormat - input audio format is wrong"); - } -- if (setmode) -- m_mode = MODE_RAW; -+ if (mode) -+ *mode = MODE_RAW; + } + +-bool CDecoder::IsSurfaceValid(vdpau_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 == VDP_INVALID_HANDLE) +- { +- m_videoSurfaces[i]->state = 0; +- return false; +- } +- +- return true; +-} +- + int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) + { + //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); +@@ -738,63 +839,38 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) + return -1; } - // transcode - else if (m_settings.mode != AUDIO_ANALOG && -@@ -1231,8 +1239,8 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett - format.m_dataFormat = AE_FMT_AC3; - format.m_sampleRate = 48000; - format.m_channelLayout = AE_CH_LAYOUT_2_0; -- if (setmode) -- m_mode = MODE_TRANSCODE; -+ if (mode) -+ *mode = MODE_TRANSCODE; - } - else + +- vdpau_render_state * render = NULL; +- +- // find unused surface +- { CSingleLock lock(vdp->m_videoSurfaceSec); +- 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))) +- { +- render = vdp->m_videoSurfaces[i]; +- render->state = 0; +- break; +- } +- } +- } ++ VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)pic->data[3]; ++ surf = vdp->m_videoSurfaces.GetFree(surf != 0 ? surf : VDP_INVALID_HANDLE); + + VdpStatus vdp_st = VDP_STATUS_ERROR; +- if (render == NULL) ++ if (surf == VDP_INVALID_HANDLE) { -@@ -1283,7 +1291,7 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett + // create a new surface + VdpDecoderProfile profile; + ReadFormatOf(avctx->codec_id, 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); +- } - bool CActiveAE::NeedReconfigureBuffers() - { -- AEAudioFormat newFormat = m_sinkRequestFormat; -+ AEAudioFormat newFormat = GetInputFormat(); - ApplySettingsToFormat(newFormat, m_settings); - - if (newFormat.m_dataFormat != m_sinkRequestFormat.m_dataFormat || -@@ -1296,7 +1304,7 @@ bool CActiveAE::NeedReconfigureBuffers() - - bool CActiveAE::NeedReconfigureSink() - { -- AEAudioFormat newFormat = m_sinkRequestFormat; -+ AEAudioFormat newFormat = GetInputFormat(); - ApplySettingsToFormat(newFormat, m_settings); - - std::string device = AE_IS_RAW(newFormat.m_dataFormat) ? m_settings.passthoughdevice : m_settings.device; -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h -index 462c993..d684a44 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h -@@ -252,8 +252,9 @@ class CActiveAE : public IAE, private CThread - void LoadSettings(); - bool NeedReconfigureBuffers(); - bool NeedReconfigureSink(); -- void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, bool setmode = false); -+ void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode = NULL); - void Configure(AEAudioFormat *desiredFmt = NULL); -+ AEAudioFormat GetInputFormat(AEAudioFormat *desiredFmt = NULL); - CActiveAEStream* CreateStream(MsgStreamNew *streamMsg); - void DiscardStream(CActiveAEStream *stream); - void SFlushStream(CActiveAEStream *stream); -@@ -297,6 +298,7 @@ class CActiveAE : public IAE, private CThread - AEAudioFormat m_sinkRequestFormat; - AEAudioFormat m_encoderFormat; - AEAudioFormat m_internalFormat; -+ AEAudioFormat m_inputFormat; - AudioSettings m_settings; - CEngineStats m_stats; - IAEEncoder *m_encoder; --- -1.8.4 - - -From d64657004969b56678534798ef0aef16838fab21 Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Sun, 8 Sep 2013 20:50:40 +0200 -Subject: [PATCH 92/92] ActiveAE: fix channel layout for audiophile mode - ---- - .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 31 ++++++++++++---------- - 1 file changed, 17 insertions(+), 14 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 4fa3a2d..f8a44b5 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -1249,21 +1249,27 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett - settings.stereoupmix || - !g_advancedSettings.m_audioAudiophile) +- if (render->surface == VDP_INVALID_HANDLE) +- { + 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); ++ &surf); + vdp->CheckStatus(vdp_st, __LINE__); + if (vdp_st != VDP_STATUS_OK) { -+ CAEChannelInfo stdLayout; - switch (settings.channels) - { - default: -- case 0: format.m_channelLayout = AE_CH_LAYOUT_2_0; break; -- case 1: format.m_channelLayout = AE_CH_LAYOUT_2_0; break; -- case 2: format.m_channelLayout = AE_CH_LAYOUT_2_1; break; -- case 3: format.m_channelLayout = AE_CH_LAYOUT_3_0; break; -- case 4: format.m_channelLayout = AE_CH_LAYOUT_3_1; break; -- case 5: format.m_channelLayout = AE_CH_LAYOUT_4_0; break; -- case 6: format.m_channelLayout = AE_CH_LAYOUT_4_1; break; -- case 7: format.m_channelLayout = AE_CH_LAYOUT_5_0; break; -- case 8: format.m_channelLayout = AE_CH_LAYOUT_5_1; break; -- case 9: format.m_channelLayout = AE_CH_LAYOUT_7_0; break; -- case 10: format.m_channelLayout = AE_CH_LAYOUT_7_1; break; -+ case 0: stdLayout = AE_CH_LAYOUT_2_0; break; -+ case 1: stdLayout = AE_CH_LAYOUT_2_0; break; -+ case 2: stdLayout = AE_CH_LAYOUT_2_1; break; -+ case 3: stdLayout = AE_CH_LAYOUT_3_0; break; -+ case 4: stdLayout = AE_CH_LAYOUT_3_1; break; -+ case 5: stdLayout = AE_CH_LAYOUT_4_0; break; -+ case 6: stdLayout = AE_CH_LAYOUT_4_1; break; -+ case 7: stdLayout = AE_CH_LAYOUT_5_0; break; -+ case 8: stdLayout = AE_CH_LAYOUT_5_1; break; -+ case 9: stdLayout = AE_CH_LAYOUT_7_0; break; -+ case 10: stdLayout = AE_CH_LAYOUT_7_1; break; - } -+ -+ if (g_advancedSettings.m_audioAudiophile) -+ format.m_channelLayout.ResolveChannels(stdLayout); -+ else -+ format.m_channelLayout = stdLayout; +- free(render); + CLog::Log(LOGERROR, "CVDPAU::FFGetBuffer - No Video surface available could be created"); + return -1; } ++ vdp->m_videoSurfaces.AddSurface(surf); + } - if (m_settings.mode == AUDIO_IEC958 && format.m_sampleRate > 48000) -@@ -1283,9 +1289,6 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett + pic->data[1] = pic->data[2] = NULL; +- pic->data[0] = (uint8_t*)render; +- pic->data[3] = (uint8_t*)(uintptr_t)render->surface; ++ pic->data[0] = (uint8_t*)(uintptr_t)surf; ++ pic->data[3] = (uint8_t*)(uintptr_t)surf; + + pic->linesize[0] = pic->linesize[1] = pic->linesize[2] = 0; + + pic->type= FF_BUFFER_TYPE_USER; + +- render->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE; + pic->reordered_opaque= avctx->reordered_opaque; + return 0; + } +@@ -805,31 +881,17 @@ void CDecoder::FFReleaseBuffer(AVCodecContext *avctx, AVFrame *pic) + CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; + CDecoder* vdp = (CDecoder*)ctx->GetHardware(); + +- vdpau_render_state * render; ++ VdpVideoSurface surf; + unsigned int i; + + CSingleLock lock(vdp->m_DecoderSection); + +- render=(vdpau_render_state*)pic->data[0]; +- if(!render) +- { +- CLog::Log(LOGERROR, "CVDPAU::FFReleaseBuffer - invalid context handle provided"); +- return; +- } ++ surf = (VdpVideoSurface)(uintptr_t)pic->data[3]; ++ ++ vdp->m_videoSurfaces.ClearReference(surf); + +- CSingleLock vLock(vdp->m_videoSurfaceSec); +- render->state &= ~FF_VDPAU_STATE_USED_FOR_REFERENCE; + for(i=0; i<4; i++) + pic->data[i]= NULL; +- +- // find render state in queue +- if (!vdp->IsSurfaceValid(render)) +- { +- CLog::Log(LOGDEBUG, "CVDPAU::FFReleaseBuffer - ignoring invalid buffer"); +- return; +- } +- +- render->state &= ~FF_VDPAU_STATE_USED_FOR_REFERENCE; + } + + VdpStatus CDecoder::Render( VdpDecoder decoder, VdpVideoSurface target, +@@ -861,17 +923,10 @@ void CDecoder::FFDrawSlice(struct AVCodecContext *s, + } + + VdpStatus vdp_st; +- vdpau_render_state * render; +- +- render = (vdpau_render_state*)src->data[0]; +- if(!render) +- { +- CLog::Log(LOGERROR, "CVDPAU::FFDrawSlice - invalid context handle provided"); +- return; +- } ++ VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)src->data[3]; + + // ffmpeg vc-1 decoder does not flush, make sure the data buffer is still valid +- if (!vdp->IsSurfaceValid(render)) ++ if (!vdp->m_videoSurfaces.IsValid(surf)) + { + CLog::Log(LOGWARNING, "CVDPAU::FFDrawSlice - ignoring invalid buffer"); + return; +@@ -893,7 +948,7 @@ void CDecoder::FFDrawSlice(struct AVCodecContext *s, + 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, ++ surf, + (VdpPictureInfo const *)&(vdp->m_hwContext.info), + vdp->m_hwContext.bitstream_buffers_used, + vdp->m_hwContext.bitstream_buffers); +@@ -919,29 +974,20 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + if(pFrame) + { // we have a new frame from decoder + +- vdpau_render_state * render = (vdpau_render_state*)pFrame->data[0]; +- if(!render) +- { +- CLog::Log(LOGERROR, "CVDPAU::Decode: no valid frame"); +- return VC_ERROR; +- } +- ++ VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)pFrame->data[3]; + // ffmpeg vc-1 decoder does not flush, make sure the data buffer is still valid +- if (!IsSurfaceValid(render)) ++ if (!m_videoSurfaces.IsValid(surf)) { - format.m_channelLayout = AE_CH_LAYOUT_2_0; + CLog::Log(LOGWARNING, "CVDPAU::Decode - ignoring invalid buffer"); + return VC_BUFFER; } - -- CAEChannelInfo stdLayout = format.m_channelLayout; -- format.m_channelLayout.ResolveChannels(stdLayout); +- CSingleLock lock(m_videoSurfaceSec); +- render->state |= FF_VDPAU_STATE_USED_FOR_RENDER; +- lock.Leave(); ++ m_videoSurfaces.MarkRender(surf); + + // send frame to output for processing + CVdpauDecodedPicture pic; + memset(&pic.DVDPic, 0, sizeof(pic.DVDPic)); + ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(&pic.DVDPic); +- pic.render = render; ++ pic.videoSurface = surf; + pic.DVDPic.color_matrix = avctx->colorspace; + m_bufferStats.IncDecoded(); + m_vdpauOutput.m_dataPort.SendOutMessage(COutputDataProtocol::NEWFRAME, &pic, sizeof(pic)); +@@ -2126,17 +2172,13 @@ void CMixer::Flush() + { + 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; ++ m_config.videoSurfaces->ClearRender(pic.videoSurface); } + 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; ++ m_config.videoSurfaces->ClearRender(pic.videoSurface); + } + Message *msg; + while (m_dataPort.ReceiveOutMessage(&msg)) +@@ -2144,9 +2186,7 @@ void CMixer::Flush() + 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; ++ m_config.videoSurfaces->ClearRender(pic.videoSurface); + } + else if (msg->signal == CMixerDataProtocol::BUFFER) + { +@@ -2264,7 +2304,7 @@ void CMixer::InitCycle() + } + + m_processPicture.DVDPic = m_mixerInput[1].DVDPic; +- m_processPicture.render = m_mixerInput[1].render; ++ m_processPicture.videoSurface = m_mixerInput[1].videoSurface; + } + + void CMixer::FiniCycle() +@@ -2272,10 +2312,9 @@ void CMixer::FiniCycle() + while (m_mixerInput.size() > 3) + { + CVdpauDecodedPicture &tmp = m_mixerInput.back(); +- if (tmp.render && m_processPicture.DVDPic.format != RENDER_FMT_VDPAU_420) ++ if (m_processPicture.DVDPic.format != RENDER_FMT_VDPAU_420) + { +- CSingleLock lock(*m_config.videoSurfaceSec); +- tmp.render->state &= ~FF_VDPAU_STATE_USED_FOR_RENDER; ++ m_config.videoSurfaces->ClearRender(tmp.videoSurface); + } + m_mixerInput.pop_back(); + // m_config.stats->DecDecoded(); +@@ -2307,10 +2346,10 @@ void CMixer::ProcessPicture() + // 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; ++ past_surfaces[1] = m_mixerInput[3].videoSurface; + if (m_mixerInput.size() > 2) +- past_surfaces[0] = m_mixerInput[2].render->surface; +- futu_surfaces[0] = m_mixerInput[0].render->surface; ++ past_surfaces[0] = m_mixerInput[2].videoSurface; ++ futu_surfaces[0] = m_mixerInput[0].videoSurface; + pastCount = 2; + futuCount = 1; + } +@@ -2320,31 +2359,31 @@ void CMixer::ProcessPicture() + { // first field + if (m_mixerInput.size() > 3) + { +- past_surfaces[3] = m_mixerInput[3].render->surface; +- past_surfaces[2] = m_mixerInput[3].render->surface; ++ past_surfaces[3] = m_mixerInput[3].videoSurface; ++ past_surfaces[2] = m_mixerInput[3].videoSurface; + } + if (m_mixerInput.size() > 2) + { +- past_surfaces[1] = m_mixerInput[2].render->surface; +- past_surfaces[0] = m_mixerInput[2].render->surface; ++ past_surfaces[1] = m_mixerInput[2].videoSurface; ++ past_surfaces[0] = m_mixerInput[2].videoSurface; + } +- futu_surfaces[0] = m_mixerInput[1].render->surface; +- futu_surfaces[1] = m_mixerInput[0].render->surface;; ++ futu_surfaces[0] = m_mixerInput[1].videoSurface; ++ futu_surfaces[1] = m_mixerInput[0].videoSurface; + } + else + { // second field + if (m_mixerInput.size() > 3) + { +- past_surfaces[3] = m_mixerInput[3].render->surface; ++ past_surfaces[3] = m_mixerInput[3].videoSurface; + } + if (m_mixerInput.size() > 2) + { +- past_surfaces[2] = m_mixerInput[2].render->surface; +- past_surfaces[1] = m_mixerInput[2].render->surface; ++ past_surfaces[2] = m_mixerInput[2].videoSurface; ++ past_surfaces[1] = m_mixerInput[2].videoSurface; + } +- past_surfaces[0] = m_mixerInput[1].render->surface; +- futu_surfaces[0] = m_mixerInput[1].render->surface; +- futu_surfaces[1] = m_mixerInput[1].render->surface; ++ past_surfaces[0] = m_mixerInput[1].videoSurface; ++ futu_surfaces[0] = m_mixerInput[1].videoSurface; ++ futu_surfaces[1] = m_mixerInput[1].videoSurface; + + if (m_mixerInput[0].DVDPic.pts != DVD_NOPTS_VALUE && + m_mixerInput[1].DVDPic.pts != DVD_NOPTS_VALUE) +@@ -2379,7 +2418,7 @@ void CMixer::ProcessPicture() + m_mixerfield, + pastCount, + past_surfaces, +- m_mixerInput[1].render->surface, ++ m_mixerInput[1].videoSurface, + futuCount, + futu_surfaces, + &sourceRect, +@@ -2853,9 +2892,7 @@ void COutput::Flush() + 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; ++ m_config.videoSurfaces->ClearRender(pic.videoSurface); + } + } + msg->Release(); +@@ -2866,9 +2903,7 @@ void COutput::Flush() + 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; ++ m_config.videoSurfaces->ClearRender(pic.videoSurface); + } + else if (msg->signal == COutputDataProtocol::RETURNPIC) + { +@@ -2903,9 +2938,7 @@ void COutput::Flush() + 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; ++ m_config.videoSurfaces->MarkRender(it2->second.sourceVuv); + } + } + } +@@ -2999,9 +3032,9 @@ CVdpauRenderPicture* COutput::ProcessMixerPicture() + { + m_config.useInteropYuv = true; + GLMapSurfaces(); +- retPic->sourceIdx = procPic.render->surface; ++ retPic->sourceIdx = procPic.videoSurface; + for (unsigned int i=0; i<4; ++i) +- retPic->texture[i] = m_bufferPool.glVideoSurfaceMap[procPic.render->surface].texture[i]; ++ retPic->texture[i] = m_bufferPool.glVideoSurfaceMap[procPic.videoSurface].texture[i]; + retPic->texWidth = m_config.surfaceWidth; + retPic->texHeight = m_config.surfaceHeight; + retPic->crop.x1 = 0; +@@ -3118,9 +3151,8 @@ void COutput::ProcessReturnPicture(CVdpauRenderPicture *pic) + 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; ++ VdpVideoSurface surf = it->second.sourceVuv; ++ m_config.videoSurfaces->ClearRender(surf); + } + else if (pic->DVDPic.format == RENDER_FMT_VDPAU) + { +@@ -3526,17 +3558,19 @@ void COutput::GLMapSurfaces() + if (m_config.useInteropYuv) + { + VdpauBufferPool::GLVideoSurface glSurface; +- if (m_config.videoSurfaces->size() != m_bufferPool.glVideoSurfaceMap.size()) ++ VdpVideoSurface surf; ++ if (m_config.videoSurfaces->Size() != m_bufferPool.glVideoSurfaceMap.size()) + { +- CSingleLock lock(*m_config.videoSurfaceSec); +- for (unsigned int i = 0; i < m_config.videoSurfaces->size(); i++) ++ for (unsigned int i = 0; i < m_config.videoSurfaces->Size(); i++) + { +- if ((*m_config.videoSurfaces)[i]->surface == VDP_INVALID_HANDLE) ++ surf = m_config.videoSurfaces->GetAtIndex(i); ++ ++ if (surf == VDP_INVALID_HANDLE) + continue; + +- if (m_bufferPool.glVideoSurfaceMap.find((*m_config.videoSurfaces)[i]->surface) == m_bufferPool.glVideoSurfaceMap.end()) ++ if (m_bufferPool.glVideoSurfaceMap.find(surf) == m_bufferPool.glVideoSurfaceMap.end()) + { +- glSurface.sourceVuv = (*m_config.videoSurfaces)[i]; ++ glSurface.sourceVuv = surf; + while (glGetError() != GL_NO_ERROR) ; + glGenTextures(4, glSurface.texture); + if (glGetError() != GL_NO_ERROR) +@@ -3544,7 +3578,7 @@ void COutput::GLMapSurfaces() + CLog::Log(LOGERROR, "VDPAU::COutput error creating texture"); + m_vdpError = true; + } +- glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast((*m_config.videoSurfaces)[i]->surface), ++ glSurface.glVdpauSurface = glVDPAURegisterVideoSurfaceNV(reinterpret_cast(surf), + GL_TEXTURE_2D, 4, glSurface.texture); + + if (glGetError() != GL_NO_ERROR) +@@ -3564,7 +3598,7 @@ void COutput::GLMapSurfaces() + CLog::Log(LOGERROR, "VDPAU::COutput error mapping surface"); + m_vdpError = true; + } +- m_bufferPool.glVideoSurfaceMap[(*m_config.videoSurfaces)[i]->surface] = glSurface; ++ m_bufferPool.glVideoSurfaceMap[surf] = glSurface; + if (m_vdpError) + return; + CLog::Log(LOGNOTICE, "VDPAU::COutput registered surface"); +@@ -3616,7 +3650,7 @@ void COutput::GLUnmapSurfaces() + 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) + { +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +index db2671f..0b5239c 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.h +@@ -60,6 +60,7 @@ + #include "threads/Event.h" + #include "threads/Thread.h" + #include "utils/ActorProtocol.h" ++#include + + using namespace Actor; + +@@ -167,6 +168,8 @@ class CVdpauBufferStats + * for init. + */ + ++class CVideoSurfaces; ++ + struct CVdpauConfig + { + int surfaceWidth; +@@ -184,8 +187,7 @@ struct CVdpauConfig + int featureCount; + int upscale; + VdpVideoMixerFeature vdpFeatures[14]; +- std::vector *videoSurfaces; +- CCriticalSection *videoSurfaceSec; ++ CVideoSurfaces *videoSurfaces; + bool usePixmaps; + int numRenderBuffers; + uint32_t maxReferences; +@@ -199,7 +201,7 @@ struct CVdpauConfig + struct CVdpauDecodedPicture + { + DVDVideoPicture DVDPic; +- vdpau_render_state *render; ++ VdpVideoSurface videoSurface; + }; + + /** +@@ -208,7 +210,7 @@ struct CVdpauDecodedPicture + struct CVdpauProcessedPicture + { + DVDVideoPicture DVDPic; +- vdpau_render_state *render; ++ VdpVideoSurface videoSurface; + VdpOutputSurface outputSurface; + }; + +@@ -381,7 +383,7 @@ struct VdpauBufferPool + #ifdef GL_NV_vdpau_interop + GLvdpauSurfaceNV glVdpauSurface; + #endif +- vdpau_render_state *sourceVuv; ++ VdpVideoSurface sourceVuv; + VdpOutputSurface sourceRgb; + }; + std::vector allRenderPics; +@@ -511,6 +513,29 @@ class COutput : private CThread + }; + + //----------------------------------------------------------------------------- ++// VDPAU Video Surface states ++//----------------------------------------------------------------------------- ++ ++class CVideoSurfaces ++{ ++public: ++ void AddSurface(VdpVideoSurface surf); ++ void ClearReference(VdpVideoSurface surf); ++ bool MarkRender(VdpVideoSurface surf); ++ void ClearRender(VdpVideoSurface surf); ++ bool IsValid(VdpVideoSurface surf); ++ VdpVideoSurface GetFree(VdpVideoSurface surf); ++ VdpVideoSurface GetAtIndex(int idx); ++ VdpVideoSurface RemoveNext(bool skiprender = false); ++ void Reset(); ++ int Size(); ++protected: ++ std::map m_state; ++ std::list m_freeSurfaces; ++ CCriticalSection m_section; ++}; ++ ++//----------------------------------------------------------------------------- + // VDPAU decoder + //----------------------------------------------------------------------------- + +@@ -570,7 +595,6 @@ class CDecoder + 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(); +@@ -603,9 +627,8 @@ class CDecoder + ThreadIdentifier m_decoderThread; + bool m_vdpauConfigured; + CVdpauConfig m_vdpauConfig; +- std::vector m_videoSurfaces; ++ CVideoSurfaces m_videoSurfaces; + AVVDPAUContext m_hwContext; +- CCriticalSection m_videoSurfaceSec; + + COutput m_vdpauOutput; + CVdpauBufferStats m_bufferStats; +-- +1.8.4 + + +From 74110a11740b2c853d02311a3373a7bd82a6c115 Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Sun, 22 Sep 2013 15:03:43 +0200 +Subject: [PATCH 81/82] vdpau: reduce number of render pics to 4 + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index e0784c4..d239494 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -38,7 +38,12 @@ + #include "cores/VideoRenderers/RenderFlags.h" + + using namespace VDPAU; +-#define NUM_RENDER_PICS 9 ++ ++// we use GetAllowedReferences() - 1 output surfaces ++// this has the result that we won't wait for a free render buffer ++// in RenderManager::WaitForBuffer ++// instead we keep vdpau busy ++#define NUM_RENDER_PICS 4 + + #define ARSIZE(x) (sizeof(x) / sizeof((x)[0])) + +-- +1.8.4 + + +From 1b6809f4148456b550ddbdf7a843240664fba12f Mon Sep 17 00:00:00 2001 +From: Rainer Hochecker +Date: Tue, 24 Sep 2013 16:20:24 +0200 +Subject: [PATCH 82/82] vdpau: return from decode after max 50ms, required + after db6ba05611c13d07ee918918314d8f57febb4230 + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +index d239494..1e26d13 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp +@@ -1067,7 +1067,7 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + } + } + +- if (!retval && !m_inMsgEvent.WaitMSec(2000)) ++ if (!retval && !m_inMsgEvent.WaitMSec(50)) + break; + } + uint64_t diff = CurrentHostCounter() - startTime; +@@ -1075,16 +1075,6 @@ int CDecoder::Decode(AVCodecContext *avctx, AVFrame *pFrame) + { + m_bufferStats.SetParams(diff, m_codecControl); + } +- if (diff*1000/CurrentHostFrequency() > 50) +- CLog::Log(LOGDEBUG,"CVDPAU::Decode long wait: %d", (int)((diff*1000)/CurrentHostFrequency())); +- +- if (!retval) +- { +- CLog::Log(LOGERROR, "VDPAU::%s - timed out waiting for output message", __FUNCTION__); +- m_DisplayState = VDPAU_ERROR; +- retval |= VC_ERROR; +- } +- + return retval; } -- diff --git a/packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-995.10-disable-alt-tab.patch b/packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-995.10-disable-alt-tab.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/13.alpha-2ef8929/xbmc-995.10-disable-alt-tab.patch rename to packages/mediacenter/xbmc/patches/13.alpha-7f45288/xbmc-995.10-disable-alt-tab.patch