aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/shaders/yuv2rgb_basic.glsl26
-rw-r--r--system/shaders/yuv2rgb_basic_gles.glsl50
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp6
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt34
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp (renamed from xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.cpp)191
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h (renamed from xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.h)37
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp238
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h160
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp158
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h30
12 files changed, 635 insertions, 299 deletions
diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl
index 59cac3eaa8..7141ffe68d 100644
--- a/system/shaders/yuv2rgb_basic.glsl
+++ b/system/shaders/yuv2rgb_basic.glsl
@@ -24,19 +24,24 @@
# define sampler2D sampler2DRect
#endif
+#ifdef GL_ES
+ precision mediump float;
+#endif
+
uniform sampler2D m_sampY;
uniform sampler2D m_sampU;
uniform sampler2D m_sampV;
varying vec2 m_cordY;
varying vec2 m_cordU;
varying vec2 m_cordV;
-
uniform vec2 m_step;
-
uniform mat4 m_yuvmat;
-
uniform float m_stretch;
+#ifdef GL_ES
+ uniform float m_alpha;
+#endif
+
vec2 stretch(vec2 pos)
{
#if (XBMC_STRETCH)
@@ -67,7 +72,12 @@ vec4 process()
, 1.0 );
rgb = m_yuvmat * yuv;
+
+#ifdef GL_ES
+ rgb.a = m_alpha;
+#else
rgb.a = gl_Color.a;
+#endif
#elif defined(XBMC_NV12_RRG)
@@ -78,7 +88,12 @@ vec4 process()
, 1.0 );
rgb = m_yuvmat * yuv;
+
+#ifdef GL_ES
+ rgb.a = m_alpha;
+#else
rgb.a = gl_Color.a;
+#endif
#elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
@@ -117,9 +132,14 @@ vec4 process()
vec4 yuv = vec4(outY, outUV, 1.0);
rgb = m_yuvmat * yuv;
+#ifdef GL_ES
+ rgb.a = m_alpha;
+#else
rgb.a = gl_Color.a;
#endif
+#endif
+
return rgb;
}
diff --git a/system/shaders/yuv2rgb_basic_gles.glsl b/system/shaders/yuv2rgb_basic_gles.glsl
deleted file mode 100644
index 82fa003b53..0000000000
--- a/system/shaders/yuv2rgb_basic_gles.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-precision mediump float;
-uniform sampler2D m_sampY;
-uniform sampler2D m_sampU;
-uniform sampler2D m_sampV;
-varying vec2 m_cordY;
-varying vec2 m_cordU;
-varying vec2 m_cordV;
-uniform float m_alpha;
-uniform mat4 m_yuvmat;
-
-// handles both YV12 and NV12 formats
-void main()
-{
- vec4 yuv, rgb;
-#if defined(XBMC_NV12_RRG)
- yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r
- , texture2D(m_sampU, m_cordU).r
- , texture2D(m_sampV, m_cordV).g
- , 1.0);
-#else
- yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r
- , texture2D(m_sampU, m_cordU).g
- , texture2D(m_sampV, m_cordV).a
- , 1.0);
-#endif
-
- rgb = m_yuvmat * yuv;
- rgb.a = m_alpha;
- gl_FragColor = rgb;
-}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
index ac2f1db709..f2fdff50ce 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
@@ -32,7 +32,7 @@
#include "settings/DisplaySettings.h"
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
-#include "VideoShaders/YUV2RGBShader.h"
+#include "VideoShaders/YUV2RGBShaderGL.h"
#include "VideoShaders/VideoFilterShaderGL.h"
#include "windowing/WindowingFactory.h"
#include "guilib/Texture.h"
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
index 38946dd6b1..f25883ad7b 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
@@ -36,7 +36,7 @@
#include "settings/DisplaySettings.h"
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
-#include "VideoShaders/YUV2RGBShader.h"
+#include "VideoShaders/YUV2RGBShaderGLES.h"
#include "VideoShaders/VideoFilterShaderGLES.h"
#include "windowing/WindowingFactory.h"
#include "guilib/Texture.h"
@@ -541,8 +541,8 @@ void CLinuxRendererGLES::LoadShaders(int field)
CLog::Log(LOGNOTICE, "GL: Selecting Single Pass YUV 2 RGB shader");
EShaderFormat shaderFormat = GetShaderFormat();
- m_pYUVProgShader = new YUV2RGBProgressiveShader(false, m_iFlags, shaderFormat);
- m_pYUVBobShader = new YUV2RGBBobShader(false, m_iFlags, shaderFormat);
+ m_pYUVProgShader = new YUV2RGBProgressiveShader(m_iFlags, shaderFormat);
+ m_pYUVBobShader = new YUV2RGBBobShader(m_iFlags, shaderFormat);
if ((m_pYUVProgShader && m_pYUVProgShader->CompileAndLink())
&& (m_pYUVBobShader && m_pYUVBobShader->CompileAndLink()))
{
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
index d39a5594b7..3f02baf112 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
@@ -1,23 +1,23 @@
-set(SOURCES ConvolutionKernels.cpp)
+set(SOURCES ConvolutionKernels.cpp
+ YUVMatrix.cpp)
set(HEADERS ConvolutionKernels.h
+ YUVMatrix.h
dither.h
ShaderFormats.h)
if(CORE_SYSTEM_NAME STREQUAL windows)
- list(APPEND SOURCES WinVideoFilter.cpp
- YUV2RGBShader.cpp)
- list(APPEND HEADERS WinVideoFilter.h
- YUV2RGBShader.h)
+ list(APPEND SOURCES WinVideoFilter.cpp)
+ list(APPEND HEADERS WinVideoFilter.h)
endif()
if(OPENGL_FOUND)
- list(APPEND SOURCES VideoFilterShaderGL.cpp
- GLSLOutput.cpp
- YUV2RGBShader.cpp)
- list(APPEND HEADERS VideoFilterShaderGL.h
- GLSLOutput.h
- YUV2RGBShader.h)
+ list(APPEND SOURCES GLSLOutput.cpp
+ VideoFilterShaderGL.cpp
+ YUV2RGBShaderGL.cpp)
+ list(APPEND HEADERS GLSLOutput.h
+ VideoFilterShaderGL.h
+ YUV2RGBShaderGL.h)
endif()
if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR
@@ -26,12 +26,12 @@ if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR
CORE_PLATFORM_NAME_LC STREQUAL imx OR
CORE_PLATFORM_NAME_LC STREQUAL mir OR
CORE_PLATFORM_NAME_LC STREQUAL wayland))
- list(APPEND SOURCES VideoFilterShaderGLES.cpp
- GLSLOutput.cpp
- YUV2RGBShader.cpp)
- list(APPEND HEADERS VideoFilterShaderGLES.h
- GLSLOutput.h
- YUV2RGBShader.h)
+ list(APPEND SOURCES GLSLOutput.cpp
+ VideoFilterShaderGLES.cpp
+ YUV2RGBShaderGLES.cpp)
+ list(APPEND HEADERS GLSLOutput.h
+ VideoFilterShaderGLES.h
+ YUV2RGBShaderGLES.h)
endif()
core_add_library(videoshaders)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
index ce79623b62..3eaa59ac11 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
@@ -28,7 +28,7 @@
#include "VideoRenderers/WinRenderBuffer.h"
#include "windowing/WindowingFactory.h"
#include "WinVideoFilter.h"
-#include "YUV2RGBShader.h"
+#include "YUVMatrix.h"
#include <DirectXPackedVector.h>
#include <map>
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
index 70a7a329b7..5549ff313f 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
@@ -21,153 +21,16 @@
#include "system.h"
#include "../RenderFlags.h"
-#include "YUV2RGBShader.h"
+#include "YUV2RGBShaderGL.h"
+#include "YUVMatrix.h"
#include "settings/AdvancedSettings.h"
#include "guilib/TransformMatrix.h"
#include "utils/log.h"
-#if defined(HAS_GL) || defined(HAS_GLES)
#include "utils/GLUtils.h"
-#endif
#include <string>
#include <sstream>
-// http://www.martinreddy.net/gfx/faqs/colorconv.faq
-
-//
-// Transformation matrixes for different colorspaces.
-//
-static float yuv_coef_bt601[4][4] =
-{
- { 1.0f, 1.0f, 1.0f, 0.0f },
- { 0.0f, -0.344f, 1.773f, 0.0f },
- { 1.403f, -0.714f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f }
-};
-
-static float yuv_coef_bt709[4][4] =
-{
- { 1.0f, 1.0f, 1.0f, 0.0f },
- { 0.0f, -0.1870f, 1.8556f, 0.0f },
- { 1.5701f, -0.4664f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f }
-};
-
-static float yuv_coef_bt2020[4][4] =
-{
- { 1.0f, 1.0f, 1.0f, 0.0f },
- { 0.0f, -0.1645f, 1.8814f, 0.0f },
- { 1.4745f, -0.5713f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f }
-};
-
-static float yuv_coef_ebu[4][4] =
-{
- { 1.0f, 1.0f, 1.0f, 0.0f },
- { 0.0f, -0.3960f, 2.029f, 0.0f },
- { 1.140f, -0.581f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f }
-};
-
-static float yuv_coef_smtp240m[4][4] =
-{
- { 1.0f, 1.0f, 1.0f, 0.0f },
- { 0.0f, -0.2253f, 1.8270f, 0.0f },
- { 1.5756f, -0.5000f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f }
-};
-
-static float** PickYUVConversionMatrix(unsigned flags)
-{
- // Pick the matrix.
-
- switch(CONF_FLAGS_YUVCOEF_MASK(flags))
- {
- case CONF_FLAGS_YUVCOEF_240M:
- return reinterpret_cast<float**>(yuv_coef_smtp240m);
- case CONF_FLAGS_YUVCOEF_BT2020:
- return reinterpret_cast<float**>(yuv_coef_bt2020);
- case CONF_FLAGS_YUVCOEF_BT709:
- return reinterpret_cast<float**>(yuv_coef_bt709);
- case CONF_FLAGS_YUVCOEF_BT601:
- return reinterpret_cast<float**>(yuv_coef_bt601);
- case CONF_FLAGS_YUVCOEF_EBU:
- return reinterpret_cast<float**>(yuv_coef_ebu);
- }
-
- return reinterpret_cast<float**>(yuv_coef_bt601);
-}
-
-void CalculateYUVMatrix(TransformMatrix &matrix
- , unsigned int flags
- , EShaderFormat format
- , float black
- , float contrast
- , bool limited)
-{
- TransformMatrix coef;
-
- matrix *= TransformMatrix::CreateScaler(contrast, contrast, contrast);
- matrix *= TransformMatrix::CreateTranslation(black, black, black);
-
- float (*conv)[4] = (float (*)[4])PickYUVConversionMatrix(flags);
- for(int row = 0; row < 3; row++)
- for(int col = 0; col < 4; col++)
- coef.m[row][col] = conv[col][row];
- coef.identity = false;
-
- if (limited)
- {
- matrix *= TransformMatrix::CreateTranslation(+ 16.0f / 255
- , + 16.0f / 255
- , + 16.0f / 255);
- matrix *= TransformMatrix::CreateScaler((235 - 16) / 255.0f
- , (235 - 16) / 255.0f
- , (235 - 16) / 255.0f);
- }
-
- matrix *= coef;
- matrix *= TransformMatrix::CreateTranslation(0.0, -0.5, -0.5);
-
- if (!(flags & CONF_FLAGS_YUV_FULLRANGE))
- {
- matrix *= TransformMatrix::CreateScaler(255.0f / (235 - 16)
- , 255.0f / (240 - 16)
- , 255.0f / (240 - 16));
- matrix *= TransformMatrix::CreateTranslation(- 16.0f / 255
- , - 16.0f / 255
- , - 16.0f / 255);
- }
-
- int effectiveBpp;
- switch (format)
- {
- case SHADER_YV12_9:
- effectiveBpp = 9;
- break;
- case SHADER_YV12_10:
- effectiveBpp = 10;
- break;
- case SHADER_YV12_12:
- effectiveBpp = 12;
- break;
- case SHADER_YV12_14:
- effectiveBpp = 14;
- break;
- default:
- effectiveBpp = 0;
- }
-
- if (effectiveBpp > 8 && effectiveBpp < 16)
- {
- // Convert range to 2 bytes
- float scale = 65535.0f / ((1 << effectiveBpp) - 1);
- matrix *= TransformMatrix::CreateScaler(scale, scale, scale);
- }
-}
-
-#if defined(HAS_GL) || HAS_GLES >= 2
-
using namespace Shaders;
static void CalculateYUVMatrixGL(GLfloat res[4][4]
@@ -221,7 +84,6 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderF
m_defines += m_glslOutput->GetDefines();
}
-#ifdef HAS_GL
if(rect)
m_defines += "#define XBMC_texture_rectangle 1\n";
else
@@ -259,27 +121,6 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderF
CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format);
VertexShader()->LoadSource("yuv2rgb_vertex.glsl", m_defines);
-#elif HAS_GLES >= 2
- m_hVertex = -1;
- m_hYcoord = -1;
- m_hUcoord = -1;
- m_hVcoord = -1;
- m_hProj = -1;
- m_hModel = -1;
- m_hAlpha = -1;
- if (m_format == SHADER_YV12)
- m_defines += "#define XBMC_YV12\n";
- else if (m_format == SHADER_NV12)
- m_defines += "#define XBMC_NV12\n";
- else if (m_format == SHADER_NV12_RRG)
- m_defines += "#define XBMC_NV12_RRG\n";
- else if (m_format == SHADER_YV12)
- m_defines += "#define XBMC_YV12\n";
- else
- CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format);
-
- VertexShader()->LoadSource("yuv2rgb_vertex_gles.glsl", m_defines);
-#endif
CLog::Log(LOGDEBUG, "GL: BaseYUV2RGBGLSLShader: defines:\n%s", m_defines.c_str());
}
@@ -291,15 +132,6 @@ BaseYUV2RGBGLSLShader::~BaseYUV2RGBGLSLShader()
void BaseYUV2RGBGLSLShader::OnCompiledAndLinked()
{
-#if HAS_GLES >= 2
- m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
- m_hYcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordY");
- m_hUcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordU");
- m_hVcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordV");
- m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
- m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
- m_hAlpha = glGetUniformLocation(ProgramHandle(), "m_alpha");
-#endif
m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY");
m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU");
m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV");
@@ -325,11 +157,7 @@ bool BaseYUV2RGBGLSLShader::OnEnabled()
CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast, !m_convertFullRange);
glUniformMatrix4fv(m_hMatrix, 1, GL_FALSE, (GLfloat*)matrix);
-#if HAS_GLES >= 2
- glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
- glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
- glUniform1f(m_hAlpha, m_alpha);
-#endif
+
VerifyGLState();
if (m_glslOutput) m_glslOutput->OnEnabled();
return true;
@@ -347,7 +175,6 @@ void BaseYUV2RGBGLSLShader::Free()
//////////////////////////////////////////////////////////////////////
// BaseYUV2RGBGLSLShader - base class for GLSL YUV2RGB shaders
//////////////////////////////////////////////////////////////////////
-#if defined(HAS_GL) // No ARB Shader when using GLES2.0
BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format)
{
m_width = 1;
@@ -361,7 +188,6 @@ BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format)
m_hUTex = -1;
m_hVTex = -1;
}
-#endif
//////////////////////////////////////////////////////////////////////
// YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing
@@ -372,12 +198,8 @@ YUV2RGBProgressiveShader::YUV2RGBProgressiveShader(bool rect, unsigned flags, ES
GLSLOutput *output)
: BaseYUV2RGBGLSLShader(rect, flags, format, stretch, output)
{
-#ifdef HAS_GL
PixelShader()->LoadSource("yuv2rgb_basic.glsl", m_defines);
PixelShader()->AppendSource("output.glsl");
-#elif HAS_GLES >= 2
- PixelShader()->LoadSource("yuv2rgb_basic_gles.glsl", m_defines);
-#endif
}
@@ -391,11 +213,7 @@ YUV2RGBBobShader::YUV2RGBBobShader(bool rect, unsigned flags, EShaderFormat form
m_hStepX = -1;
m_hStepY = -1;
m_hField = -1;
-#ifdef HAS_GL
PixelShader()->LoadSource("yuv2rgb_bob.glsl", m_defines);
-#elif HAS_GLES >= 2
- PixelShader()->LoadSource("yuv2rgb_bob_gles.glsl", m_defines);
-#endif
}
void YUV2RGBBobShader::OnCompiledAndLinked()
@@ -422,7 +240,6 @@ bool YUV2RGBBobShader::OnEnabled()
//////////////////////////////////////////////////////////////////////
// YUV2RGBProgressiveShaderARB - YUV2RGB with no deinterlacing
//////////////////////////////////////////////////////////////////////
-#if defined(HAS_GL) // No ARB Shader when using GLES2.0
YUV2RGBProgressiveShaderARB::YUV2RGBProgressiveShaderARB(bool rect, unsigned flags, EShaderFormat format)
: BaseYUV2RGBARBShader(flags, format)
{
@@ -479,5 +296,3 @@ bool YUV2RGBProgressiveShaderARB::OnEnabled()
m_width, m_height);
return true;
}
-#endif
-#endif // HAS_GL
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
index 4e0b4817ea..e8220f2c05 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
@@ -29,8 +29,6 @@ void CalculateYUVMatrix(TransformMatrix &matrix
, float contrast
, bool limited);
-#if defined(HAS_GL) || HAS_GLES >= 2
-
#include "GLSLOutput.h"
#ifndef __GNUC__
@@ -54,15 +52,7 @@ namespace Shaders {
virtual void SetBlack(float black) {};
virtual void SetContrast(float contrast) {};
virtual void SetNonLinStretch(float stretch) {};
-#if HAS_GLES >= 2
- virtual GLint GetVertexLoc() { return 0; };
- virtual GLint GetYcoordLoc() { return 0; };
- virtual GLint GetUcoordLoc() { return 0; };
- virtual GLint GetVcoordLoc() { return 0; };
-
- virtual void SetMatrices(GLfloat *p, GLfloat *m) {};
- virtual void SetAlpha(GLfloat alpha) {};
-#endif
+
void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; }
protected:
@@ -84,15 +74,6 @@ namespace Shaders {
void SetBlack(float black) override { m_black = black; }
void SetContrast(float contrast) override { m_contrast = contrast; }
void SetNonLinStretch(float stretch) override { m_stretch = stretch; }
-#if HAS_GLES >= 2
- GLint GetVertexLoc() override { return m_hVertex; }
- GLint GetYcoordLoc() override { return m_hYcoord; }
- GLint GetUcoordLoc() override { return m_hUcoord; }
- GLint GetVcoordLoc() override { return m_hVcoord; }
-
- void SetMatrices(GLfloat *p, GLfloat *m) override { m_proj = p; m_model = m; }
- void SetAlpha(GLfloat alpha) override { m_alpha = alpha; }
-#endif
protected:
void OnCompiledAndLinked() override;
@@ -121,22 +102,8 @@ namespace Shaders {
GLint m_hMatrix;
GLint m_hStretch;
GLint m_hStep;
-#if HAS_GLES >= 2
- GLint m_hVertex;
- GLint m_hYcoord;
- GLint m_hUcoord;
- GLint m_hVcoord;
- GLint m_hProj;
- GLint m_hModel;
- GLint m_hAlpha;
-
- GLfloat *m_proj;
- GLfloat *m_model;
- GLfloat m_alpha;
-#endif
};
-#if defined(HAS_GL) // No ARB Shader when using GLES2.0
class BaseYUV2RGBARBShader
: public BaseYUV2RGBShader
, public CARBShaderProgram
@@ -174,7 +141,6 @@ namespace Shaders {
void OnCompiledAndLinked() override;
bool OnEnabled() override;
};
-#endif
class YUV2RGBProgressiveShader : public BaseYUV2RGBGLSLShader
{
@@ -203,4 +169,3 @@ namespace Shaders {
#ifndef __GNUC__
#pragma warning( pop )
#endif
-#endif
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp
new file mode 100644
index 0000000000..69dd780c58
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2007 d4rk
+ * Copyright (C) 2007-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "../RenderFlags.h"
+#include "YUV2RGBShaderGLES.h"
+#include "YUVMatrix.h"
+#include "settings/AdvancedSettings.h"
+#include "guilib/TransformMatrix.h"
+#include "utils/log.h"
+#include "utils/GLUtils.h"
+
+#include <string>
+#include <sstream>
+
+using namespace Shaders;
+
+static void CalculateYUVMatrixGL(GLfloat res[4][4]
+ , unsigned int flags
+ , EShaderFormat format
+ , float black
+ , float contrast
+ , bool limited)
+{
+ TransformMatrix matrix;
+ CalculateYUVMatrix(matrix, flags, format, black, contrast, limited);
+
+ for(int row = 0; row < 3; row++)
+ for(int col = 0; col < 4; col++)
+ res[col][row] = matrix.m[row][col];
+
+ res[0][3] = 0.0f;
+ res[1][3] = 0.0f;
+ res[2][3] = 0.0f;
+ res[3][3] = 1.0f;
+}
+
+//////////////////////////////////////////////////////////////////////
+// BaseYUV2RGBGLSLShader - base class for GLSL YUV2RGB shaders
+//////////////////////////////////////////////////////////////////////
+
+BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(unsigned flags, EShaderFormat format, bool stretch,
+ GLSLOutput *output)
+{
+ m_width = 1;
+ m_height = 1;
+ m_field = 0;
+ m_flags = flags;
+ m_format = format;
+
+ m_black = 0.0f;
+ m_contrast = 1.0f;
+
+ m_stretch = 0.0f;
+
+ // shader attribute handles
+ m_hYTex = -1;
+ m_hUTex = -1;
+ m_hVTex = -1;
+ m_hMatrix = -1;
+ m_hStretch = -1;
+ m_hStep = -1;
+
+ m_hVertex = -1;
+ m_hYcoord = -1;
+ m_hUcoord = -1;
+ m_hVcoord = -1;
+ m_hProj = -1;
+ m_hModel = -1;
+ m_hAlpha = -1;
+
+ m_proj = nullptr;
+ m_model = nullptr;
+ m_alpha = 1.0;
+
+ // get defines from the output stage if used
+ m_glslOutput = output;
+ if (m_glslOutput)
+ m_defines += m_glslOutput->GetDefines();
+
+ // not supported on GLES 2.0
+ m_defines += "#define XBMC_texture_rectangle 0\n";
+ m_defines += "#define XBMC_texture_rectangle_hack 0\n";
+
+ //don't compile in stretch support when it's not needed
+ if (stretch)
+ m_defines += "#define XBMC_STRETCH 1\n";
+ else
+ m_defines += "#define XBMC_STRETCH 0\n";
+
+ if (m_format == SHADER_YV12 ||
+ m_format == SHADER_YV12_9 ||
+ m_format == SHADER_YV12_10 ||
+ m_format == SHADER_YV12_12 ||
+ m_format == SHADER_YV12_14 ||
+ m_format == SHADER_YV12_16)
+ m_defines += "#define XBMC_YV12\n";
+ else if (m_format == SHADER_NV12)
+ m_defines += "#define XBMC_NV12\n";
+ else if (m_format == SHADER_YUY2)
+ m_defines += "#define XBMC_YUY2\n";
+ else if (m_format == SHADER_UYVY)
+ m_defines += "#define XBMC_UYVY\n";
+ else if (m_format == SHADER_NV12_RRG)
+ m_defines += "#define XBMC_NV12_RRG\n";
+ else if (m_format == SHADER_YV12)
+ m_defines += "#define XBMC_YV12\n";
+ else
+ CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format);
+
+ VertexShader()->LoadSource("yuv2rgb_vertex_gles.glsl", m_defines);
+
+ CLog::Log(LOGDEBUG, "GL: BaseYUV2RGBGLSLShader: defines:\n%s", m_defines.c_str());
+}
+
+BaseYUV2RGBGLSLShader::~BaseYUV2RGBGLSLShader()
+{
+ delete m_glslOutput;
+}
+
+void BaseYUV2RGBGLSLShader::OnCompiledAndLinked()
+{
+ m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
+ m_hYcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordY");
+ m_hUcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordU");
+ m_hVcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordV");
+ m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
+ m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hAlpha = glGetUniformLocation(ProgramHandle(), "m_alpha");
+ m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY");
+ m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU");
+ m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV");
+ m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_yuvmat");
+ m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
+ m_hStep = glGetUniformLocation(ProgramHandle(), "m_step");
+ VerifyGLState();
+
+ if (m_glslOutput) m_glslOutput->OnCompiledAndLinked(ProgramHandle());
+}
+
+bool BaseYUV2RGBGLSLShader::OnEnabled()
+{
+ // set shader attributes once enabled
+ glUniform1i(m_hYTex, 0);
+ glUniform1i(m_hUTex, 1);
+ glUniform1i(m_hVTex, 2);
+ glUniform1f(m_hStretch, m_stretch);
+ glUniform2f(m_hStep, 1.0 / m_width, 1.0 / m_height);
+
+ GLfloat matrix[4][4];
+ // keep video levels
+ CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast, !m_convertFullRange);
+
+ glUniformMatrix4fv(m_hMatrix, 1, GL_FALSE, (GLfloat*)matrix);
+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
+ glUniform1f(m_hAlpha, m_alpha);
+ VerifyGLState();
+ if (m_glslOutput) m_glslOutput->OnEnabled();
+ return true;
+}
+
+void BaseYUV2RGBGLSLShader::OnDisabled()
+{
+ if (m_glslOutput) m_glslOutput->OnDisabled();
+}
+
+void BaseYUV2RGBGLSLShader::Free()
+{
+ if (m_glslOutput) m_glslOutput->Free();
+}
+
+//////////////////////////////////////////////////////////////////////
+// YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing
+// Use for weave deinterlacing / progressive
+//////////////////////////////////////////////////////////////////////
+
+YUV2RGBProgressiveShader::YUV2RGBProgressiveShader(unsigned flags, EShaderFormat format, bool stretch,
+ GLSLOutput *output)
+ : BaseYUV2RGBGLSLShader(flags, format, stretch, output)
+{
+ PixelShader()->LoadSource("yuv2rgb_basic.glsl", m_defines);
+ PixelShader()->AppendSource("output.glsl");
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// YUV2RGBBobShader - YUV2RGB with Bob deinterlacing
+//////////////////////////////////////////////////////////////////////
+
+YUV2RGBBobShader::YUV2RGBBobShader(unsigned flags, EShaderFormat format)
+ : BaseYUV2RGBGLSLShader(flags, format, false)
+{
+ m_hStepX = -1;
+ m_hStepY = -1;
+ m_hField = -1;
+
+ PixelShader()->LoadSource("yuv2rgb_bob_gles.glsl", m_defines);
+}
+
+void YUV2RGBBobShader::OnCompiledAndLinked()
+{
+ BaseYUV2RGBGLSLShader::OnCompiledAndLinked();
+ m_hStepX = glGetUniformLocation(ProgramHandle(), "m_stepX");
+ m_hStepY = glGetUniformLocation(ProgramHandle(), "m_stepY");
+ m_hField = glGetUniformLocation(ProgramHandle(), "m_field");
+ VerifyGLState();
+}
+
+bool YUV2RGBBobShader::OnEnabled()
+{
+ if(!BaseYUV2RGBGLSLShader::OnEnabled())
+ return false;
+
+ glUniform1i(m_hField, m_field);
+ glUniform1f(m_hStepX, 1.0f / (float)m_width);
+ glUniform1f(m_hStepY, 1.0f / (float)m_height);
+ VerifyGLState();
+ return true;
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
new file mode 100644
index 0000000000..ff36c3c533
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
@@ -0,0 +1,160 @@
+/*
+ * 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 "guilib/TransformMatrix.h"
+#include "ShaderFormats.h"
+
+void CalculateYUVMatrix(TransformMatrix &matrix
+ , unsigned int flags
+ , EShaderFormat format
+ , float black
+ , float contrast
+ , bool limited);
+
+#include "GLSLOutput.h"
+
+#ifndef __GNUC__
+#pragma warning( push )
+#pragma warning( disable : 4250 )
+#endif
+
+#include "guilib/Shader.h"
+
+namespace Shaders {
+
+ class BaseYUV2RGBShader : virtual public CShaderProgram
+ {
+ public:
+ BaseYUV2RGBShader() : m_convertFullRange(false) {};
+ ~BaseYUV2RGBShader() override = default;
+ virtual void SetField(int field) {};
+ virtual void SetWidth(int width) {};
+ virtual void SetHeight(int width) {};
+
+ virtual void SetBlack(float black) {};
+ virtual void SetContrast(float contrast) {};
+ virtual void SetNonLinStretch(float stretch) {};
+
+ virtual GLint GetVertexLoc() { return 0; };
+ virtual GLint GetYcoordLoc() { return 0; };
+ virtual GLint GetUcoordLoc() { return 0; };
+ virtual GLint GetVcoordLoc() { return 0; };
+
+ virtual void SetMatrices(GLfloat *p, GLfloat *m) {};
+ virtual void SetAlpha(GLfloat alpha) {};
+
+ void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; }
+
+ protected:
+ bool m_convertFullRange;
+ };
+
+
+ class BaseYUV2RGBGLSLShader
+ : public BaseYUV2RGBShader
+ , public CGLSLShaderProgram
+ {
+ public:
+ BaseYUV2RGBGLSLShader(unsigned flags, EShaderFormat format, bool stretch, GLSLOutput *output=NULL);
+ ~BaseYUV2RGBGLSLShader() override;
+ void SetField(int field) override { m_field = field; }
+ void SetWidth(int w) override { m_width = w; }
+ void SetHeight(int h) override { m_height = h; }
+
+ void SetBlack(float black) override { m_black = black; }
+ void SetContrast(float contrast) override { m_contrast = contrast; }
+ void SetNonLinStretch(float stretch) override { m_stretch = stretch; }
+
+ GLint GetVertexLoc() override { return m_hVertex; }
+ GLint GetYcoordLoc() override { return m_hYcoord; }
+ GLint GetUcoordLoc() override { return m_hUcoord; }
+ GLint GetVcoordLoc() override { return m_hVcoord; }
+
+ void SetMatrices(GLfloat *p, GLfloat *m) override { m_proj = p; m_model = m; }
+ void SetAlpha(GLfloat alpha) override { m_alpha = alpha; }
+
+ protected:
+ void OnCompiledAndLinked() override;
+ bool OnEnabled() override;
+ void OnDisabled() override;
+ void Free() override;
+
+ unsigned m_flags;
+ EShaderFormat m_format;
+ int m_width;
+ int m_height;
+ int m_field;
+
+ float m_black;
+ float m_contrast;
+ float m_stretch;
+
+ std::string m_defines;
+
+ Shaders::GLSLOutput *m_glslOutput;
+
+ // shader attribute handles
+ GLint m_hYTex;
+ GLint m_hUTex;
+ GLint m_hVTex;
+ GLint m_hMatrix;
+ GLint m_hStretch;
+ GLint m_hStep;
+
+ GLint m_hVertex;
+ GLint m_hYcoord;
+ GLint m_hUcoord;
+ GLint m_hVcoord;
+ GLint m_hProj;
+ GLint m_hModel;
+ GLint m_hAlpha;
+
+ GLfloat *m_proj;
+ GLfloat *m_model;
+ GLfloat m_alpha;
+ };
+
+ class YUV2RGBProgressiveShader : public BaseYUV2RGBGLSLShader
+ {
+ public:
+ YUV2RGBProgressiveShader(unsigned flags=0,
+ EShaderFormat format=SHADER_NONE,
+ bool stretch = false,
+ GLSLOutput *output=NULL);
+ };
+
+ class YUV2RGBBobShader : public BaseYUV2RGBGLSLShader
+ {
+ public:
+ YUV2RGBBobShader(unsigned flags=0, EShaderFormat format=SHADER_NONE);
+ void OnCompiledAndLinked() override;
+ bool OnEnabled() override;
+
+ GLint m_hStepX;
+ GLint m_hStepY;
+ GLint m_hField;
+ };
+
+} // end namespace
+
+#ifndef __GNUC__
+#pragma warning( pop )
+#endif
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp
new file mode 100644
index 0000000000..fd3e61c147
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007 d4rk
+ * Copyright (C) 2007-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "../RenderFlags.h"
+#include "YUVMatrix.h"
+
+// http://www.martinreddy.net/gfx/faqs/colorconv.faq
+
+//
+// Transformation matrixes for different colorspaces.
+//
+static float yuv_coef_bt601[4][4] =
+{
+ { 1.0f, 1.0f, 1.0f, 0.0f },
+ { 0.0f, -0.344f, 1.773f, 0.0f },
+ { 1.403f, -0.714f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
+};
+
+static float yuv_coef_bt709[4][4] =
+{
+ { 1.0f, 1.0f, 1.0f, 0.0f },
+ { 0.0f, -0.1870f, 1.8556f, 0.0f },
+ { 1.5701f, -0.4664f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
+};
+
+static float yuv_coef_bt2020[4][4] =
+{
+ { 1.0f, 1.0f, 1.0f, 0.0f },
+ { 0.0f, -0.1645f, 1.8814f, 0.0f },
+ { 1.4745f, -0.5713f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
+};
+
+static float yuv_coef_ebu[4][4] =
+{
+ { 1.0f, 1.0f, 1.0f, 0.0f },
+ { 0.0f, -0.3960f, 2.029f, 0.0f },
+ { 1.140f, -0.581f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
+};
+
+static float yuv_coef_smtp240m[4][4] =
+{
+ { 1.0f, 1.0f, 1.0f, 0.0f },
+ { 0.0f, -0.2253f, 1.8270f, 0.0f },
+ { 1.5756f, -0.5000f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
+};
+
+static float** PickYUVConversionMatrix(unsigned flags)
+{
+ // Pick the matrix.
+
+ switch(CONF_FLAGS_YUVCOEF_MASK(flags))
+ {
+ case CONF_FLAGS_YUVCOEF_240M:
+ return reinterpret_cast<float**>(yuv_coef_smtp240m);
+ case CONF_FLAGS_YUVCOEF_BT2020:
+ return reinterpret_cast<float**>(yuv_coef_bt2020);
+ case CONF_FLAGS_YUVCOEF_BT709:
+ return reinterpret_cast<float**>(yuv_coef_bt709);
+ case CONF_FLAGS_YUVCOEF_BT601:
+ return reinterpret_cast<float**>(yuv_coef_bt601);
+ case CONF_FLAGS_YUVCOEF_EBU:
+ return reinterpret_cast<float**>(yuv_coef_ebu);
+ }
+
+ return reinterpret_cast<float**>(yuv_coef_bt601);
+}
+
+void CalculateYUVMatrix(TransformMatrix &matrix
+ , unsigned int flags
+ , EShaderFormat format
+ , float black
+ , float contrast
+ , bool limited)
+{
+ TransformMatrix coef;
+
+ matrix *= TransformMatrix::CreateScaler(contrast, contrast, contrast);
+ matrix *= TransformMatrix::CreateTranslation(black, black, black);
+
+ float (*conv)[4] = (float (*)[4])PickYUVConversionMatrix(flags);
+ for(int row = 0; row < 3; row++)
+ for(int col = 0; col < 4; col++)
+ coef.m[row][col] = conv[col][row];
+ coef.identity = false;
+
+ if (limited)
+ {
+ matrix *= TransformMatrix::CreateTranslation(+ 16.0f / 255
+ , + 16.0f / 255
+ , + 16.0f / 255);
+ matrix *= TransformMatrix::CreateScaler((235 - 16) / 255.0f
+ , (235 - 16) / 255.0f
+ , (235 - 16) / 255.0f);
+ }
+
+ matrix *= coef;
+ matrix *= TransformMatrix::CreateTranslation(0.0, -0.5, -0.5);
+
+ if (!(flags & CONF_FLAGS_YUV_FULLRANGE))
+ {
+ matrix *= TransformMatrix::CreateScaler(255.0f / (235 - 16)
+ , 255.0f / (240 - 16)
+ , 255.0f / (240 - 16));
+ matrix *= TransformMatrix::CreateTranslation(- 16.0f / 255
+ , - 16.0f / 255
+ , - 16.0f / 255);
+ }
+
+ int effectiveBpp;
+ switch (format)
+ {
+ case SHADER_YV12_9:
+ effectiveBpp = 9;
+ break;
+ case SHADER_YV12_10:
+ effectiveBpp = 10;
+ break;
+ case SHADER_YV12_12:
+ effectiveBpp = 12;
+ break;
+ case SHADER_YV12_14:
+ effectiveBpp = 14;
+ break;
+ default:
+ effectiveBpp = 0;
+ }
+
+ if (effectiveBpp > 8 && effectiveBpp < 16)
+ {
+ // Convert range to 2 bytes
+ float scale = 65535.0f / ((1 << effectiveBpp) - 1);
+ matrix *= TransformMatrix::CreateScaler(scale, scale, scale);
+ }
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h
new file mode 100644
index 0000000000..5ecffd7539
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "guilib/TransformMatrix.h"
+#include "ShaderFormats.h"
+
+void CalculateYUVMatrix(TransformMatrix &matrix
+ , unsigned int flags
+ , EShaderFormat format
+ , float black
+ , float contrast
+ , bool limited);