aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in1
-rw-r--r--configure.ac1
-rw-r--r--xbmc/Application.cpp2
-rw-r--r--xbmc/cores/VideoRenderers/BaseRenderer.h6
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.cpp (renamed from xbmc/cores/VideoRenderers/DXVAHD.cpp)0
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.h (renamed from xbmc/cores/VideoRenderers/DXVAHD.h)0
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.cpp (renamed from xbmc/cores/VideoRenderers/MMALRenderer.cpp)0
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.h (renamed from xbmc/cores/VideoRenderers/MMALRenderer.h)0
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/Makefile.in15
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.cpp264
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.h56
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.cpp174
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.h54
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.cpp418
-rw-r--r--xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.h64
-rw-r--r--xbmc/cores/VideoRenderers/LinuxRendererGL.cpp1004
-rw-r--r--xbmc/cores/VideoRenderers/LinuxRendererGL.h46
-rw-r--r--xbmc/cores/VideoRenderers/Makefile.in4
-rw-r--r--xbmc/cores/VideoRenderers/RenderManager.cpp387
-rw-r--r--xbmc/cores/VideoRenderers/RenderManager.h102
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp1
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.cpp136
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.h17
-rw-r--r--xbmc/guilib/GUIVideoControl.cpp4
24 files changed, 1610 insertions, 1146 deletions
diff --git a/Makefile.in b/Makefile.in
index c85825260d..dfd7861250 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,6 +37,7 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \
xbmc/cores/ExternalPlayer/ExternalPlayer.a \
xbmc/cores/VideoRenderers/VideoRenderer.a \
xbmc/cores/VideoRenderers/VideoShaders/VideoShaders.a \
+ xbmc/cores/VideoRenderers/HwDecRender/HwDecRender.a \
xbmc/cores/cores.a \
xbmc/cores/paplayer/paplayer.a \
xbmc/cores/playercorefactory/playercorefactory.a \
diff --git a/configure.ac b/configure.ac
index 53e662a3a0..3f5ddc78e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2356,6 +2356,7 @@ OUTPUT_FILES="Makefile \
xbmc/cdrip/Makefile \
xbmc/cores/Makefile \
xbmc/cores/VideoRenderers/Makefile \
+ xbmc/cores/VideoRenderers/HwDecRender/Makefile \
xbmc/cores/dvdplayer/Makefile \
lib/libdvd/Makefile \
xbmc/cores/DllLoader/Makefile \
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index e5787b9ded..32848b0e02 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -3554,7 +3554,7 @@ PlayBackRet CApplication::PlayFile(const CFileItem& item, bool bRestart)
else if(m_pPlayer->IsPlayingVideo())
{
// if player didn't manange to switch to fullscreen by itself do it here
- if (options.fullscreen && g_renderManager.IsStarted() &&
+ if (options.fullscreen && g_renderManager.IsConfigured() &&
g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO )
SwitchToFullScreen(true);
}
diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h
index 6c69b80146..81384a1ee5 100644
--- a/xbmc/cores/VideoRenderers/BaseRenderer.h
+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h
@@ -85,9 +85,9 @@ public:
virtual int GetImage(YV12Image *image, int source = -1, bool readonly = false) = 0;
virtual void ReleaseImage(int source, bool preserve = false) = 0;
virtual bool AddVideoPicture(DVDVideoPicture* picture, int index) { return false; }
- virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index) = 0;
+ virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index) {};
virtual void FlipPage(int source) = 0;
- virtual unsigned int PreInit() = 0;
+ virtual void PreInit() = 0;
virtual void UnInit() = 0;
virtual void Reset() = 0;
virtual void Flush() {};
@@ -110,6 +110,8 @@ public:
virtual bool Supports(EINTERLACEMETHOD method) = 0;
virtual bool Supports(ESCALINGMETHOD method) = 0;
+ ERenderFormat GetRenderFormat() { return m_format; }
+
void SetViewMode(int viewMode);
RESOLUTION GetResolution() const;
diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.cpp
index c8fd6717ee..c8fd6717ee 100644
--- a/xbmc/cores/VideoRenderers/DXVAHD.cpp
+++ b/xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.cpp
diff --git a/xbmc/cores/VideoRenderers/DXVAHD.h b/xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.h
index 154668f12b..154668f12b 100644
--- a/xbmc/cores/VideoRenderers/DXVAHD.h
+++ b/xbmc/cores/VideoRenderers/HwDecRender/DXVAHD.h
diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.cpp
index 466f44cfc3..466f44cfc3 100644
--- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp
+++ b/xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.cpp
diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.h b/xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.h
index d3e5129314..d3e5129314 100644
--- a/xbmc/cores/VideoRenderers/MMALRenderer.h
+++ b/xbmc/cores/VideoRenderers/HwDecRender/MMALRenderer.h
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/Makefile.in b/xbmc/cores/VideoRenderers/HwDecRender/Makefile.in
new file mode 100644
index 0000000000..a302e28efb
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/Makefile.in
@@ -0,0 +1,15 @@
+SRCS=
+
+ifeq (@USE_OPENGL@,1)
+SRCS += RendererVAAPI.cpp
+SRCS += RendererVDPAU.cpp
+endif
+
+ifeq (@USE_MMAL@,1)
+SRCS += MMALRenderer.cpp
+endif
+
+LIB=HwDecRender.a
+
+include ../../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) \ No newline at end of file
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.cpp b/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.cpp
new file mode 100644
index 0000000000..2744a5ac51
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "RendererVAAPI.h"
+
+#ifdef HAVE_LIBVA
+
+#include "cores/dvdplayer/DVDCodecs/Video/VAAPI.h"
+#include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h"
+#include "settings/Settings.h"
+#include "settings/AdvancedSettings.h"
+#include "utils/log.h"
+
+CRendererVAAPI::CRendererVAAPI()
+{
+
+}
+
+CRendererVAAPI::~CRendererVAAPI()
+{
+ for (int i = 0; i < NUM_BUFFERS; ++i)
+ {
+ DeleteTexture(i);
+ }
+}
+
+void CRendererVAAPI::AddVideoPictureHW(DVDVideoPicture &picture, int index)
+{
+ VAAPI::CVaapiRenderPicture *vaapi = picture.vaapi;
+ YUVBUFFER &buf = m_buffers[index];
+ VAAPI::CVaapiRenderPicture *pic = vaapi->Acquire();
+ if (buf.hwDec)
+ ((VAAPI::CVaapiRenderPicture*)buf.hwDec)->Release();
+ buf.hwDec = pic;
+
+ if (m_format == RENDER_FMT_VAAPINV12)
+ {
+ YV12Image &im = m_buffers[index].image;
+ CDVDCodecUtils::CopyNV12Picture(&im, &vaapi->DVDPic);
+ }
+}
+
+void CRendererVAAPI::ReleaseBuffer(int idx)
+{
+ YUVBUFFER &buf = m_buffers[idx];
+ if (buf.hwDec)
+ ((VAAPI::CVaapiRenderPicture*)buf.hwDec)->Release();
+ buf.hwDec = NULL;
+}
+
+CRenderInfo CRendererVAAPI::GetRenderInfo()
+{
+ CRenderInfo info;
+ info.formats = m_formats;
+ info.max_buffer_size = NUM_BUFFERS;
+ if (m_format == RENDER_FMT_VAAPINV12)
+ info.optimal_buffer_size = 3;
+ else
+ info.optimal_buffer_size = 5;
+ return info;
+}
+
+bool CRendererVAAPI::Supports(ERENDERFEATURE feature)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ return CLinuxRendererGL::Supports(feature);
+
+ if (feature == RENDERFEATURE_STRETCH ||
+ feature == RENDERFEATURE_ZOOM ||
+ feature == RENDERFEATURE_VERTICAL_SHIFT ||
+ feature == RENDERFEATURE_PIXEL_RATIO ||
+ feature == RENDERFEATURE_POSTPROCESS ||
+ feature == RENDERFEATURE_ROTATION ||
+ feature == RENDERFEATURE_NONLINSTRETCH)
+ return true;
+
+ return false;
+}
+
+bool CRendererVAAPI::Supports(EINTERLACEMETHOD method)
+{
+ VAAPI::CVaapiRenderPicture *vaapiPic = (VAAPI::CVaapiRenderPicture*)m_buffers[m_iYV12RenderBuffer].hwDec;
+ if(vaapiPic && vaapiPic->vaapi)
+ return vaapiPic->vaapi->Supports(method);
+ return false;
+}
+
+bool CRendererVAAPI::Supports(ESCALINGMETHOD method)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ return CLinuxRendererGL::Supports(method);
+
+ //nearest neighbor doesn't work on YUY2 and UYVY
+ if (method == VS_SCALINGMETHOD_NEAREST &&
+ m_format != RENDER_FMT_YUYV422 &&
+ m_format != RENDER_FMT_UYVY422)
+ return true;
+
+ if(method == VS_SCALINGMETHOD_LINEAR
+ || method == VS_SCALINGMETHOD_AUTO)
+ return true;
+
+ if(method == VS_SCALINGMETHOD_CUBIC
+ || method == VS_SCALINGMETHOD_LANCZOS2
+ || method == VS_SCALINGMETHOD_SPLINE36_FAST
+ || method == VS_SCALINGMETHOD_LANCZOS3_FAST
+ || method == VS_SCALINGMETHOD_SPLINE36
+ || method == VS_SCALINGMETHOD_LANCZOS3)
+ {
+ // if scaling is below level, avoid hq scaling
+ float scaleX = fabs(((float)m_sourceWidth - m_destRect.Width())/m_sourceWidth)*100;
+ float scaleY = fabs(((float)m_sourceHeight - m_destRect.Height())/m_sourceHeight)*100;
+ int minScale = CSettings::Get().GetInt("videoplayer.hqscalers");
+ if (scaleX < minScale && scaleY < minScale)
+ return false;
+
+ // spline36 and lanczos3 are only allowed through advancedsettings.xml
+ if(method != VS_SCALINGMETHOD_SPLINE36
+ && method != VS_SCALINGMETHOD_LANCZOS3)
+ return true;
+ else
+ return g_advancedSettings.m_videoEnableHighQualityHwScalers;
+ }
+
+ return false;
+}
+
+bool CRendererVAAPI::LoadShadersHook()
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ return false;
+
+ CLog::Log(LOGNOTICE, "GL: Using VAAPI render method");
+ m_renderMethod = RENDER_VAAPI;
+ return true;
+}
+
+bool CRendererVAAPI::RenderHook(int idx)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ return false;
+
+ UpdateVideoFilter();
+ RenderRGB(idx, m_currentField);
+ YUVBUFFER &buf = m_buffers[idx];
+ if (buf.hwDec)
+ {
+ ((VAAPI::CVaapiRenderPicture*)buf.hwDec)->Sync();
+ }
+ return true;
+}
+
+bool CRendererVAAPI::CreateTexture(int index)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ {
+ return CreateNV12Texture(index);
+ }
+
+ YV12Image &im = m_buffers[index].image;
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[0][0];
+
+ DeleteTexture(index);
+
+ memset(&im , 0, sizeof(im));
+ memset(&fields, 0, sizeof(fields));
+ im.height = m_sourceHeight;
+ im.width = m_sourceWidth;
+
+ plane.texwidth = im.width;
+ plane.texheight = im.height;
+
+ plane.pixpertex_x = 1;
+ plane.pixpertex_y = 1;
+
+ plane.id = 1;
+
+ return true;
+}
+
+void CRendererVAAPI::DeleteTexture(int index)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ {
+ DeleteNV12Texture(index);
+ return;
+ }
+
+ YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0];
+ if (m_buffers[index].hwDec)
+ ((VAAPI::CVaapiRenderPicture*)m_buffers[index].hwDec)->Release();
+ m_buffers[index].hwDec = NULL;
+ plane.id = 0;
+}
+
+bool CRendererVAAPI::UploadTexture(int index)
+{
+ if (m_format == RENDER_FMT_VAAPINV12)
+ {
+ return UploadNV12Texture(index);
+ }
+
+ VAAPI::CVaapiRenderPicture *vaapi = (VAAPI::CVaapiRenderPicture*)m_buffers[index].hwDec;
+
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[FIELD_FULL][0];
+
+ if (!vaapi || !vaapi->valid)
+ {
+ return false;
+ }
+
+ if (!vaapi->CopyGlx())
+ return false;
+
+ plane.id = vaapi->texture;
+
+ // in stereoscopic mode sourceRect may only
+ // be a part of the source video surface
+ plane.rect = m_sourceRect;
+
+ // clip rect
+ if (vaapi->crop.x1 > plane.rect.x1)
+ plane.rect.x1 = vaapi->crop.x1;
+ if (vaapi->crop.x2 < plane.rect.x2)
+ plane.rect.x2 = vaapi->crop.x2;
+ if (vaapi->crop.y1 > plane.rect.y1)
+ plane.rect.y1 = vaapi->crop.y1;
+ if (vaapi->crop.y2 < plane.rect.y2)
+ plane.rect.y2 = vaapi->crop.y2;
+
+ plane.texheight = vaapi->texHeight;
+ plane.texwidth = vaapi->texWidth;
+
+ if (m_textureTarget == GL_TEXTURE_2D)
+ {
+ plane.rect.y1 /= plane.texheight;
+ plane.rect.y2 /= plane.texheight;
+ plane.rect.x1 /= plane.texwidth;
+ plane.rect.x2 /= plane.texwidth;
+ }
+ return true;
+}
+
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.h b/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.h
new file mode 100644
index 0000000000..c6d0615ae7
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVAAPI.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "system.h"
+
+#ifdef HAVE_LIBVA
+
+#include "cores/VideoRenderers/LinuxRendererGL.h"
+
+class CRendererVAAPI : public CLinuxRendererGL
+{
+public:
+ CRendererVAAPI();
+ virtual ~CRendererVAAPI();
+
+ // Player functions
+ virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
+ virtual void ReleaseBuffer(int idx);
+ virtual CRenderInfo GetRenderInfo();
+
+ // Feature support
+ virtual bool Supports(ERENDERFEATURE feature);
+ virtual bool Supports(EINTERLACEMETHOD method);
+ virtual bool Supports(ESCALINGMETHOD method);
+
+protected:
+ virtual bool LoadShadersHook();
+ virtual bool RenderHook(int idx);
+
+ // textures
+ virtual bool UploadTexture(int index);
+ virtual void DeleteTexture(int index);
+ virtual bool CreateTexture(int index);
+};
+
+#endif
+
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.cpp b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.cpp
new file mode 100644
index 0000000000..41c9add383
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "RendererVDA.h"
+
+#if defined(TARGET_DARWIN_OSX)
+
+#include "settings/Settings.h"
+#include "settings/AdvancedSettings.h"
+#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "utils/log.h"
+#include "osx/CocoaInterface.h"
+#include <CoreVideo/CoreVideo.h>
+#include <OpenGL/CGLIOSurface.h>
+#include "windowing/WindowingFactory.h"
+
+CRendererVDA::CRendererVDA()
+{
+
+}
+
+CRendererVDA::~CRendererVDA()
+{
+
+}
+
+void CRendererVDA::AddVideoPictureHW(DVDVideoPicture &picture, int index)
+{
+ YUVBUFFER &buf = m_buffers[index];
+ if (buf.hwDec)
+ CVBufferRelease((struct __CVBuffer *)buf.hwDec);
+ buf.hwDec = picture.cvBufferRef;
+ // retain another reference, this way dvdplayer and renderer can issue releases.
+ CVBufferRetain(picture.cvBufferRef);
+}
+
+void CRendererVDA::ReleaseBuffer(int idx)
+{
+ YUVBUFFER &buf = m_buffers[idx];
+ if (buf.hwDec)
+ CVBufferRelease((struct __CVBuffer *)buf.hwDec);
+ buf.hwDec = NULL;
+}
+
+
+bool CRendererVDA::Supports(EINTERLACEMETHOD method)
+{
+ return false;
+}
+
+bool CRendererVDA::Supports(EDEINTERLACEMODE mode)
+{
+ return false;
+}
+
+EINTERLACEMETHOD CRendererVDA::AutoInterlaceMethod()
+{
+ return VS_INTERLACEMETHOD_NONE;
+}
+
+bool CRendererVDA::LoadShadersHook()
+{
+ CLog::Log(LOGNOTICE, "GL: Using CVBREF render method");
+ // m_renderMethod = RENDER_CVREF;
+ m_textureTarget = GL_TEXTURE_RECTANGLE_ARB;
+ return false;
+}
+
+bool CRendererVDA::CreateTexture(int index)
+{
+ YV12Image &im = m_buffers[index].image;
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[0][0];
+
+ DeleteTexture(index);
+
+ memset(&im , 0, sizeof(im));
+ memset(&fields, 0, sizeof(fields));
+
+ im.bpp = 1;
+ im.width = m_sourceWidth;
+ im.height = m_sourceHeight;
+ im.cshift_x = 0;
+ im.cshift_y = 0;
+
+ plane.pixpertex_x = 2;
+ plane.pixpertex_y = 1;
+ plane.texwidth = im.width / plane.pixpertex_x;
+ plane.texheight = im.height / plane.pixpertex_y;
+
+ if(m_renderMethod & RENDER_POT)
+ {
+ plane.texwidth = NP2(plane.texwidth);
+ plane.texheight = NP2(plane.texheight);
+ }
+
+ glEnable(m_textureTarget);
+ glGenTextures(1, &plane.id);
+ glDisable(m_textureTarget);
+
+ return true;
+}
+
+void CRendererVDA::DeleteTexture(int index)
+{
+ YUVPLANE &plane = m_buffers[index].fields[0][0];
+
+ if (m_buffers[index].hwDec)
+ CVBufferRelease((struct __CVBuffer *)m_buffers[index].hwDec);
+ m_buffers[index].hwDec = NULL;
+
+ if (plane.id && glIsTexture(plane.id))
+ glDeleteTextures(1, &plane.id), plane.id = 0;
+}
+
+bool CRendererVDA::UploadTexture(int index)
+{
+ YUVBUFFER &buf = m_buffers[index];
+ YUVFIELDS &fields = buf.fields;
+
+ CVBufferRef cvBufferRef = (struct __CVBuffer *)m_buffers[index].hwDec;
+
+ glEnable(m_textureTarget);
+
+ if (cvBufferRef && fields[m_currentField][0].flipindex != buf.flipindex)
+ {
+
+ // It is the fastest way to render a CVPixelBuffer backed
+ // with an IOSurface as there is no CPU -> GPU upload.
+ CGLContextObj cgl_ctx = (CGLContextObj)g_Windowing.GetCGLContextObj();
+ IOSurfaceRef surface = CVPixelBufferGetIOSurface(cvBufferRef);
+ GLsizei texWidth = IOSurfaceGetWidth(surface);
+ GLsizei texHeight= IOSurfaceGetHeight(surface);
+ OSType format_type = IOSurfaceGetPixelFormat(surface);
+
+ glBindTexture(m_textureTarget, fields[FIELD_FULL][0].id);
+
+ if (format_type == kCVPixelFormatType_422YpCbCr8)
+ CGLTexImageIOSurface2D(cgl_ctx, m_textureTarget, GL_RGBA8,
+ texWidth / 2, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
+ else if (format_type == kCVPixelFormatType_32BGRA)
+ CGLTexImageIOSurface2D(cgl_ctx, m_textureTarget, GL_RGBA8,
+ texWidth, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
+
+ glBindTexture(m_textureTarget, 0);
+ fields[FIELD_FULL][0].flipindex = buf.flipindex;
+
+ }
+
+
+ CalculateTextureSourceRects(index, 3);
+ glDisable(m_textureTarget);
+
+ return true;
+}
+
+#endif \ No newline at end of file
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.h b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.h
new file mode 100644
index 0000000000..a170dd66a2
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDA.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "system.h"
+
+#if defined(TARGET_DARWIN_OSX)
+
+#include "cores/VideoRenderers/LinuxRendererGL.h"
+
+class CRendererVDA : public CLinuxRendererGL
+{
+public:
+ CRendererVDA();
+ virtual ~CRendererVDA();
+
+ // Player functions
+ virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
+ virtual void ReleaseBuffer(int idx);
+
+ // Feature support
+ virtual bool Supports(EINTERLACEMETHOD method);
+ virtual bool Supports(EDEINTERLACEMODE mode);
+
+ virtual EINTERLACEMETHOD AutoInterlaceMethod();
+
+protected:
+ virtual bool LoadShadersHook();
+
+ // textures
+ virtual bool UploadTexture(int index);
+ virtual void DeleteTexture(int index);
+ virtual bool CreateTexture(int index);
+};
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.cpp b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.cpp
new file mode 100644
index 0000000000..13378989a7
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.cpp
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "RendererVDPAU.h"
+
+#ifdef HAVE_LIBVDPAU
+
+#include "cores/dvdplayer/DVDCodecs/Video/VDPAU.h"
+#include "settings/Settings.h"
+#include "settings/AdvancedSettings.h"
+#include "utils/log.h"
+#include "utils/GLUtils.h"
+
+CRendererVDPAU::CRendererVDPAU()
+{
+
+}
+
+CRendererVDPAU::~CRendererVDPAU()
+{
+ for (int i = 0; i < NUM_BUFFERS; ++i)
+ {
+ DeleteTexture(i);
+ }
+}
+
+void CRendererVDPAU::AddVideoPictureHW(DVDVideoPicture &picture, int index)
+{
+ VDPAU::CVdpauRenderPicture *vdpau = picture.vdpau;
+ YUVBUFFER &buf = m_buffers[index];
+ VDPAU::CVdpauRenderPicture *pic = vdpau->Acquire();
+ if (buf.hwDec)
+ ((VDPAU::CVdpauRenderPicture*)buf.hwDec)->Release();
+ buf.hwDec = pic;
+}
+
+void CRendererVDPAU::ReleaseBuffer(int idx)
+{
+ YUVBUFFER &buf = m_buffers[idx];
+ if (buf.hwDec)
+ ((VDPAU::CVdpauRenderPicture*)buf.hwDec)->Release();
+ buf.hwDec = NULL;
+}
+
+CRenderInfo CRendererVDPAU::GetRenderInfo()
+{
+ CRenderInfo info;
+ info.formats = m_formats;
+ info.max_buffer_size = NUM_BUFFERS;
+ info.optimal_buffer_size = 5;
+ return info;
+}
+
+bool CRendererVDPAU::Supports(ERENDERFEATURE feature)
+{
+ if(feature == RENDERFEATURE_BRIGHTNESS ||
+ feature == RENDERFEATURE_CONTRAST)
+ {
+ if ((m_renderMethod & RENDER_VDPAU) && !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE))
+ return true;
+
+ return (m_renderMethod & RENDER_GLSL)
+ || (m_renderMethod & RENDER_ARB)
+ || ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE);
+ }
+ else if (feature == RENDERFEATURE_NOISE ||
+ feature == RENDERFEATURE_SHARPNESS)
+ {
+ if (m_format == RENDER_FMT_VDPAU)
+ return true;
+ }
+ else if (feature == RENDERFEATURE_STRETCH ||
+ feature == RENDERFEATURE_ZOOM ||
+ feature == RENDERFEATURE_VERTICAL_SHIFT ||
+ feature == RENDERFEATURE_PIXEL_RATIO ||
+ feature == RENDERFEATURE_POSTPROCESS ||
+ feature == RENDERFEATURE_ROTATION ||
+ feature == RENDERFEATURE_NONLINSTRETCH)
+ return true;
+
+ return false;
+}
+
+bool CRendererVDPAU::Supports(EINTERLACEMETHOD method)
+{
+ VDPAU::CVdpauRenderPicture *VDPAUPic = (VDPAU::CVdpauRenderPicture*)m_buffers[m_iYV12RenderBuffer].hwDec;
+ if(VDPAUPic && VDPAUPic->vdpau)
+ return VDPAUPic->vdpau->Supports(method);
+ return false;
+}
+
+bool CRendererVDPAU::Supports(ESCALINGMETHOD method)
+{
+ if (m_format == RENDER_FMT_VDPAU_420)
+ return CLinuxRendererGL::Supports(method);
+
+ //nearest neighbor doesn't work on YUY2 and UYVY
+ if (method == VS_SCALINGMETHOD_NEAREST &&
+ m_format != RENDER_FMT_YUYV422 &&
+ m_format != RENDER_FMT_UYVY422)
+ return true;
+
+ if(method == VS_SCALINGMETHOD_LINEAR
+ || method == VS_SCALINGMETHOD_AUTO)
+ return true;
+
+ if(method == VS_SCALINGMETHOD_CUBIC
+ || method == VS_SCALINGMETHOD_LANCZOS2
+ || method == VS_SCALINGMETHOD_SPLINE36_FAST
+ || method == VS_SCALINGMETHOD_LANCZOS3_FAST
+ || method == VS_SCALINGMETHOD_SPLINE36
+ || method == VS_SCALINGMETHOD_LANCZOS3)
+ {
+ // if scaling is below level, avoid hq scaling
+ float scaleX = fabs(((float)m_sourceWidth - m_destRect.Width())/m_sourceWidth)*100;
+ float scaleY = fabs(((float)m_sourceHeight - m_destRect.Height())/m_sourceHeight)*100;
+ int minScale = CSettings::GetInstance().GetInt("videoplayer.hqscalers");
+ if (scaleX < minScale && scaleY < minScale)
+ return false;
+
+ // spline36 and lanczos3 are only allowed through advancedsettings.xml
+ if(method != VS_SCALINGMETHOD_SPLINE36
+ && method != VS_SCALINGMETHOD_LANCZOS3)
+ return true;
+ else
+ return g_advancedSettings.m_videoEnableHighQualityHwScalers;
+ }
+
+ return false;
+}
+
+bool CRendererVDPAU::LoadShadersHook()
+{
+ if (m_format == RENDER_FMT_VDPAU)
+ {
+ CLog::Log(LOGNOTICE, "GL: Using VDPAU render method");
+ m_renderMethod = RENDER_VDPAU;
+ return true;
+ }
+ return false;
+}
+
+bool CRendererVDPAU::RenderHook(int idx)
+{
+ UpdateVideoFilter();
+
+ if (m_format == RENDER_FMT_VDPAU_420)
+ {
+ switch(m_renderQuality)
+ {
+ case RQ_LOW:
+ case RQ_SINGLEPASS:
+ if (m_currentField == FIELD_FULL)
+ RenderProgressiveWeave(idx, m_currentField);
+ else
+ RenderSinglePass(idx, m_currentField);
+ VerifyGLState();
+ break;
+
+ case RQ_MULTIPASS:
+ if (m_currentField == FIELD_FULL)
+ RenderProgressiveWeave(idx, m_currentField);
+ else
+ {
+ RenderToFBO(idx, m_currentField);
+ RenderFromFBO();
+ }
+ VerifyGLState();
+ break;
+ }
+ }
+ else
+ {
+ RenderRGB(idx, m_currentField);
+ }
+
+ YUVBUFFER &buf = m_buffers[idx];
+ if (buf.hwDec)
+ {
+ ((VDPAU::CVdpauRenderPicture*)buf.hwDec)->Sync();
+ }
+ return true;
+}
+
+bool CRendererVDPAU::CreateTexture(int index)
+{
+ if (m_format == RENDER_FMT_VDPAU)
+ return CreateVDPAUTexture(index);
+ else if (m_format == RENDER_FMT_VDPAU_420)
+ return CreateVDPAUTexture420(index);
+ else
+ return false;
+}
+
+void CRendererVDPAU::DeleteTexture(int index)
+{
+ if (m_format == RENDER_FMT_VDPAU)
+ DeleteVDPAUTexture(index);
+ else if (m_format == RENDER_FMT_VDPAU_420)
+ DeleteVDPAUTexture420(index);
+}
+
+bool CRendererVDPAU::UploadTexture(int index)
+{
+ if (m_format == RENDER_FMT_VDPAU)
+ return UploadVDPAUTexture(index);
+ else if (m_format == RENDER_FMT_VDPAU_420)
+ return UploadVDPAUTexture420(index);
+ else
+ return false;
+}
+
+bool CRendererVDPAU::CreateVDPAUTexture(int index)
+{
+ YV12Image &im = m_buffers[index].image;
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[FIELD_FULL][0];
+
+ DeleteVDPAUTexture(index);
+
+ memset(&im , 0, sizeof(im));
+ memset(&fields, 0, sizeof(fields));
+ im.height = m_sourceHeight;
+ im.width = m_sourceWidth;
+
+ plane.texwidth = im.width;
+ plane.texheight = im.height;
+
+ plane.pixpertex_x = 1;
+ plane.pixpertex_y = 1;
+
+ plane.id = 1;
+ return true;
+}
+
+void CRendererVDPAU::DeleteVDPAUTexture(int index)
+{
+ YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0];
+
+ if (m_buffers[index].hwDec)
+ ((VDPAU::CVdpauRenderPicture*)m_buffers[index].hwDec)->Release();
+ m_buffers[index].hwDec = NULL;
+
+ plane.id = 0;
+}
+
+bool CRendererVDPAU::UploadVDPAUTexture(int index)
+{
+ VDPAU::CVdpauRenderPicture *vdpau = (VDPAU::CVdpauRenderPicture*)m_buffers[index].hwDec;
+
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[FIELD_FULL][0];
+
+ if (!vdpau || !vdpau->valid)
+ {
+ return false;
+ }
+
+ plane.id = vdpau->texture[0];
+
+ // in stereoscopic mode sourceRect may only
+ // be a part of the source video surface
+ plane.rect = m_sourceRect;
+
+ // clip rect
+ if (vdpau->crop.x1 > plane.rect.x1)
+ plane.rect.x1 = vdpau->crop.x1;
+ if (vdpau->crop.x2 < plane.rect.x2)
+ plane.rect.x2 = vdpau->crop.x2;
+ if (vdpau->crop.y1 > plane.rect.y1)
+ plane.rect.y1 = vdpau->crop.y1;
+ if (vdpau->crop.y2 < plane.rect.y2)
+ plane.rect.y2 = vdpau->crop.y2;
+
+ plane.texheight = vdpau->texHeight;
+ plane.texwidth = vdpau->texWidth;
+
+ if (m_textureTarget == GL_TEXTURE_2D)
+ {
+ plane.rect.y1 /= plane.texheight;
+ plane.rect.y2 /= plane.texheight;
+ plane.rect.x1 /= plane.texwidth;
+ plane.rect.x2 /= plane.texwidth;
+ }
+
+ return true;
+}
+
+bool CRendererVDPAU::CreateVDPAUTexture420(int index)
+{
+ 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;
+
+ return true;
+}
+
+void CRendererVDPAU::DeleteVDPAUTexture420(int index)
+{
+ YUVFIELDS &fields = m_buffers[index].fields;
+
+ if (m_buffers[index].hwDec)
+ ((VDPAU::CVdpauRenderPicture*)m_buffers[index].hwDec)->Release();
+ m_buffers[index].hwDec = NULL;
+
+ 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;
+}
+
+bool CRendererVDPAU::UploadVDPAUTexture420(int index)
+{
+ VDPAU::CVdpauRenderPicture *vdpau = (VDPAU::CVdpauRenderPicture*)m_buffers[index].hwDec;
+ YV12Image &im = m_buffers[index].image;
+
+ 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);
+ return true;
+}
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.h b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.h
new file mode 100644
index 0000000000..55ab570993
--- /dev/null
+++ b/xbmc/cores/VideoRenderers/HwDecRender/RendererVDPAU.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "system.h"
+
+#ifdef HAVE_LIBVDPAU
+
+#include "cores/VideoRenderers/LinuxRendererGL.h"
+
+class CRendererVDPAU : public CLinuxRendererGL
+{
+public:
+ CRendererVDPAU();
+ virtual ~CRendererVDPAU();
+
+ // Player functions
+ virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
+ virtual void ReleaseBuffer(int idx);
+ virtual CRenderInfo GetRenderInfo();
+
+ // Feature support
+ virtual bool Supports(ERENDERFEATURE feature);
+ virtual bool Supports(EINTERLACEMETHOD method);
+ virtual bool Supports(ESCALINGMETHOD method);
+
+protected:
+ virtual bool LoadShadersHook();
+ virtual bool RenderHook(int idx);
+
+ // textures
+ virtual bool UploadTexture(int index);
+ virtual void DeleteTexture(int index);
+ virtual bool CreateTexture(int index);
+
+ bool CreateVDPAUTexture(int index);
+ void DeleteVDPAUTexture(int index);
+ bool UploadVDPAUTexture(int index);
+
+ bool CreateVDPAUTexture420(int index);
+ void DeleteVDPAUTexture420(int index);
+ bool UploadVDPAUTexture420(int index);
+};
+
+#endif
+
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
index cec75eb863..0ba50fabe7 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
@@ -54,20 +54,11 @@ extern "C" {
#include "libswscale/swscale.h"
}
-#ifdef HAVE_LIBVDPAU
-#include "cores/dvdplayer/DVDCodecs/Video/VDPAU.h"
-#endif
-#ifdef HAVE_LIBVA
-#include "cores/dvdplayer/DVDCodecs/Video/VAAPI.h"
-#endif
-
-#ifdef TARGET_DARWIN
- #include "osx/CocoaInterface.h"
- #include <CoreVideo/CoreVideo.h>
- #include <OpenGL/CGLIOSurface.h>
- #ifdef TARGET_DARWIN_OSX
- #include "osx/DarwinUtils.h"
- #endif
+#ifdef TARGET_DARWIN_OSX
+#include "osx/CocoaInterface.h"
+#include <CoreVideo/CoreVideo.h>
+#include <OpenGL/CGLIOSurface.h>
+#include "osx/DarwinUtils.h"
#endif
//due to a bug on osx nvidia, using gltexsubimage2d with a pbo bound and a null pointer
@@ -119,23 +110,12 @@ CLinuxRendererGL::YUVBUFFER::YUVBUFFER()
memset(&image , 0, sizeof(image));
memset(&pbo , 0, sizeof(pbo));
flipindex = 0;
-#ifdef HAVE_LIBVDPAU
- vdpau = NULL;
-#endif
-#ifdef HAVE_LIBVA
- vaapi = NULL;
-#endif
-#ifdef TARGET_DARWIN_OSX
- cvBufferRef = NULL;
-#endif
+ hwDec = NULL;
}
CLinuxRendererGL::YUVBUFFER::~YUVBUFFER()
{
-#ifdef TARGET_DARWIN_OSX
- if (cvBufferRef)
- CVBufferRelease(cvBufferRef);
-#endif
+
}
CLinuxRendererGL::CLinuxRendererGL()
@@ -156,11 +136,6 @@ CLinuxRendererGL::CLinuxRendererGL()
m_scalingMethod = VS_SCALINGMETHOD_LINEAR;
m_scalingMethodGui = (ESCALINGMETHOD)-1;
- // default texture handlers to YUV
- m_textureUpload = &CLinuxRendererGL::UploadYV12Texture;
- m_textureCreate = &CLinuxRendererGL::CreateYV12Texture;
- m_textureDelete = &CLinuxRendererGL::DeleteYV12Texture;
-
m_rgbBuffer = NULL;
m_rgbBufferSize = 0;
m_context = NULL;
@@ -224,7 +199,7 @@ bool CLinuxRendererGL::ValidateRenderer()
return false;
int index = m_iYV12RenderBuffer;
- YUVBUFFER& buf = m_buffers[index];
+ YUVBUFFER& buf = m_buffers[index];
if (!buf.fields[FIELD_FULL][0].id)
return false;
@@ -239,20 +214,16 @@ bool CLinuxRendererGL::ValidateRenderTarget()
{
if (!m_bValidated)
{
- if ((m_format == RENDER_FMT_CVBREF) ||
- (!glewIsSupported("GL_ARB_texture_non_power_of_two") && glewIsSupported("GL_ARB_texture_rectangle")))
+ if (!glewIsSupported("GL_ARB_texture_non_power_of_two") && glewIsSupported("GL_ARB_texture_rectangle"))
{
- CLog::Log(LOGNOTICE,"Using GL_TEXTURE_RECTANGLE_ARB");
m_textureTarget = GL_TEXTURE_RECTANGLE_ARB;
}
- else
- CLog::Log(LOGNOTICE,"Using GL_TEXTURE_2D");
// function pointer for texture might change in
// call to LoadShaders
glFinish();
for (int i = 0 ; i < NUM_BUFFERS ; i++)
- (this->*m_textureDelete)(i);
+ DeleteTexture(i);
// trigger update of video filters
m_scalingMethodGui = (ESCALINGMETHOD)-1;
@@ -260,8 +231,13 @@ bool CLinuxRendererGL::ValidateRenderTarget()
// create the yuv textures
LoadShaders();
+ if (m_textureTarget == GL_TEXTURE_RECTANGLE_ARB)
+ CLog::Log(LOGNOTICE,"Using GL_TEXTURE_RECTANGLE_ARB");
+ else
+ CLog::Log(LOGNOTICE,"Using GL_TEXTURE_2D");
+
for (int i = 0 ; i < m_NumYV12Buffers ; i++)
- (this->*m_textureCreate)(i);
+ CreateTexture(i);
m_bValidated = true;
return true;
@@ -328,8 +304,11 @@ int CLinuxRendererGL::NextYV12Texture()
int CLinuxRendererGL::GetImage(YV12Image *image, int source, bool readonly)
{
- if (!image) return -1;
- if (!m_bValidated) return -1;
+ if (!image)
+ return -1;
+
+ if (!m_bValidated)
+ return -1;
/* take next available buffer */
if( source == AUTOSOURCE )
@@ -539,7 +518,7 @@ void CLinuxRendererGL::Flush()
glFinish();
for (int i = 0 ; i < m_NumYV12Buffers ; i++)
- (this->*m_textureDelete)(i);
+ DeleteTexture(i);
glFinish();
m_bValidated = false;
@@ -547,24 +526,6 @@ void CLinuxRendererGL::Flush()
m_iYV12RenderBuffer = 0;
}
-void CLinuxRendererGL::ReleaseBuffer(int idx)
-{
-#if defined(HAVE_LIBVDPAU) || defined(HAVE_LIBVA) || defined(TARGET_DARWIN)
- YUVBUFFER &buf = m_buffers[idx];
-#endif
-#ifdef HAVE_LIBVDPAU
- SAFE_RELEASE(buf.vdpau);
-#endif
-#ifdef HAVE_LIBVA
- SAFE_RELEASE(buf.vaapi);
-#endif
-#ifdef TARGET_DARWIN
- if (buf.cvBufferRef)
- CVBufferRelease(buf.cvBufferRef);
- buf.cvBufferRef = NULL;
-#endif
-}
-
void CLinuxRendererGL::Update()
{
if (!m_bConfigured) return;
@@ -713,7 +674,7 @@ void CLinuxRendererGL::FlipPage(int source)
return;
}
-unsigned int CLinuxRendererGL::PreInit()
+void CLinuxRendererGL::PreInit()
{
CSingleLock lock(g_graphicsContext);
m_bConfigured = false;
@@ -755,14 +716,9 @@ unsigned int CLinuxRendererGL::PreInit()
m_formats.push_back(RENDER_FMT_NV12);
m_formats.push_back(RENDER_FMT_YUYV422);
m_formats.push_back(RENDER_FMT_UYVY422);
-#ifdef TARGET_DARWIN
- m_formats.push_back(RENDER_FMT_CVBREF);
-#endif
// setup the background colour
m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff;
-
- return true;
}
void CLinuxRendererGL::UpdateVideoFilter()
@@ -834,7 +790,7 @@ void CLinuxRendererGL::UpdateVideoFilter()
case VS_SCALINGMETHOD_LINEAR:
SetTextureFilter(m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR);
m_renderQuality = RQ_SINGLEPASS;
- if (((m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI)) && m_nonLinStretch)
+ if (Supports(RENDERFEATURE_NONLINSTRETCH) && m_nonLinStretch)
{
m_pVideoFilterShader = new StretchFilterShader();
if (!m_pVideoFilterShader->CompileAndLink())
@@ -913,17 +869,7 @@ void CLinuxRendererGL::UpdateVideoFilter()
void CLinuxRendererGL::LoadShaders(int field)
{
- if (m_format == RENDER_FMT_VDPAU)
- {
- CLog::Log(LOGNOTICE, "GL: Using VDPAU render method");
- m_renderMethod = RENDER_VDPAU;
- }
- else if (m_format == RENDER_FMT_VAAPI)
- {
- CLog::Log(LOGNOTICE, "GL: Using VAAPI render method");
- m_renderMethod = RENDER_VAAPI;
- }
- else
+ if (!LoadShadersHook())
{
int requestedMethod = CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_RENDERMETHOD);
CLog::Log(LOGDEBUG, "GL: Requested render method: %d", requestedMethod);
@@ -1007,13 +953,6 @@ void CLinuxRendererGL::LoadShaders(int field)
}
}
- /* cvbref format piggy back on normal glsl */
- if (m_format == RENDER_FMT_CVBREF)
- {
- CLog::Log(LOGNOTICE, "GL: Using CVBREF render method");
- m_renderMethod |= RENDER_CVREF;
- }
-
// determine whether GPU supports NPOT textures
if (!glewIsSupported("GL_ARB_texture_non_power_of_two"))
{
@@ -1039,57 +978,6 @@ void CLinuxRendererGL::LoadShaders(int field)
}
else
m_pboUsed = false;
-
- // Now that we now the render method, setup texture function handlers
- if (m_format == RENDER_FMT_NV12 ||
- m_format == RENDER_FMT_VAAPINV12)
- {
- m_textureUpload = &CLinuxRendererGL::UploadNV12Texture;
- m_textureCreate = &CLinuxRendererGL::CreateNV12Texture;
- m_textureDelete = &CLinuxRendererGL::DeleteNV12Texture;
- }
- else if (m_format == RENDER_FMT_YUYV422 ||
- m_format == RENDER_FMT_UYVY422)
- {
- m_textureUpload = &CLinuxRendererGL::UploadYUV422PackedTexture;
- m_textureCreate = &CLinuxRendererGL::CreateYUV422PackedTexture;
- m_textureDelete = &CLinuxRendererGL::DeleteYUV422PackedTexture;
- }
- else if (m_format == RENDER_FMT_VDPAU)
- {
- m_textureUpload = &CLinuxRendererGL::UploadVDPAUTexture;
- 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;
- m_textureCreate = &CLinuxRendererGL::CreateVAAPITexture;
- m_textureDelete = &CLinuxRendererGL::DeleteVAAPITexture;
- }
- else if (m_format == RENDER_FMT_CVBREF)
- {
- m_textureUpload = &CLinuxRendererGL::UploadCVRefTexture;
- m_textureCreate = &CLinuxRendererGL::CreateCVRefTexture;
- m_textureDelete = &CLinuxRendererGL::DeleteCVRefTexture;
- }
- else
- {
- // setup default YV12 texture handlers
- m_textureUpload = &CLinuxRendererGL::UploadYV12Texture;
- m_textureCreate = &CLinuxRendererGL::CreateYV12Texture;
- m_textureDelete = &CLinuxRendererGL::DeleteYV12Texture;
- }
-
- //in case of software colorspace conversion, all formats are handled by the same method
- if (m_renderMethod & RENDER_SW)
- m_textureUpload = &CLinuxRendererGL::UploadRGBTexture;
}
void CLinuxRendererGL::UnInit()
@@ -1121,8 +1009,7 @@ void CLinuxRendererGL::UnInit()
// YV12 textures
for (int i = 0; i < NUM_BUFFERS; ++i)
{
- (this->*m_textureDelete)(i);
- DeleteVAAPITexture(i);
+ DeleteTexture(i);
}
// cleanup framebuffer object if it was in use
@@ -1145,31 +1032,25 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
m_currentField = FIELD_FULL;
// call texture load function
- if (!(this->*m_textureUpload)(renderBuffer))
+ if (!UploadTexture(renderBuffer))
return;
- if (m_renderMethod & RENDER_GLSL)
+ if (RenderHook(renderBuffer))
+ ;
+ else if (m_renderMethod & RENDER_GLSL)
{
UpdateVideoFilter();
switch(m_renderQuality)
{
case RQ_LOW:
case RQ_SINGLEPASS:
- if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL)
- RenderProgressiveWeave(renderBuffer, m_currentField);
- else
- RenderSinglePass(renderBuffer, m_currentField);
+ RenderSinglePass(renderBuffer, m_currentField);
VerifyGLState();
break;
case RQ_MULTIPASS:
- if (m_format == RENDER_FMT_VDPAU_420 && m_currentField == FIELD_FULL)
- RenderProgressiveWeave(renderBuffer, m_currentField);
- else
- {
- RenderToFBO(renderBuffer, m_currentField);
- RenderFromFBO();
- }
+ RenderToFBO(renderBuffer, m_currentField);
+ RenderFromFBO();
VerifyGLState();
break;
}
@@ -1178,46 +1059,11 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
{
RenderSinglePass(renderBuffer, m_currentField);
}
-#ifdef HAVE_LIBVDPAU
- else if (m_renderMethod & RENDER_VDPAU)
- {
- UpdateVideoFilter();
- RenderRGB(renderBuffer, m_currentField);
- }
-#endif
-#ifdef HAVE_LIBVA
- else if (m_renderMethod & RENDER_VAAPI)
- {
- UpdateVideoFilter();
- RenderRGB(renderBuffer, m_currentField);
- }
-#endif
else
{
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
-#ifdef HAVE_LIBVA
- if (m_format == RENDER_FMT_VAAPI)
- {
- YUVBUFFER &buf = m_buffers[renderBuffer];
- if (buf.vaapi)
- {
- buf.vaapi->Sync();
- }
- }
-#endif
}
void CLinuxRendererGL::RenderSinglePass(int index, int field)
@@ -1557,7 +1403,6 @@ void CLinuxRendererGL::RenderProgressiveWeave(int index, int field)
void CLinuxRendererGL::RenderRGB(int index, int field)
{
-#if defined(HAVE_LIBVDPAU) || defined(HAVE_LIBVA)
YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0];
glEnable(m_textureTarget);
@@ -1626,7 +1471,6 @@ void CLinuxRendererGL::RenderRGB(int index, int field)
glBindTexture (m_textureTarget, 0);
glDisable(m_textureTarget);
-#endif
}
void CLinuxRendererGL::RenderSoftware(int index, int field)
@@ -1705,132 +1549,6 @@ bool CLinuxRendererGL::RenderCapture(CRenderCapture* capture)
return true;
}
-//********************************************************************************************************
-// YV12 Texture creation, deletion, copying + clearing
-//********************************************************************************************************
-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 false;
- bool deinterlacing;
- if (m_currentField == FIELD_FULL)
- deinterlacing = false;
- else
- deinterlacing = true;
-
- glEnable(m_textureTarget);
- VerifyGLState();
-
- glPixelStorei(GL_UNPACK_ALIGNMENT,1);
-
- if (deinterlacing)
- {
- // Load Even Y Field
- LoadPlane( fields[FIELD_TOP][0] , GL_LUMINANCE, buf.flipindex
- , im->width, im->height >> 1
- , im->stride[0]*2, im->bpp, im->plane[0] );
-
- //load Odd Y Field
- LoadPlane( fields[FIELD_BOT][0], GL_LUMINANCE, buf.flipindex
- , im->width, im->height >> 1
- , im->stride[0]*2, im->bpp, im->plane[0] + im->stride[0]) ;
-
- // Load Even U & V Fields
- LoadPlane( fields[FIELD_TOP][1], GL_LUMINANCE, buf.flipindex
- , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
- , im->stride[1]*2, im->bpp, im->plane[1] );
-
- LoadPlane( fields[FIELD_TOP][2], GL_ALPHA, buf.flipindex
- , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
- , im->stride[2]*2, im->bpp, im->plane[2] );
-
- // Load Odd U & V Fields
- LoadPlane( fields[FIELD_BOT][1], GL_LUMINANCE, buf.flipindex
- , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
- , im->stride[1]*2, im->bpp, im->plane[1] + im->stride[1] );
-
- LoadPlane( fields[FIELD_BOT][2], GL_ALPHA, buf.flipindex
- , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
- , im->stride[2]*2, im->bpp, im->plane[2] + im->stride[2] );
- }
- else
- {
- //Load Y plane
- LoadPlane( fields[FIELD_FULL][0], GL_LUMINANCE, buf.flipindex
- , im->width, im->height
- , im->stride[0], im->bpp, im->plane[0] );
-
- //load U plane
- LoadPlane( fields[FIELD_FULL][1], GL_LUMINANCE, buf.flipindex
- , im->width >> im->cshift_x, im->height >> im->cshift_y
- , im->stride[1], im->bpp, im->plane[1] );
-
- //load V plane
- LoadPlane( fields[FIELD_FULL][2], GL_ALPHA, buf.flipindex
- , im->width >> im->cshift_x, im->height >> im->cshift_y
- , im->stride[2], im->bpp, im->plane[2] );
- }
-
- VerifyGLState();
-
- CalculateTextureSourceRects(source, 3);
-
- glDisable(m_textureTarget);
- return true;
-}
-
-void CLinuxRendererGL::DeleteYV12Texture(int index)
-{
- YV12Image &im = m_buffers[index].image;
- YUVFIELDS &fields = m_buffers[index].fields;
- GLuint *pbo = m_buffers[index].pbo;
-
- if( fields[FIELD_FULL][0].id == 0 ) return;
-
- /* finish up all textures, and delete them */
- g_graphicsContext.BeginPaint(); //FIXME
- for(int f = 0;f<MAX_FIELDS;f++)
- {
- for(int p = 0;p<MAX_PLANES;p++)
- {
- if( fields[f][p].id )
- {
- if (glIsTexture(fields[f][p].id))
- glDeleteTextures(1, &fields[f][p].id);
- fields[f][p].id = 0;
- }
- }
- }
- g_graphicsContext.EndPaint();
-
- for(int p = 0;p<MAX_PLANES;p++)
- {
- if (pbo[p])
- {
- if (im.plane[p])
- {
- glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo[p]);
- glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
- im.plane[p] = NULL;
- glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
- }
- glDeleteBuffersARB(1, pbo + p);
- pbo[p] = 0;
- }
- else
- {
- if (im.plane[p])
- {
- delete[] im.plane[p];
- im.plane[p] = NULL;
- }
- }
- }
-}
static GLint GetInternalFormat(GLint format, int bpp)
{
@@ -1851,6 +1569,52 @@ static GLint GetInternalFormat(GLint format, int bpp)
return format;
}
+//-----------------------------------------------------------------------------
+// Textures
+//-----------------------------------------------------------------------------
+
+bool CLinuxRendererGL::CreateTexture(int index)
+{
+ if (m_format == RENDER_FMT_NV12)
+ return CreateNV12Texture(index);
+ else if (m_format == RENDER_FMT_YUYV422 ||
+ m_format == RENDER_FMT_UYVY422)
+ return CreateYUV422PackedTexture(index);
+ else
+ return CreateYV12Texture(index);
+}
+
+void CLinuxRendererGL::DeleteTexture(int index)
+{
+ if (m_format == RENDER_FMT_NV12)
+ DeleteNV12Texture(index);
+ else if (m_format == RENDER_FMT_YUYV422 ||
+ m_format == RENDER_FMT_UYVY422)
+ DeleteYUV422PackedTexture(index);
+ else
+ DeleteYV12Texture(index);
+}
+
+bool CLinuxRendererGL::UploadTexture(int index)
+{
+ if (m_format == RENDER_FMT_NV12)
+ return UploadNV12Texture(index);
+ else if (m_format == RENDER_FMT_YUYV422 ||
+ m_format == RENDER_FMT_UYVY422)
+ return UploadYUV422PackedTexture(index);
+ //in case of software colorspace conversion, all formats are handled by the same method
+ else if (m_renderMethod & RENDER_SW)
+ return UploadRGBTexture(index);
+ else
+ return UploadYV12Texture(index);
+
+ return false;
+}
+
+//********************************************************************************************************
+// YV12 Texture creation, deletion, copying + clearing
+//********************************************************************************************************
+
bool CLinuxRendererGL::CreateYV12Texture(int index)
{
/* since we also want the field textures, pitch must be texture aligned */
@@ -2014,6 +1778,130 @@ bool CLinuxRendererGL::CreateYV12Texture(int index)
return true;
}
+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 false;
+ bool deinterlacing;
+ if (m_currentField == FIELD_FULL)
+ deinterlacing = false;
+ else
+ deinterlacing = true;
+
+ glEnable(m_textureTarget);
+ VerifyGLState();
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+
+ if (deinterlacing)
+ {
+ // Load Even Y Field
+ LoadPlane( fields[FIELD_TOP][0] , GL_LUMINANCE, buf.flipindex
+ , im->width, im->height >> 1
+ , im->stride[0]*2, im->bpp, im->plane[0] );
+
+ //load Odd Y Field
+ LoadPlane( fields[FIELD_BOT][0], GL_LUMINANCE, buf.flipindex
+ , im->width, im->height >> 1
+ , im->stride[0]*2, im->bpp, im->plane[0] + im->stride[0]) ;
+
+ // Load Even U & V Fields
+ LoadPlane( fields[FIELD_TOP][1], GL_LUMINANCE, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
+ , im->stride[1]*2, im->bpp, im->plane[1] );
+
+ LoadPlane( fields[FIELD_TOP][2], GL_ALPHA, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
+ , im->stride[2]*2, im->bpp, im->plane[2] );
+
+ // Load Odd U & V Fields
+ LoadPlane( fields[FIELD_BOT][1], GL_LUMINANCE, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
+ , im->stride[1]*2, im->bpp, im->plane[1] + im->stride[1] );
+
+ LoadPlane( fields[FIELD_BOT][2], GL_ALPHA, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
+ , im->stride[2]*2, im->bpp, im->plane[2] + im->stride[2] );
+ }
+ else
+ {
+ //Load Y plane
+ LoadPlane( fields[FIELD_FULL][0], GL_LUMINANCE, buf.flipindex
+ , im->width, im->height
+ , im->stride[0], im->bpp, im->plane[0] );
+
+ //load U plane
+ LoadPlane( fields[FIELD_FULL][1], GL_LUMINANCE, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> im->cshift_y
+ , im->stride[1], im->bpp, im->plane[1] );
+
+ //load V plane
+ LoadPlane( fields[FIELD_FULL][2], GL_ALPHA, buf.flipindex
+ , im->width >> im->cshift_x, im->height >> im->cshift_y
+ , im->stride[2], im->bpp, im->plane[2] );
+ }
+
+ VerifyGLState();
+
+ CalculateTextureSourceRects(source, 3);
+
+ glDisable(m_textureTarget);
+ return true;
+}
+
+void CLinuxRendererGL::DeleteYV12Texture(int index)
+{
+ YV12Image &im = m_buffers[index].image;
+ YUVFIELDS &fields = m_buffers[index].fields;
+ GLuint *pbo = m_buffers[index].pbo;
+
+ if( fields[FIELD_FULL][0].id == 0 ) return;
+
+ /* finish up all textures, and delete them */
+ g_graphicsContext.BeginPaint(); //FIXME
+ for(int f = 0;f<MAX_FIELDS;f++)
+ {
+ for(int p = 0;p<MAX_PLANES;p++)
+ {
+ if( fields[f][p].id )
+ {
+ if (glIsTexture(fields[f][p].id))
+ glDeleteTextures(1, &fields[f][p].id);
+ fields[f][p].id = 0;
+ }
+ }
+ }
+ g_graphicsContext.EndPaint();
+
+ for(int p = 0;p<MAX_PLANES;p++)
+ {
+ if (pbo[p])
+ {
+ if (im.plane[p])
+ {
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo[p]);
+ glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+ im.plane[p] = NULL;
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+ glDeleteBuffersARB(1, pbo + p);
+ pbo[p] = 0;
+ }
+ else
+ {
+ if (im.plane[p])
+ {
+ delete[] im.plane[p];
+ im.plane[p] = NULL;
+ }
+ }
+ }
+}
+
//********************************************************************************************************
// NV12 Texture loading, creation and deletion
//********************************************************************************************************
@@ -2291,384 +2179,6 @@ void CLinuxRendererGL::DeleteNV12Texture(int index)
}
}
-void CLinuxRendererGL::DeleteVDPAUTexture(int index)
-{
-#ifdef HAVE_LIBVDPAU
- YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0];
-
- SAFE_RELEASE(m_buffers[index].vdpau);
-
- plane.id = 0;
-#endif
-}
-
-bool CLinuxRendererGL::CreateVDPAUTexture(int index)
-{
-#ifdef HAVE_LIBVDPAU
- YV12Image &im = m_buffers[index].image;
- YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[FIELD_FULL][0];
-
- DeleteVDPAUTexture(index);
-
- memset(&im , 0, sizeof(im));
- memset(&fields, 0, sizeof(fields));
- im.height = m_sourceHeight;
- im.width = m_sourceWidth;
-
- plane.texwidth = im.width;
- plane.texheight = im.height;
-
- plane.pixpertex_x = 1;
- plane.pixpertex_y = 1;
-
- plane.id = 1;
-
-#endif
- return true;
-}
-
-bool CLinuxRendererGL::UploadVDPAUTexture(int index)
-{
-#ifdef HAVE_LIBVDPAU
- VDPAU::CVdpauRenderPicture *vdpau = m_buffers[index].vdpau;
-
- YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[FIELD_FULL][0];
-
- if (!vdpau || !vdpau->valid)
- {
- return false;
- }
-
- plane.id = vdpau->texture[0];
-
- // in stereoscopic mode sourceRect may only
- // be a part of the source video surface
- plane.rect = m_sourceRect;
-
- // clip rect
- if (vdpau->crop.x1 > plane.rect.x1)
- plane.rect.x1 = vdpau->crop.x1;
- if (vdpau->crop.x2 < plane.rect.x2)
- plane.rect.x2 = vdpau->crop.x2;
- if (vdpau->crop.y1 > plane.rect.y1)
- plane.rect.y1 = vdpau->crop.y1;
- if (vdpau->crop.y2 < plane.rect.y2)
- plane.rect.y2 = vdpau->crop.y2;
-
- plane.texheight = vdpau->texHeight;
- plane.texwidth = vdpau->texWidth;
-
- if (m_textureTarget == GL_TEXTURE_2D)
- {
- plane.rect.y1 /= plane.texheight;
- plane.rect.y2 /= plane.texheight;
- 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;
-
- 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)
-{
-#ifdef HAVE_LIBVA
- YUVPLANE &plane = m_buffers[index].fields[FIELD_FULL][0];
- SAFE_RELEASE(m_buffers[index].vaapi);
- plane.id = 0;
-#endif
-}
-
-bool CLinuxRendererGL::CreateVAAPITexture(int index)
-{
-#ifdef HAVE_LIBVA
- YV12Image &im = m_buffers[index].image;
- YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[0][0];
-
- DeleteVAAPITexture(index);
-
- memset(&im , 0, sizeof(im));
- memset(&fields, 0, sizeof(fields));
- im.height = m_sourceHeight;
- im.width = m_sourceWidth;
-
- plane.texwidth = im.width;
- plane.texheight = im.height;
-
- plane.pixpertex_x = 1;
- plane.pixpertex_y = 1;
-
- plane.id = 1;
-
-#endif
- return true;
-}
-
-bool CLinuxRendererGL::UploadVAAPITexture(int index)
-{
-#ifdef HAVE_LIBVA
- VAAPI::CVaapiRenderPicture *vaapi = m_buffers[index].vaapi;
-
- YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[FIELD_FULL][0];
-
- if (!vaapi || !vaapi->valid)
- {
- return false;
- }
-
- if (!vaapi->CopyGlx())
- return false;
-
- plane.id = vaapi->texture;
-
- // in stereoscopic mode sourceRect may only
- // be a part of the source video surface
- plane.rect = m_sourceRect;
-
- // clip rect
- if (vaapi->crop.x1 > plane.rect.x1)
- plane.rect.x1 = vaapi->crop.x1;
- if (vaapi->crop.x2 < plane.rect.x2)
- plane.rect.x2 = vaapi->crop.x2;
- if (vaapi->crop.y1 > plane.rect.y1)
- plane.rect.y1 = vaapi->crop.y1;
- if (vaapi->crop.y2 < plane.rect.y2)
- plane.rect.y2 = vaapi->crop.y2;
-
- plane.texheight = vaapi->texHeight;
- plane.texwidth = vaapi->texWidth;
-
- if (m_textureTarget == GL_TEXTURE_2D)
- {
- plane.rect.y1 /= plane.texheight;
- plane.rect.y2 /= plane.texheight;
- plane.rect.x1 /= plane.texwidth;
- plane.rect.x2 /= plane.texwidth;
- }
-
-#endif
- return true;
-}
-
-//********************************************************************************************************
-// CoreVideoRef Texture creation, deletion, copying + clearing
-//********************************************************************************************************
-bool CLinuxRendererGL::UploadCVRefTexture(int index)
-{
-#ifdef TARGET_DARWIN
- YUVBUFFER &buf = m_buffers[index];
- YUVFIELDS &fields = buf.fields;
-
- CVBufferRef cvBufferRef = m_buffers[index].cvBufferRef;
-
- glEnable(m_textureTarget);
-
- if (cvBufferRef && fields[m_currentField][0].flipindex != buf.flipindex)
- {
-
- // It is the fastest way to render a CVPixelBuffer backed
- // with an IOSurface as there is no CPU -> GPU upload.
- CGLContextObj cgl_ctx = (CGLContextObj)g_Windowing.GetCGLContextObj();
- IOSurfaceRef surface = CVPixelBufferGetIOSurface(cvBufferRef);
- GLsizei texWidth = IOSurfaceGetWidth(surface);
- GLsizei texHeight= IOSurfaceGetHeight(surface);
- OSType format_type = IOSurfaceGetPixelFormat(surface);
-
- glBindTexture(m_textureTarget, fields[FIELD_FULL][0].id);
-
- if (format_type == kCVPixelFormatType_422YpCbCr8)
- CGLTexImageIOSurface2D(cgl_ctx, m_textureTarget, GL_RGBA8,
- texWidth / 2, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
- else if (format_type == kCVPixelFormatType_32BGRA)
- CGLTexImageIOSurface2D(cgl_ctx, m_textureTarget, GL_RGBA8,
- texWidth, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
-
- glBindTexture(m_textureTarget, 0);
- fields[FIELD_FULL][0].flipindex = buf.flipindex;
-
- }
-
-
- CalculateTextureSourceRects(index, 3);
- glDisable(m_textureTarget);
-
-#endif
- return true;
-}
-
-void CLinuxRendererGL::DeleteCVRefTexture(int index)
-{
-#ifdef TARGET_DARWIN
- YUVPLANE &plane = m_buffers[index].fields[0][0];
-
- if (m_buffers[index].cvBufferRef)
- CVBufferRelease(m_buffers[index].cvBufferRef);
- m_buffers[index].cvBufferRef = NULL;
-
- if (plane.id && glIsTexture(plane.id))
- glDeleteTextures(1, &plane.id), plane.id = 0;
-#endif
-}
-
-bool CLinuxRendererGL::CreateCVRefTexture(int index)
-{
-#ifdef TARGET_DARWIN
- YV12Image &im = m_buffers[index].image;
- YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[0][0];
-
- DeleteCVRefTexture(index);
-
- memset(&im , 0, sizeof(im));
- memset(&fields, 0, sizeof(fields));
-
- im.bpp = 1;
- im.width = m_sourceWidth;
- im.height = m_sourceHeight;
- im.cshift_x = 0;
- im.cshift_y = 0;
-
- plane.pixpertex_x = 2;
- plane.pixpertex_y = 1;
- plane.texwidth = im.width / plane.pixpertex_x;
- plane.texheight = im.height / plane.pixpertex_y;
-
- if(m_renderMethod & RENDER_POT)
- {
- plane.texwidth = NP2(plane.texwidth);
- plane.texheight = NP2(plane.texheight);
- }
-
- glEnable(m_textureTarget);
- glGenTextures(1, &plane.id);
- glDisable(m_textureTarget);
-
-#endif
- return true;
-}
-
bool CLinuxRendererGL::UploadYUV422PackedTexture(int source)
{
YUVBUFFER& buf = m_buffers[source];
@@ -3240,12 +2750,6 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature)
{
if(feature == RENDERFEATURE_BRIGHTNESS)
{
- if ((m_renderMethod & RENDER_VDPAU) && !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE))
- return true;
-
- if (m_renderMethod & RENDER_VAAPI)
- return false;
-
return (m_renderMethod & RENDER_GLSL)
|| (m_renderMethod & RENDER_ARB)
|| ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE);
@@ -3253,12 +2757,6 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature)
if(feature == RENDERFEATURE_CONTRAST)
{
- if ((m_renderMethod & RENDER_VDPAU) && !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE))
- return true;
-
- if (m_renderMethod & RENDER_VAAPI)
- return false;
-
return (m_renderMethod & RENDER_GLSL)
|| (m_renderMethod & RENDER_ARB)
|| ((m_renderMethod & RENDER_SW) && glewIsSupported("GL_ARB_imaging") == GL_TRUE);
@@ -3268,21 +2766,16 @@ bool CLinuxRendererGL::Supports(ERENDERFEATURE feature)
return false;
if(feature == RENDERFEATURE_NOISE)
- {
- if(m_renderMethod & RENDER_VDPAU)
- return true;
- }
+ return false;
if(feature == RENDERFEATURE_SHARPNESS)
{
- if(m_renderMethod & RENDER_VDPAU)
- return true;
+ return false;
}
if (feature == RENDERFEATURE_NONLINSTRETCH)
{
- if (((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT)) ||
- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI))
+ if ((m_renderMethod & RENDER_GLSL) && !(m_renderMethod & RENDER_POT))
return true;
}
@@ -3322,34 +2815,6 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method)
if(method == VS_INTERLACEMETHOD_AUTO)
return true;
-
- if(m_renderMethod & RENDER_VDPAU ||
- m_format == RENDER_FMT_VDPAU_420)
- {
-#ifdef HAVE_LIBVDPAU
- VDPAU::CVdpauRenderPicture *vdpauPic = m_buffers[m_iYV12RenderBuffer].vdpau;
- if(vdpauPic && vdpauPic->vdpau)
- return vdpauPic->vdpau->Supports(method);
-#endif
- return false;
- }
-
- if(m_format == RENDER_FMT_VAAPI ||
- m_format == RENDER_FMT_VAAPINV12)
- {
-#ifdef HAVE_LIBVA
- VAAPI::CVaapiRenderPicture *vaapiPic = m_buffers[m_iYV12RenderBuffer].vaapi;
- if(vaapiPic && vaapiPic->vaapi)
- return vaapiPic->vaapi->Supports(method);
-#endif
- return false;
- }
-
-#ifdef TARGET_DARWIN_IOS
- // iOS does not have the ponies for YADIF
- if(method == VS_INTERLACEMETHOD_DEINTERLACE)
- return false;
-#endif
if(method == VS_INTERLACEMETHOD_DEINTERLACE
|| method == VS_INTERLACEMETHOD_DEINTERLACE_HALF
@@ -3392,8 +2857,7 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method)
if (scaleX < minScale && scaleY < minScale)
return false;
- if ((glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL)) ||
- (m_renderMethod & RENDER_VDPAU) || (m_renderMethod & RENDER_VAAPI))
+ if (glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL))
{
// spline36 and lanczos3 are only allowed through advancedsettings.xml
if(method != VS_SCALINGMETHOD_SPLINE36
@@ -3409,12 +2873,6 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method)
EINTERLACEMETHOD CLinuxRendererGL::AutoInterlaceMethod()
{
- if(m_renderMethod & RENDER_CVREF)
- return VS_INTERLACEMETHOD_NONE;
-
- if(m_renderMethod & RENDER_VDPAU)
- return VS_INTERLACEMETHOD_NONE;
-
if(Supports(VS_INTERLACEMETHOD_RENDER_BOB))
return VS_INTERLACEMETHOD_RENDER_BOB;
@@ -3460,54 +2918,8 @@ CRenderInfo CLinuxRendererGL::GetRenderInfo()
CRenderInfo info;
info.formats = m_formats;
info.max_buffer_size = NUM_BUFFERS;
- if(m_format == RENDER_FMT_CVBREF)
- info.optimal_buffer_size = 2;
- else if (m_format == RENDER_FMT_VAAPI ||
- m_format == RENDER_FMT_VAAPINV12 ||
- m_format == RENDER_FMT_VDPAU ||
- m_format == RENDER_FMT_VDPAU_420)
- info.optimal_buffer_size = 5;
- else
- info.optimal_buffer_size = 3;
+ info.optimal_buffer_size = 3;
return info;
}
-void CLinuxRendererGL::AddVideoPictureHW(DVDVideoPicture &picture, int index)
-{
- if (picture.format == RENDER_FMT_VDPAU ||
- picture.format == RENDER_FMT_VDPAU_420)
- {
-#ifdef HAVE_LIBVDPAU
- VDPAU::CVdpauRenderPicture *vdpau = picture.vdpau;
- YUVBUFFER &buf = m_buffers[index];
- VDPAU::CVdpauRenderPicture *pic = vdpau->Acquire();
- SAFE_RELEASE(buf.vdpau);
- buf.vdpau = pic;
-#endif
- }
- else if (picture.format == RENDER_FMT_VAAPI ||
- picture.format == RENDER_FMT_VAAPINV12)
- {
-#ifdef HAVE_LIBVA
- VAAPI::CVaapiRenderPicture *vaapi = picture.vaapi;
- YUVBUFFER &buf = m_buffers[index];
- VAAPI::CVaapiRenderPicture *pic = vaapi->Acquire();
- SAFE_RELEASE(buf.vaapi);
- buf.vaapi = pic;
-#endif
- }
- else if (picture.format == RENDER_FMT_CVBREF)
- {
-#ifdef TARGET_DARWIN
- struct __CVBuffer *cvBufferRef = picture.cvBufferRef;
- YUVBUFFER &buf = m_buffers[index];
- if (buf.cvBufferRef)
- CVBufferRelease(buf.cvBufferRef);
- buf.cvBufferRef = cvBufferRef;
- // retain another reference, this way dvdplayer and renderer can issue releases.
- CVBufferRetain(buf.cvBufferRef);
-#endif
- }
-}
-
#endif
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h
index 2ae7ad6024..249b82da7a 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h
@@ -40,8 +40,6 @@ class CRenderCapture;
class CBaseTexture;
namespace Shaders { class BaseYUV2RGBShader; }
namespace Shaders { class BaseVideoFilterShader; }
-namespace VAAPI { class CVaapiRenderPicture; }
-namespace VDPAU { class CVdpauRenderPicture; }
#undef ALIGN
#define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1))
@@ -122,13 +120,11 @@ public:
virtual bool IsConfigured() { return m_bConfigured; }
virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
virtual void ReleaseImage(int source, bool preserve = false);
- virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
virtual void FlipPage(int source);
- virtual unsigned int PreInit();
+ virtual void PreInit();
virtual void UnInit();
virtual void Reset(); /* resets renderer after seek for example */
virtual void Flush();
- virtual void ReleaseBuffer(int idx);
virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; }
virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
virtual void Update();
@@ -146,8 +142,8 @@ public:
protected:
virtual void Render(DWORD flags, int renderBuffer);
- void ClearBackBuffer();
- void DrawBlackBars();
+ void ClearBackBuffer();
+ void DrawBlackBars();
bool ValidateRenderer();
int NextYV12Texture();
@@ -157,9 +153,9 @@ protected:
void UpdateVideoFilter();
// textures
- bool (CLinuxRendererGL::*m_textureUpload)(int index);
- void (CLinuxRendererGL::*m_textureDelete)(int index);
- bool (CLinuxRendererGL::*m_textureCreate)(int index);
+ virtual bool UploadTexture(int index);
+ virtual void DeleteTexture(int index);
+ virtual bool CreateTexture(int index);
bool UploadYV12Texture(int index);
void DeleteYV12Texture(int index);
@@ -168,22 +164,6 @@ protected:
bool UploadNV12Texture(int index);
void DeleteNV12Texture(int index);
bool CreateNV12Texture(int index);
-
- bool UploadVDPAUTexture(int index);
- 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);
-
- bool UploadCVRefTexture(int index);
- void DeleteCVRefTexture(int index);
- bool CreateCVRefTexture(int index);
bool UploadYUV422PackedTexture(int index);
void DeleteYUV422PackedTexture(int index);
@@ -204,6 +184,10 @@ protected:
void RenderRGB(int renderBuffer, int field); // render using vdpau/vaapi hardware
void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware
+ // hooks for HwDec Renderered
+ virtual bool LoadShadersHook() { return false; };
+ virtual bool RenderHook(int idx) { return false; };
+
struct
{
CFrameBufferObject fbo;
@@ -260,15 +244,7 @@ protected:
unsigned flipindex; /* used to decide if this has been uploaded */
GLuint pbo[MAX_PLANES];
-#ifdef HAVE_LIBVDPAU
- VDPAU::CVdpauRenderPicture *vdpau;
-#endif
-#ifdef HAVE_LIBVA
- VAAPI::CVaapiRenderPicture *vaapi;
-#endif
-#ifdef TARGET_DARWIN_OSX
- struct __CVBuffer *cvBufferRef;
-#endif
+ void *hwDec;
};
typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS];
diff --git a/xbmc/cores/VideoRenderers/Makefile.in b/xbmc/cores/VideoRenderers/Makefile.in
index 7fcc322618..d964285020 100644
--- a/xbmc/cores/VideoRenderers/Makefile.in
+++ b/xbmc/cores/VideoRenderers/Makefile.in
@@ -20,10 +20,6 @@ SRCS += LinuxRendererGLES.cpp
SRCS += OverlayRendererGL.cpp
endif
-ifeq (@USE_MMAL@,1)
-SRCS += MMALRenderer.cpp
-endif
-
LIB = VideoRenderer.a
include @abs_top_srcdir@/Makefile.include
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
index 8146a727b1..d9949d2ed0 100644
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -19,9 +19,6 @@
*/
#include "system.h"
-#if defined(HAS_GL)
- #include "system_gl.h"
-#endif
#include "RenderManager.h"
#include "RenderFlags.h"
#include "threads/CriticalSection.h"
@@ -40,7 +37,12 @@
#include "cores/DataCacheCore.h"
#if defined(HAS_GL)
- #include "LinuxRendererGL.h"
+#include "LinuxRendererGL.h"
+#include "HwDecRender/RendererVAAPI.h"
+#include "HwDecRender/RendererVDPAU.h"
+#if defined(TARGET_DARWIN_OSX)
+#include "HwDecRender/RendererVDA.h"
+#endif
#elif defined(HAS_MMAL)
#include "MMALRenderer.h"
#elif HAS_GLES == 2
@@ -58,10 +60,6 @@
#include "../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
#include "../dvdplayer/DVDCodecs/DVDCodecUtils.h"
-#ifdef HAVE_LIBVA
- #include "../dvdplayer/DVDCodecs/Video/VAAPI.h"
-#endif
-
using namespace KODI::MESSAGING;
#define MAXPRESENTDELAY 0.500
@@ -104,10 +102,37 @@ static void requeue(std::deque<int> &trg, std::deque<int> &src)
src.pop_front();
}
+static std::string GetRenderFormatName(ERenderFormat format)
+{
+ switch(format)
+ {
+ case RENDER_FMT_YUV420P: return "YV12";
+ case RENDER_FMT_YUV420P16: return "YV12P16";
+ case RENDER_FMT_YUV420P10: return "YV12P10";
+ case RENDER_FMT_NV12: return "NV12";
+ 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_VAAPINV12: return "VAAPI_NV12";
+ case RENDER_FMT_OMXEGL: return "OMXEGL";
+ case RENDER_FMT_CVBREF: return "BGRA";
+ case RENDER_FMT_EGLIMG: return "EGLIMG";
+ case RENDER_FMT_BYPASS: return "BYPASS";
+ case RENDER_FMT_MEDIACODEC:return "MEDIACODEC";
+ case RENDER_FMT_IMXMAP: return "IMXMAP";
+ case RENDER_FMT_MMAL: return "MMAL";
+ case RENDER_FMT_NONE: return "NONE";
+ }
+ return "UNKNOWN";
+}
+
CXBMCRenderManager::CXBMCRenderManager()
{
m_pRenderer = NULL;
- m_bIsStarted = false;
+ m_renderState = STATE_UNCONFIGURED;
m_presentstep = PRESENT_IDLE;
m_rendermethod = 0;
@@ -128,7 +153,6 @@ CXBMCRenderManager::CXBMCRenderManager()
CXBMCRenderManager::~CXBMCRenderManager()
{
delete m_pRenderer;
- m_pRenderer = NULL;
}
void CXBMCRenderManager::GetVideoRect(CRect &source, CRect &dest, CRect &view)
@@ -214,14 +238,11 @@ void CXBMCRenderManager::WaitPresentTime(double presenttime)
avgerror /= ERRORBUFFSIZE;
-
//we change the clock speed slightly
//to make every frame's presenttime end up in the middle of two vblanks
//integral correction, clamp to -0.5:0.5 range
m_presentcorr = std::max(std::min(m_presentcorr + avgerror * 0.01, 0.1), -0.1);
g_VideoReferenceClock.SetFineAdjust(1.0 - avgerror * 0.01 - m_presentcorr * 0.01);
-
- //printf("%f %f % 2.0f%% % f % f\n", presenttime, clock, m_presentcorr * 100, error, error_org);
}
std::string CXBMCRenderManager::GetVSyncState()
@@ -238,56 +259,118 @@ std::string CXBMCRenderManager::GetVSyncState()
return state;
}
-bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, int buffers)
+bool CXBMCRenderManager::Configure(DVDVideoPicture& picture, float fps, unsigned flags, unsigned int orientation, int buffers)
{
- CSingleLock lock2(m_presentlock);
+ // check if something has changed
+ {
+ float config_framerate = fps;
+ float render_framerate = g_graphicsContext.GetFPS();
+ if (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) == ADJUST_REFRESHRATE_OFF)
+ render_framerate = config_framerate;
+ bool changerefresh = (fps != 0) &&
+ (m_fps == 0.0 || fmod(m_fps, fps) != 0.0) &&
+ (render_framerate != config_framerate);
+
+ CSharedLock lock(m_sharedSection);
+ if (m_width == picture.iWidth &&
+ m_height == picture.iHeight &&
+ m_dwidth == picture.iDisplayWidth &&
+ m_dheight == picture.iDisplayHeight &&
+ !changerefresh &&
+ (m_flags & ~CONF_FLAGS_FULLSCREEN) == (flags & ~CONF_FLAGS_FULLSCREEN) &&
+ m_format == picture.format &&
+ m_extended_format == picture.extended_format &&
+ m_orientation == orientation &&
+ m_NumberBuffers == buffers &&
+ m_pRenderer != NULL)
+ return true;
+ }
+
+ std::string formatstr = GetRenderFormatName(picture.format);
+ CLog::Log(LOGDEBUG, "CXBMCRenderManager::Configure - change configuration. %dx%d. display: %dx%d. framerate: %4.2f. format: %s", picture.iWidth, picture.iHeight, picture.iDisplayWidth, picture.iDisplayHeight, fps, formatstr.c_str());
- /* make sure any queued frame was fully presented */
- XbmcThreads::EndTime endtime(5000);
- while(m_presentstep != PRESENT_IDLE && m_presentstep != PRESENT_READY)
+ // make sure any queued frame was fully presented
{
- if(endtime.IsTimePast())
+ CSingleLock lock(m_presentlock);
+ XbmcThreads::EndTime endtime(5000);
+ while(m_presentstep != PRESENT_IDLE && m_presentstep != PRESENT_READY)
{
- CLog::Log(LOGWARNING, "CRenderManager::Configure - timeout waiting for state");
- return false;
+ if(endtime.IsTimePast())
+ {
+ CLog::Log(LOGWARNING, "CRenderManager::Configure - timeout waiting for state");
+ return false;
+ }
+ m_presentevent.wait(lock, endtime.MillisLeft());
}
- m_presentevent.wait(lock2, endtime.MillisLeft());
- };
- lock2.Leave();
+ }
- CExclusiveLock lock(m_sharedSection);
- if(!m_pRenderer)
{
- CLog::Log(LOGERROR, "%s called without a valid Renderer object", __FUNCTION__);
+ CExclusiveLock lock(m_sharedSection);
+ m_width = picture.iWidth;
+ m_height = picture.iHeight,
+ m_dwidth = picture.iDisplayWidth;
+ m_dheight = picture.iDisplayHeight;
+ m_fps = fps;
+ m_flags = flags;
+ m_format = picture.format;
+ m_extended_format = picture.extended_format;
+ m_orientation = orientation;
+ m_NumberBuffers = buffers;
+ m_renderState = STATE_CONFIGURING;
+ m_stateEvent.Reset();
+ }
+
+ if (!m_stateEvent.WaitMSec(1000))
+ {
+ CLog::Log(LOGWARNING, "CRenderManager::Configure - timeout waiting for configure");
+ return false;
+ }
+
+ CSharedLock lock(m_sharedSection);
+ if (m_renderState != STATE_CONFIGURED)
+ {
+ CLog::Log(LOGWARNING, "CRenderManager::Configure - failed to configure");
return false;
}
+ return true;
+}
+
+bool CXBMCRenderManager::Configure()
+{
+ CExclusiveLock lock(m_sharedSection);
+ CSingleLock lock2(m_presentlock);
- bool result = m_pRenderer->Configure(width, height, d_width, d_height, fps, flags, format, extended_format, orientation);
- if(result)
+ if (m_pRenderer && m_pRenderer->GetRenderFormat() != m_format)
{
- if( flags & CONF_FLAGS_FULLSCREEN )
- {
- lock.Leave();
- CApplicationMessenger::GetInstance().PostMsg(TMSG_SWITCHTOFULLSCREEN);
- lock.Enter();
- }
- lock2.Enter();
- m_format = format;
+ DeleteRenderer();
+ }
+
+ if(!m_pRenderer)
+ {
+ CreateRenderer();
+ if (!m_pRenderer)
+ return false;
+ else
+ m_pRenderer->PreInit();
+ }
+ bool result = m_pRenderer->Configure(m_width, m_height, m_dwidth, m_dheight, m_fps, m_flags, m_format, m_extended_format, m_orientation);
+ if (result)
+ {
CRenderInfo info = m_pRenderer->GetRenderInfo();
int renderbuffers = info.optimal_buffer_size;
m_QueueSize = renderbuffers;
- if (buffers > 0)
- m_QueueSize = std::min(buffers, renderbuffers);
+ if (m_NumberBuffers > 0)
+ m_QueueSize = std::min(m_NumberBuffers, renderbuffers);
m_QueueSize = std::min(m_QueueSize, (int)info.max_buffer_size);
m_QueueSize = std::min(m_QueueSize, NUM_BUFFERS);
if(m_QueueSize < 2)
{
m_QueueSize = 2;
- CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, renderbuffers, buffers);
+ CLog::Log(LOGWARNING, "CXBMCRenderManager::Configure - queue size too small (%d, %d, %d)", m_QueueSize, renderbuffers, m_NumberBuffers);
}
m_pRenderer->SetBufferSize(m_QueueSize);
@@ -300,7 +383,6 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
for (int i=1; i < m_QueueSize; i++)
m_free.push_back(i);
- m_bIsStarted = true;
m_bRenderGUI = true;
m_waitForBufferCount = 0;
m_bReconfigured = true;
@@ -310,17 +392,24 @@ bool CXBMCRenderManager::Configure(unsigned int width, unsigned int height, unsi
m_presentevent.notifyAll();
m_renderedOverlay = false;
+ m_renderState = STATE_CONFIGURED;
+
CLog::Log(LOGDEBUG, "CXBMCRenderManager::Configure - %d", m_QueueSize);
}
+ else
+ m_renderState = STATE_UNCONFIGURED;
+ m_stateEvent.Set();
return result;
}
bool CXBMCRenderManager::IsConfigured() const
{
- if (!m_pRenderer)
+ CSharedLock lock(m_sharedSection);
+ if (m_renderState == STATE_CONFIGURED)
+ return true;
+ else
return false;
- return m_pRenderer->IsConfigured();
}
void CXBMCRenderManager::Update()
@@ -350,54 +439,66 @@ bool CXBMCRenderManager::HasFrame()
void CXBMCRenderManager::FrameMove()
{
- { CSharedLock lock(m_sharedSection);
- CSingleLock lock2(m_presentlock);
+ CSharedLock lock(m_sharedSection);
- if (!m_pRenderer)
+ if (m_renderState == STATE_UNCONFIGURED)
+ return;
+ else if (m_renderState == STATE_CONFIGURING)
+ {
+ lock.Leave();
+ if (!Configure())
return;
- if (m_presentstep == PRESENT_FRAME2)
+ if (m_flags & CONF_FLAGS_FULLSCREEN)
{
- if(!m_queued.empty())
- {
- double timestamp = GetPresentTime();
- SPresent& m = m_Queue[m_presentsource];
- SPresent& q = m_Queue[m_queued.front()];
- if(timestamp > m.timestamp + (q.timestamp - m.timestamp) * 0.5)
- {
- m_presentstep = PRESENT_READY;
- m_presentevent.notifyAll();
- }
- }
+ CApplicationMessenger::GetInstance().PostMsg(TMSG_SWITCHTOFULLSCREEN);
}
+ lock.Enter();
+ }
- if (m_presentstep == PRESENT_READY)
- PrepareNextRender();
-
- if(m_presentstep == PRESENT_FLIP)
- {
- m_pRenderer->FlipPage(m_presentsource);
- m_presentstep = PRESENT_FRAME;
- m_presentevent.notifyAll();
- }
+ CSingleLock lock2(m_presentlock);
- /* release all previous */
- for(std::deque<int>::iterator it = m_discard.begin(); it != m_discard.end(); )
+ if (m_presentstep == PRESENT_FRAME2)
+ {
+ if (!m_queued.empty())
{
- // renderer may want to keep the frame for postprocessing
- if (!m_pRenderer->NeedBufferForRef(*it) || !m_bRenderGUI)
+ double timestamp = GetPresentTime();
+ SPresent& m = m_Queue[m_presentsource];
+ SPresent& q = m_Queue[m_queued.front()];
+ if(timestamp > m.timestamp + (q.timestamp - m.timestamp) * 0.5)
{
- m_pRenderer->ReleaseBuffer(*it);
- m_overlays.Release(*it);
- m_free.push_back(*it);
- it = m_discard.erase(it);
+ m_presentstep = PRESENT_READY;
+ m_presentevent.notifyAll();
}
- else
- ++it;
}
+ }
- m_bRenderGUI = true;
+ if (m_presentstep == PRESENT_READY)
+ PrepareNextRender();
+
+ if(m_presentstep == PRESENT_FLIP)
+ {
+ m_pRenderer->FlipPage(m_presentsource);
+ m_presentstep = PRESENT_FRAME;
+ m_presentevent.notifyAll();
}
+
+ /* release all previous */
+ for (std::deque<int>::iterator it = m_discard.begin(); it != m_discard.end(); )
+ {
+ // renderer may want to keep the frame for postprocessing
+ if (!m_pRenderer->NeedBufferForRef(*it) || !m_bRenderGUI)
+ {
+ m_pRenderer->ReleaseBuffer(*it);
+ m_overlays.Release(*it);
+ m_free.push_back(*it);
+ it = m_discard.erase(it);
+ }
+ else
+ ++it;
+ }
+
+ m_bRenderGUI = true;
}
void CXBMCRenderManager::FrameFinish()
@@ -437,8 +538,14 @@ void CXBMCRenderManager::FrameFinish()
}
}
-unsigned int CXBMCRenderManager::PreInit()
+void CXBMCRenderManager::PreInit()
{
+ if (!g_application.IsCurrentThread())
+ {
+ CLog::Log(LOGERROR, "CXBMCRenderManager::UnInit - not called from render thread");
+ return;
+ }
+
CRetakeLock<CExclusiveLock> lock(m_sharedSection);
m_presentcorr = 0.0;
@@ -446,44 +553,35 @@ unsigned int CXBMCRenderManager::PreInit()
m_errorindex = 0;
memset(m_errorbuff, 0, sizeof(m_errorbuff));
- m_bIsStarted = false;
if (!m_pRenderer)
{
-#if defined(HAS_GL)
- m_pRenderer = new CLinuxRendererGL();
-#elif defined(HAS_MMAL)
- m_pRenderer = new CMMALRenderer();
-#elif HAS_GLES == 2
- m_pRenderer = new CLinuxRendererGLES();
-#elif defined(HAS_DX)
- m_pRenderer = new CWinRenderer();
-#elif defined(HAS_SDL)
- m_pRenderer = new CLinuxRenderer();
-#endif
+ m_format = RENDER_FMT_NONE;
+ CreateRenderer();
}
UpdateDisplayLatency();
m_QueueSize = 2;
m_QueueSkip = 0;
-
- return m_pRenderer->PreInit();
}
void CXBMCRenderManager::UnInit()
{
- CRetakeLock<CExclusiveLock> lock(m_sharedSection);
+ if (!g_application.IsCurrentThread())
+ {
+ CLog::Log(LOGERROR, "CXBMCRenderManager::UnInit - not called from render thread");
+ return;
+ }
- m_bIsStarted = false;
+ CRetakeLock<CExclusiveLock> lock(m_sharedSection);
m_overlays.Flush();
g_fontManager.Unload("__subtitle__");
g_fontManager.Unload("__subtitleborder__");
- // free renderer resources.
- // TODO: we may also want to release the renderer here.
- if (m_pRenderer)
- m_pRenderer->UnInit();
+ DeleteRenderer();
+
+ m_renderState = STATE_UNCONFIGURED;
}
bool CXBMCRenderManager::Flush()
@@ -496,9 +594,13 @@ bool CXBMCRenderManager::Flush()
CLog::Log(LOGDEBUG, "%s - flushing renderer", __FUNCTION__);
CRetakeLock<CExclusiveLock> lock(m_sharedSection);
- m_pRenderer->Flush();
- m_overlays.Flush();
- m_flushEvent.Set();
+
+ if (m_pRenderer)
+ {
+ m_pRenderer->Flush();
+ m_overlays.Flush();
+ m_flushEvent.Set();
+ }
}
else
{
@@ -513,6 +615,7 @@ bool CXBMCRenderManager::Flush()
return true;
}
+ CSingleLock lock(m_presentlock);
m_queued.clear();
m_discard.clear();
m_free.clear();
@@ -522,6 +625,56 @@ bool CXBMCRenderManager::Flush()
return true;
}
+void CXBMCRenderManager::CreateRenderer()
+{
+ if (!m_pRenderer)
+ {
+#if defined(HAS_MMAL)
+ m_pRenderer = new CMMALRenderer();
+#elif HAS_GLES == 2
+ m_pRenderer = new CLinuxRendererGLES();
+#elif defined(HAS_DX)
+ m_pRenderer = new CWinRenderer();
+#endif
+#if defined(HAS_GL)
+ if (m_format == RENDER_FMT_VAAPI || m_format == RENDER_FMT_VAAPINV12)
+ {
+#if defined(HAVE_LIBVA)
+ m_pRenderer = new CRendererVAAPI;
+#endif
+ }
+ else if (m_format == RENDER_FMT_VDPAU || m_format == RENDER_FMT_VDPAU_420)
+ {
+#if defined(HAVE_LIBVDPAU)
+ m_pRenderer = new CRendererVDPAU;
+#endif
+ }
+ else if (m_format == RENDER_FMT_CVBREF)
+ {
+#if defined(TARGET_DARWIN_OSX)
+ m_pRenderer = new CRendererVDA;
+#endif
+ }
+ else if (m_format != RENDER_FMT_NONE)
+ {
+ m_pRenderer = new CLinuxRendererGL;
+ }
+#endif
+ if (m_pRenderer)
+ m_pRenderer->PreInit();
+ }
+}
+
+void CXBMCRenderManager::DeleteRenderer()
+{
+ CLog::Log(LOGDEBUG, "%s - deleting renderer", __FUNCTION__);
+
+ if (m_pRenderer)
+ {
+ delete m_pRenderer;
+ m_pRenderer = NULL;
+ }
+}
void CXBMCRenderManager::SetupScreenshot()
{
@@ -756,13 +909,6 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L
}
}
-void CXBMCRenderManager::Reset()
-{
- CSharedLock lock(m_sharedSection);
- if (m_pRenderer)
- m_pRenderer->Reset();
-}
-
RESOLUTION CXBMCRenderManager::GetResolution()
{
CSharedLock lock(m_sharedSection);
@@ -803,6 +949,9 @@ void CXBMCRenderManager::Render(bool clear, DWORD flags, DWORD alpha, bool gui)
{
CSharedLock lock(m_sharedSection);
+ if (m_renderState != STATE_CONFIGURED)
+ return;
+
if (!gui && m_pRenderer->IsGuiLayer())
return;
@@ -911,10 +1060,6 @@ void CXBMCRenderManager::PresentBlend(bool clear, DWORD flags, DWORD alpha)
void CXBMCRenderManager::Recover()
{
-#if defined(HAS_GL) && !defined(TARGET_DARWIN)
- glFlush(); // attempt to have gpu done with pixmap and vdpau
-#endif
-
UpdateDisplayLatency();
}
@@ -949,8 +1094,8 @@ CRenderInfo CXBMCRenderManager::GetRenderInfo()
CRenderInfo info;
if (!m_pRenderer)
{
- CLog::Log(LOGERROR, "%s - renderer is NULL", __FUNCTION__);
- return CRenderInfo();
+ info.max_buffer_size = NUM_BUFFERS;
+ return info;;
}
return m_pRenderer->GetRenderInfo();
}
@@ -997,16 +1142,12 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
|| pic.format == RENDER_FMT_OMXEGL
|| pic.format == RENDER_FMT_CVBREF
|| pic.format == RENDER_FMT_VAAPI
+ || pic.format == RENDER_FMT_VAAPINV12
|| pic.format == RENDER_FMT_EGLIMG
|| pic.format == RENDER_FMT_MEDIACODEC
|| pic.format == RENDER_FMT_IMXMAP
|| pic.format == RENDER_FMT_MMAL)
m_pRenderer->AddVideoPictureHW(pic, index);
- else if(pic.format == RENDER_FMT_VAAPINV12)
- {
- m_pRenderer->AddVideoPictureHW(pic, index);
- CDVDCodecUtils::CopyNV12Picture(&image, &pic.vaapi->DVDPic);
- }
m_pRenderer->ReleaseImage(index, false);
@@ -1071,7 +1212,7 @@ EINTERLACEMETHOD CXBMCRenderManager::AutoInterlaceMethodInternal(EINTERLACEMETHO
int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout)
{
- CSingleLock lock2(m_presentlock);
+ CSingleLock lock(m_presentlock);
// check if gui is active and discard buffer if not
// this keeps videoplayer going
@@ -1092,7 +1233,7 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout)
if (sleeptime < 0)
sleeptime = 0;
sleeptime = std::min(sleeptime, 20);
- m_presentevent.wait(lock2, sleeptime);
+ m_presentevent.wait(lock, sleeptime);
DiscardBuffer();
return 0;
}
@@ -1100,7 +1241,7 @@ int CXBMCRenderManager::WaitForBuffer(volatile bool& bStop, int timeout)
XbmcThreads::EndTime endtime(timeout);
while(m_free.empty())
{
- m_presentevent.wait(lock2, std::min(50, timeout));
+ m_presentevent.wait(lock, std::min(50, timeout));
if(endtime.IsTimePast() || bStop)
{
if (timeout != 0 && !bStop)
diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h
index 5d0c3a4c72..e0ec3e6fbf 100644
--- a/xbmc/cores/VideoRenderers/RenderManager.h
+++ b/xbmc/cores/VideoRenderers/RenderManager.h
@@ -53,7 +53,7 @@ public:
CXBMCRenderManager();
~CXBMCRenderManager();
- // Functions called from the GUI
+ // Functions called from render thread
void GetVideoRect(CRect &source, CRect &dest, CRect &view);
float GetAspectRatio();
void Update();
@@ -64,31 +64,43 @@ public:
void Render(bool clear, DWORD flags = 0, DWORD alpha = 255, bool gui = true);
bool IsGuiLayer();
bool IsVideoLayer();
- void SetupScreenshot();
+ RESOLUTION GetResolution();
+ void UpdateResolution();
+ void SetViewMode(int iViewMode);
+ void Recover(); // called after resolution switch if something special is needed
+ void PreInit();
+ void UnInit();
+ bool Flush();
+ bool IsConfigured() const;
+ void SetupScreenshot();
CRenderCapture* AllocRenderCapture();
void ReleaseRenderCapture(CRenderCapture* capture);
void Capture(CRenderCapture *capture, unsigned int width, unsigned int height, int flags);
void ManageCaptures();
- void SetViewMode(int iViewMode);
+ // Functions called from GUI
+ bool Supports(ERENDERFEATURE feature);
+ bool Supports(EDEINTERLACEMODE method);
+ bool Supports(EINTERLACEMETHOD method);
+ bool Supports(ESCALINGMETHOD method);
+ EINTERLACEMETHOD AutoInterlaceMethod(EINTERLACEMETHOD mInt);
+
+ static float GetMaximumFPS();
+ double GetDisplayLatency() { return m_displayLatency; }
+ int GetSkippedFrames() { return m_QueueSkip; }
+ std::string GetVSyncState();
// Functions called from mplayer
/**
* Called by video player to configure renderer
- * @param width width of decoded frame
- * @param height height of decoded frame
- * @param d_width displayed width of frame (aspect ratio)
- * @param d_height displayed height of frame
+ * @param picture
* @param fps frames per second of video
* @param flags see RenderFlags.h
- * @param format see RenderFormats.h
- * @param extended_format used by DXVA
* @param orientation
* @param numbers of kept buffer references
*/
- bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation, int buffers = 0);
- bool IsConfigured() const;
+ bool Configure(DVDVideoPicture& picture, float fps, unsigned flags, unsigned int orientation, int buffers = 0);
int AddVideoPicture(DVDVideoPicture& picture);
@@ -107,9 +119,6 @@ public:
* @param sync signals frame, top, or bottom field
*/
void FlipPage(volatile bool& bStop, double timestamp = 0.0, double pts = 0.0, int source = -1, EFIELDSYNC sync = FS_NONE);
- unsigned int PreInit();
- void UnInit();
- bool Flush();
void AddOverlay(CDVDOverlay* o, double pts)
{
@@ -127,41 +136,9 @@ public:
m_overlays.AddCleanup(o);
}
- void Reset();
-
- RESOLUTION GetResolution();
-
- static float GetMaximumFPS();
- inline bool IsStarted() { return m_bIsStarted;}
- double GetDisplayLatency() { return m_displayLatency; }
- int GetSkippedFrames() { return m_QueueSkip; }
-
- bool Supports(ERENDERFEATURE feature);
- bool Supports(EDEINTERLACEMODE method);
- bool Supports(EINTERLACEMETHOD method);
- bool Supports(ESCALINGMETHOD method);
-
- EINTERLACEMETHOD AutoInterlaceMethod(EINTERLACEMETHOD mInt);
-
- static double GetPresentTime();
- void WaitPresentTime(double presenttime);
-
- std::string GetVSyncState();
-
- void UpdateResolution();
-
- CBaseRenderer *m_pRenderer;
-
// Get renderer info, can be called before configure
CRenderInfo GetRenderInfo();
- void Recover(); // called after resolution switch if something special is needed
-
- CSharedSection& GetSection() { return m_sharedSection; };
-
- void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn);
- void RegisterRenderFeaturesCallBack(const void *ctx, RenderFeaturesCallBackFn fn);
-
/**
* If player uses buffering it has to wait for a buffer before it calls
* AddVideoPicture and AddOverlay. It waits for max 50 ms before it returns -1
@@ -183,6 +160,10 @@ public:
*/
void DiscardBuffer();
+ // TODO: trash those
+ void RegisterRenderUpdateCallBack(const void *ctx, RenderUpdateCallBackFn fn);
+ void RegisterRenderFeaturesCallBack(const void *ctx, RenderFeaturesCallBackFn fn);
+
protected:
void PresentSingle(bool clear, DWORD flags, DWORD alpha);
@@ -190,17 +171,22 @@ protected:
void PresentBlend(bool clear, DWORD flags, DWORD alpha);
void PrepareNextRender();
+ static double GetPresentTime();
+ void WaitPresentTime(double presenttime);
EINTERLACEMETHOD AutoInterlaceMethodInternal(EINTERLACEMETHOD mInt);
+ bool Configure();
+ void CreateRenderer();
+ void DeleteRenderer();
+ CBaseRenderer *m_pRenderer;
+ OVERLAY::CRenderer m_overlays;
CSharedSection m_sharedSection;
-
- bool m_bIsStarted;
bool m_bReconfigured;
bool m_bRenderGUI;
int m_waitForBufferCount;
-
int m_rendermethod;
+ bool m_renderedOverlay;
enum EPRESENTSTEP
{
@@ -219,6 +205,15 @@ protected:
PRESENT_METHOD_BOB,
};
+ enum ERENDERSTATE
+ {
+ STATE_UNCONFIGURED = 0,
+ STATE_CONFIGURING,
+ STATE_CONFIGURED,
+ };
+ ERENDERSTATE m_renderState;
+ CEvent m_stateEvent;
+
double m_displayLatency;
void UpdateDisplayLatency();
@@ -238,6 +233,12 @@ protected:
std::deque<int> m_discard;
ERenderFormat m_format;
+ unsigned int m_width, m_height, m_dwidth, m_dheight;
+ unsigned int m_flags;
+ float m_fps;
+ unsigned int m_extended_format;
+ unsigned int m_orientation;
+ int m_NumberBuffers;
double m_sleeptime;
double m_presentpts;
@@ -252,9 +253,6 @@ protected:
CEvent m_flushEvent;
double m_clock_framefinish;
- OVERLAY::CRenderer m_overlays;
- bool m_renderedOverlay;
-
void RenderCapture(CRenderCapture* capture);
void RemoveCapture(CRenderCapture* capture);
CCriticalSection m_captCritSect;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
index f8050b646a..24ccfd03ff 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
@@ -1098,7 +1098,6 @@ bool CDecoder::ConfigVAAPI()
return false;
}
-
m_hwContext.config_id = m_vaapiConfig.configId;
m_hwContext.context_id = m_vaapiConfig.contextId;
m_hwContext.display = m_vaapiConfig.dpy;
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
index 379c54153c..4ab81af84c 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -152,7 +152,6 @@ CDVDPlayerVideo::CDVDPlayerVideo( CDVDClock* pClock
m_iFrameRateLength = 0;
m_bFpsInvalid = false;
m_bAllowFullscreen = false;
- memset(&m_output, 0, sizeof(m_output));
}
CDVDPlayerVideo::~CDVDPlayerVideo()
@@ -908,34 +907,6 @@ void CDVDPlayerVideo::ProcessOverlays(DVDVideoPicture* pSource, double pts)
}
#endif
-static std::string GetRenderFormatName(ERenderFormat format)
-{
- switch(format)
- {
- case RENDER_FMT_YUV420P: return "YV12";
- case RENDER_FMT_YUV420P16: return "YV12P16";
- case RENDER_FMT_YUV420P10: return "YV12P10";
- case RENDER_FMT_NV12: return "NV12";
- 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_VAAPINV12: return "VAAPI_NV12";
- case RENDER_FMT_OMXEGL: return "OMXEGL";
- case RENDER_FMT_CVBREF: return "BGRA";
- case RENDER_FMT_EGLIMG: return "EGLIMG";
- case RENDER_FMT_BYPASS: return "BYPASS";
- case RENDER_FMT_MEDIACODEC:return "MEDIACODEC";
- case RENDER_FMT_MEDIACODECSURFACE:return "MEDIACODECSURFACE";
- case RENDER_FMT_IMXMAP: return "IMXMAP";
- case RENDER_FMT_MMAL: return "MMAL";
- case RENDER_FMT_NONE: return "NONE";
- }
- return "UNKNOWN";
-}
-
std::string CDVDPlayerVideo::GetStereoMode()
{
std::string stereo_mode;
@@ -965,97 +936,40 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
/* figure out steremode expected based on user settings and hints */
unsigned int stereo_flags = GetStereoModeFlags(GetStereoMode());
-#ifdef HAS_VIDEO_PLAYBACK
double config_framerate = m_bFpsInvalid ? 0.0 : m_fFrameRate;
- double render_framerate = g_graphicsContext.GetFPS();
- if (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) == ADJUST_REFRESHRATE_OFF)
- render_framerate = config_framerate;
- bool changerefresh = !m_bFpsInvalid &&
- (m_output.framerate == 0.0 || fmod(m_output.framerate, config_framerate) != 0.0) &&
- (render_framerate != config_framerate);
-
- /* check so that our format or aspect has changed. if it has, reconfigure renderer */
- if (!g_renderManager.IsConfigured()
- || ( m_output.width != pPicture->iWidth )
- || ( m_output.height != pPicture->iHeight )
- || ( m_output.dwidth != pPicture->iDisplayWidth )
- || ( m_output.dheight != pPicture->iDisplayHeight )
- || changerefresh
- || ( m_output.color_format != (unsigned int)pPicture->format )
- || ( m_output.extended_format != pPicture->extended_format )
- || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified
- || ( m_output.chroma_position != pPicture->chroma_position && pPicture->chroma_position != 0 )
- || ( m_output.color_primaries != pPicture->color_primaries && pPicture->color_primaries != 0 )
- || ( m_output.color_transfer != pPicture->color_transfer && pPicture->color_transfer != 0 )
- || ( m_output.color_range != pPicture->color_range )
- || ( m_output.stereo_flags != stereo_flags))
- {
- CLog::Log(LOGNOTICE, " fps: %f, pwidth: %i, pheight: %i, dwidth: %i, dheight: %i"
- , config_framerate
- , pPicture->iWidth
- , pPicture->iHeight
- , pPicture->iDisplayWidth
- , pPicture->iDisplayHeight);
-
- unsigned flags = 0;
- if(pPicture->color_range == 1)
- flags |= CONF_FLAGS_YUV_FULLRANGE;
- flags |= GetFlagsChromaPosition(pPicture->chroma_position)
- | GetFlagsColorMatrix(pPicture->color_matrix, pPicture->iWidth, pPicture->iHeight)
- | GetFlagsColorPrimaries(pPicture->color_primaries)
- | GetFlagsColorTransfer(pPicture->color_transfer);
+ unsigned flags = 0;
+ if(pPicture->color_range == 1)
+ flags |= CONF_FLAGS_YUV_FULLRANGE;
- std::string formatstr = GetRenderFormatName(pPicture->format);
-
- if(m_bAllowFullscreen)
- {
- flags |= CONF_FLAGS_FULLSCREEN;
- m_bAllowFullscreen = false; // only allow on first configure
- }
+ flags |= GetFlagsChromaPosition(pPicture->chroma_position)
+ | GetFlagsColorMatrix(pPicture->color_matrix, pPicture->iWidth, pPicture->iHeight)
+ | GetFlagsColorPrimaries(pPicture->color_primaries)
+ | GetFlagsColorTransfer(pPicture->color_transfer);
- flags |= stereo_flags;
-
- CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str());
- if(!g_renderManager.Configure(pPicture->iWidth
- , pPicture->iHeight
- , pPicture->iDisplayWidth
- , pPicture->iDisplayHeight
- , config_framerate
- , flags
- , pPicture->format
- , pPicture->extended_format
- , m_hints.orientation
- , m_pVideoCodec->GetAllowedReferences()))
- {
- CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__);
- return EOS_ABORT;
- }
- m_output.width = pPicture->iWidth;
- m_output.height = pPicture->iHeight;
- m_output.dwidth = pPicture->iDisplayWidth;
- m_output.dheight = pPicture->iDisplayHeight;
- m_output.framerate = config_framerate;
- m_output.color_format = pPicture->format;
- m_output.extended_format = pPicture->extended_format;
- m_output.color_matrix = pPicture->color_matrix;
- m_output.chroma_position = pPicture->chroma_position;
- m_output.color_primaries = pPicture->color_primaries;
- m_output.color_transfer = pPicture->color_transfer;
- m_output.color_range = pPicture->color_range;
- m_output.stereo_flags = stereo_flags;
+ if(m_bAllowFullscreen)
+ {
+ flags |= CONF_FLAGS_FULLSCREEN;
+ m_bAllowFullscreen = false; // only allow on first configure
}
- int result = 0;
+ flags |= stereo_flags;
- if (!g_renderManager.IsStarted()) {
- CLog::Log(LOGERROR, "%s - renderer not started", __FUNCTION__);
+ if(!g_renderManager.Configure(picture,
+ config_framerate,
+ flags,
+ m_hints.orientation,
+ m_pVideoCodec->GetAllowedReferences()))
+ {
+ CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__);
return EOS_ABORT;
}
+ int result = 0;
+
//correct any pattern in the timestamps
- if (m_output.color_format != RENDER_FMT_BYPASS)
+ if (picture.format != RENDER_FMT_BYPASS)
{
m_pullupCorrection.Add(pts);
pts += m_pullupCorrection.GetCorrection();
@@ -1076,7 +990,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
pts -= DVD_TIME_BASE * interval;
}
- if (m_output.color_format != RENDER_FMT_BYPASS)
+ if (picture.format != RENDER_FMT_BYPASS)
{
// Correct pts by user set delay and rendering delay
pts += m_iVideoDelay - DVD_SEC_TO_TIME(g_renderManager.GetDisplayLatency());
@@ -1210,10 +1124,6 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
g_renderManager.FlipPage(CThread::m_bStop, (iCurrentClock + iSleepTime) / DVD_TIME_BASE, pts_org, -1, mDisplayField);
return result;
-#else
- // no video renderer, let's mark it as dropped
- return EOS_DROPPED;
-#endif
}
std::string CDVDPlayerVideo::GetPlayerInfo()
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
index 3e0d065ca2..b1caceea70 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
@@ -161,23 +161,6 @@ protected:
bool m_bFpsInvalid; // needed to ignore fps (e.g. dvd stills)
- struct SOutputConfiguration
- {
- unsigned int width;
- unsigned int height;
- unsigned int dwidth;
- unsigned int dheight;
- unsigned int color_format;
- unsigned int extended_format;
- unsigned int color_matrix : 4;
- unsigned int color_range : 1;
- unsigned int chroma_position;
- unsigned int color_primaries;
- unsigned int color_transfer;
- unsigned int stereo_flags;
- double framerate;
- } m_output; //holds currently configured output
-
bool m_bAllowFullscreen;
bool m_bRenderSubs;
diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp
index 27efb6401f..a844725ebb 100644
--- a/xbmc/guilib/GUIVideoControl.cpp
+++ b/xbmc/guilib/GUIVideoControl.cpp
@@ -55,7 +55,7 @@ void CGUIVideoControl::Render()
// don't render if we aren't playing video, or if the renderer isn't started
// (otherwise the lock we have from CApplication::Render() may clash with the startup
// locks in the RenderManager.)
- if (g_application.m_pPlayer->IsPlayingVideo() && g_renderManager.IsStarted())
+ if (g_application.m_pPlayer->IsPlayingVideo() && g_renderManager.IsConfigured())
{
#else
if (g_application.m_pPlayer->IsPlayingVideo())
@@ -101,7 +101,7 @@ void CGUIVideoControl::Render()
void CGUIVideoControl::RenderEx()
{
#ifdef HAS_VIDEO_PLAYBACK
- if (g_application.m_pPlayer->IsPlayingVideo() && g_renderManager.IsStarted())
+ if (g_application.m_pPlayer->IsPlayingVideo() && g_renderManager.IsConfigured())
g_renderManager.Render(false, 0, 255, false);
g_renderManager.FrameFinish();
#endif