aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris "Koying" Browet <cbro@semperpax.com>2015-01-06 17:13:32 +0100
committerChris "koying" Browet <cbro@semperpax.com>2015-01-20 14:17:08 +0100
commite4e9f7a74b0f7e5ebf7ccced65778710be8bbd7d (patch)
treed97713ee5a8fbfaeef15fe46cf6bc42c84fd353e
parentc0ac9c470719d97a5ac6630b94cd70ae9c60ae07 (diff)
ADD: [gles] BOB deinterlacing
-rw-r--r--system/shaders/guishader_frag_rgba_bob.glsl47
-rw-r--r--system/shaders/guishader_frag_rgba_bob_oes.glsl49
-rw-r--r--xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp143
-rw-r--r--xbmc/guilib/GUIShader.cpp6
-rw-r--r--xbmc/guilib/GUIShader.h4
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.cpp20
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.h4
7 files changed, 234 insertions, 39 deletions
diff --git a/system/shaders/guishader_frag_rgba_bob.glsl b/system/shaders/guishader_frag_rgba_bob.glsl
new file mode 100644
index 0000000000..3b02726496
--- /dev/null
+++ b/system/shaders/guishader_frag_rgba_bob.glsl
@@ -0,0 +1,47 @@
+/*
+ * 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 highp float;
+uniform sampler2D m_samp0;
+uniform sampler2D m_samp1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying lowp vec4 m_colour;
+uniform int m_method;
+uniform int m_field;
+uniform float m_step;
+
+void main ()
+{
+ vec2 source;
+ source = m_cord0.xy;
+
+ float temp1 = mod(source.y, 2.0*m_step);
+ float temp2 = source.y - temp1;
+ source.y = temp2 + m_step/2.0 - float(m_field)*m_step;
+
+ // Blend missing line
+ vec2 below;
+ float bstep = step(m_step, temp1);
+ below.x = source.x;
+ below.y = source.y + (2.0*m_step*bstep);
+
+ gl_FragColor = mix(texture2D(m_samp0, source), texture2D(m_samp0, below), 0.5);
+}
diff --git a/system/shaders/guishader_frag_rgba_bob_oes.glsl b/system/shaders/guishader_frag_rgba_bob_oes.glsl
new file mode 100644
index 0000000000..9b7be39744
--- /dev/null
+++ b/system/shaders/guishader_frag_rgba_bob_oes.glsl
@@ -0,0 +1,49 @@
+/*
+ * 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/>.
+ *
+ */
+
+#extension GL_OES_EGL_image_external : require
+
+precision highp float;
+uniform samplerExternalOES m_samp0;
+uniform samplerExternalOES m_samp1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying lowp vec4 m_colour;
+uniform int m_method;
+uniform int m_field;
+uniform float m_step;
+
+void main ()
+{
+ vec2 source;
+ source = m_cord0.xy;
+
+ float temp1 = mod(source.y, 2.0*m_step);
+ float temp2 = source.y - temp1;
+ source.y = temp2 + m_step/2.0 - float(m_field)*m_step;
+
+ // Blend missing line
+ vec2 below;
+ float bstep = step(m_step, temp1);
+ below.x = source.x;
+ below.y = source.y + (2.0*m_step*bstep);
+
+ gl_FragColor = mix(texture2D(m_samp0, source), texture2D(m_samp0, below), 0.5);
+}
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
index 5334a75a7a..07b6fa7c4b 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
@@ -1469,14 +1469,28 @@ void CLinuxRendererGLES::RenderEglImage(int index, int field)
unsigned int time = XbmcThreads::SystemClockMillis();
#endif
- YUVPLANE &plane = m_buffers[index].fields[field][0];
+ YUVPLANE &plane = m_buffers[index].fields[0][0];
+ YUVPLANE &planef = m_buffers[index].fields[field][0];
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(m_textureTarget, plane.id);
- g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA);
+ if (field != FIELD_FULL)
+ {
+ g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA_BOB);
+ GLint fieldLoc = g_Windowing.GUIShaderGetField();
+ GLint stepLoc = g_Windowing.GUIShaderGetStep();
+
+ if (field == FIELD_TOP)
+ glUniform1i(fieldLoc, 1);
+ else if(field == FIELD_BOT)
+ glUniform1i(fieldLoc, 0);
+ glUniform1f(stepLoc, 1.0f / (float)plane.texheight);
+ }
+ else
+ g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA);
GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
GLfloat ver[4][4];
@@ -1504,10 +1518,20 @@ void CLinuxRendererGLES::RenderEglImage(int index, int field)
ver[i][3] = 1.0f;
}
- tex[0][0] = tex[3][0] = plane.rect.x1;
- tex[0][1] = tex[1][1] = plane.rect.y1;
- tex[1][0] = tex[2][0] = plane.rect.x2;
- tex[2][1] = tex[3][1] = plane.rect.y2;
+ if (field == FIELD_FULL)
+ {
+ tex[0][0] = tex[3][0] = plane.rect.x1;
+ tex[0][1] = tex[1][1] = plane.rect.y1;
+ tex[1][0] = tex[2][0] = plane.rect.x2;
+ tex[2][1] = tex[3][1] = plane.rect.y2;
+ }
+ else
+ {
+ tex[0][0] = tex[3][0] = planef.rect.x1;
+ tex[0][1] = tex[1][1] = planef.rect.y1 * 2.0f;
+ tex[1][0] = tex[2][0] = planef.rect.x2;
+ tex[2][1] = tex[3][1] = planef.rect.y2 * 2.0f;
+ }
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
@@ -1535,13 +1559,27 @@ void CLinuxRendererGLES::RenderSurfaceTexture(int index, int field)
#endif
YUVPLANE &plane = m_buffers[index].fields[0][0];
+ YUVPLANE &planef = m_buffers[index].fields[field][0];
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, plane.id);
- g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA_OES);
+ if (field != FIELD_FULL)
+ {
+ g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA_BOB_OES);
+ GLint fieldLoc = g_Windowing.GUIShaderGetField();
+ GLint stepLoc = g_Windowing.GUIShaderGetStep();
+
+ if (field == FIELD_TOP)
+ glUniform1i(fieldLoc, 1);
+ else if(field == FIELD_BOT)
+ glUniform1i(fieldLoc, 0);
+ glUniform1f(stepLoc, 1.0f / (float)plane.texheight);
+ }
+ else
+ g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA_OES);
glUniformMatrix4fv(g_Windowing.GUIShaderGetCoord0Matrix(), 1, GL_FALSE, m_textureMatrix);
@@ -1569,10 +1607,20 @@ void CLinuxRendererGLES::RenderSurfaceTexture(int index, int field)
}
// Set texture coordinates (MediaCodec is flipped in y)
- tex[0][0] = tex[3][0] = plane.rect.x1;
- tex[0][1] = tex[1][1] = plane.rect.y2;
- tex[1][0] = tex[2][0] = plane.rect.x2;
- tex[2][1] = tex[3][1] = plane.rect.y1;
+ if (field == FIELD_FULL)
+ {
+ tex[0][0] = tex[3][0] = plane.rect.x1;
+ tex[0][1] = tex[1][1] = plane.rect.y2;
+ tex[1][0] = tex[2][0] = plane.rect.x2;
+ tex[2][1] = tex[3][1] = plane.rect.y1;
+ }
+ else
+ {
+ tex[0][0] = tex[3][0] = planef.rect.x1;
+ tex[0][1] = tex[1][1] = planef.rect.y2 * 2.0f;
+ tex[1][0] = tex[2][0] = planef.rect.x2;
+ tex[2][1] = tex[3][1] = planef.rect.y1 * 2.0f;
+ }
for(int i = 0; i < 4; i++)
{
@@ -2541,7 +2589,6 @@ bool CLinuxRendererGLES::CreateEGLIMGTexture(int index)
#ifdef HAS_LIBSTAGEFRIGHT
YV12Image &im = m_buffers[index].image;
YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[0][0];
DeleteEGLIMGTexture(index);
@@ -2551,16 +2598,23 @@ bool CLinuxRendererGLES::CreateEGLIMGTexture(int index)
im.height = m_sourceHeight;
im.width = m_sourceWidth;
- plane.texwidth = im.width;
- plane.texheight = im.height;
- plane.pixpertex_x = 1;
- plane.pixpertex_y = 1;
-
- if(m_renderMethod & RENDER_POT)
+ for (int f=0; f<3; ++f)
{
- plane.texwidth = NP2(plane.texwidth);
- plane.texheight = NP2(plane.texheight);
+ YUVPLANE &plane = fields[f][0];
+
+ plane.texwidth = im.width;
+ plane.texheight = im.height;
+ plane.pixpertex_x = 1;
+ plane.pixpertex_y = 1;
+
+ if(m_renderMethod & RENDER_POT)
+ {
+ plane.texwidth = NP2(plane.texwidth);
+ plane.texheight = NP2(plane.texheight);
+ }
}
+
+ YUVPLANE &plane = fields[0][0];
glEnable(m_textureTarget);
glGenTextures(1, &plane.id);
VerifyGLState();
@@ -2621,7 +2675,6 @@ bool CLinuxRendererGLES::CreateSurfaceTexture(int index)
{
YV12Image &im = m_buffers[index].image;
YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANE &plane = fields[0][0];
memset(&im , 0, sizeof(im));
memset(&fields, 0, sizeof(fields));
@@ -2629,15 +2682,21 @@ bool CLinuxRendererGLES::CreateSurfaceTexture(int index)
im.height = m_sourceHeight;
im.width = m_sourceWidth;
- plane.texwidth = im.width;
- plane.texheight = im.height;
- plane.pixpertex_x = 1;
- plane.pixpertex_y = 1;
-
- if(m_renderMethod & RENDER_POT)
+ for (int f=0; f<3; ++f)
{
- plane.texwidth = NP2(plane.texwidth);
- plane.texheight = NP2(plane.texheight);
+ YUVPLANE &plane = fields[f][0];
+
+ plane.texwidth = im.width;
+ plane.texheight = im.height;
+ plane.pixpertex_x = 1;
+ plane.pixpertex_y = 1;
+
+
+ if(m_renderMethod & RENDER_POT)
+ {
+ plane.texwidth = NP2(plane.texwidth);
+ plane.texheight = NP2(plane.texheight);
+ }
}
return true;
@@ -2847,9 +2906,6 @@ bool CLinuxRendererGLES::Supports(EDEINTERLACEMODE mode)
if(m_renderMethod & RENDER_OMXEGL)
return false;
- if(m_renderMethod & RENDER_EGLIMG)
- return false;
-
if(m_renderMethod & RENDER_CVREF)
return false;
@@ -2876,10 +2932,20 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method)
return false;
if(m_renderMethod & RENDER_EGLIMG)
- return false;
+ {
+ if (method == VS_INTERLACEMETHOD_RENDER_BOB || method == VS_INTERLACEMETHOD_RENDER_BOB_INVERTED)
+ return true;
+ else
+ return false;
+ }
if(m_renderMethod & RENDER_MEDIACODEC)
- return false;
+ {
+ if (method == VS_INTERLACEMETHOD_RENDER_BOB || method == VS_INTERLACEMETHOD_RENDER_BOB_INVERTED)
+ return true;
+ else
+ return false;
+ }
if(m_renderMethod & RENDER_CVREF)
return false;
@@ -2890,7 +2956,7 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method)
if(method == VS_INTERLACEMETHOD_AUTO)
return true;
-#if defined(__i386__) || defined(__x86_64__)
+#if !defined(TARGET_ANDROID) && (defined(__i386__) || defined(__x86_64__))
if(method == VS_INTERLACEMETHOD_DEINTERLACE
|| method == VS_INTERLACEMETHOD_DEINTERLACE_HALF
|| method == VS_INTERLACEMETHOD_SW_BLEND)
@@ -2933,7 +2999,10 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod()
return VS_INTERLACEMETHOD_NONE;
if(m_renderMethod & RENDER_EGLIMG)
- return VS_INTERLACEMETHOD_NONE;
+ return VS_INTERLACEMETHOD_RENDER_BOB_INVERTED;
+
+ if(m_renderMethod & RENDER_MEDIACODEC)
+ return VS_INTERLACEMETHOD_RENDER_BOB_INVERTED;
if(m_renderMethod & RENDER_CVREF)
return VS_INTERLACEMETHOD_NONE;
@@ -2941,7 +3010,7 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod()
if(m_renderMethod & RENDER_IMXMAP)
return VS_INTERLACEMETHOD_NONE;
-#if defined(__i386__) || defined(__x86_64__)
+#if !defined(TARGET_ANDROID) && (defined(__i386__) || defined(__x86_64__))
return VS_INTERLACEMETHOD_DEINTERLACE_HALF;
#else
return VS_INTERLACEMETHOD_SW_BLEND;
diff --git a/xbmc/guilib/GUIShader.cpp b/xbmc/guilib/GUIShader.cpp
index e7035565c3..a31abf4111 100644
--- a/xbmc/guilib/GUIShader.cpp
+++ b/xbmc/guilib/GUIShader.cpp
@@ -42,6 +42,8 @@ CGUIShader::CGUIShader( const char *shader ) : CGLSLShaderProgram("guishader_ver
m_hCord1 = 0;
m_hUniCol = 0;
m_hCoord0Matrix = 0;
+ m_hField = 0;
+ m_hStep = 0;
m_proj = NULL;
m_model = NULL;
@@ -54,7 +56,9 @@ void CGUIShader::OnCompiledAndLinked()
// Variables passed directly to the Fragment shader
m_hTex0 = glGetUniformLocation(ProgramHandle(), "m_samp0");
m_hTex1 = glGetUniformLocation(ProgramHandle(), "m_samp1");
- m_hUniCol = glGetUniformLocation(ProgramHandle(), "m_unicol");
+ m_hUniCol = glGetUniformLocation(ProgramHandle(), "m_unicol");
+ m_hField = glGetUniformLocation(ProgramHandle(), "m_field");
+ m_hStep = glGetUniformLocation(ProgramHandle(), "m_step");
// Variables passed directly to the Vertex shader
m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
diff --git a/xbmc/guilib/GUIShader.h b/xbmc/guilib/GUIShader.h
index f7b5d9a3df..2df6b1daf8 100644
--- a/xbmc/guilib/GUIShader.h
+++ b/xbmc/guilib/GUIShader.h
@@ -39,6 +39,8 @@ public:
GLint GetCord1Loc() { return m_hCord1; }
GLint GetUniColLoc() { return m_hUniCol; }
GLint GetCoord0MatrixLoc() { return m_hCoord0Matrix; }
+ GLint GetFieldLoc() { return m_hField; }
+ GLint GetStepLoc() { return m_hStep; }
protected:
GLint m_hTex0;
@@ -51,6 +53,8 @@ protected:
GLint m_hCord0;
GLint m_hCord1;
GLint m_hCoord0Matrix;
+ GLint m_hField;
+ GLint m_hStep;
GLfloat *m_proj;
GLfloat *m_model;
diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
index 2aeaeeccba..2270a69e7c 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.cpp
+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
@@ -43,7 +43,9 @@ static const char* ShaderNames[SM_ESHADERCOUNT] =
"guishader_frag_multi_blendcolor.glsl",
"guishader_frag_rgba.glsl",
"guishader_frag_rgba_oes.glsl",
- "guishader_frag_rgba_blendcolor.glsl"
+ "guishader_frag_rgba_blendcolor.glsl",
+ "guishader_frag_rgba_bob.glsl",
+ "guishader_frag_rgba_bob_oes.glsl"
};
CRenderSystemGLES::CRenderSystemGLES()
@@ -649,6 +651,22 @@ GLint CRenderSystemGLES::GUIShaderGetCoord0Matrix()
return -1;
}
+GLint CRenderSystemGLES::GUIShaderGetField()
+{
+ if (m_pGUIshader[m_method])
+ return m_pGUIshader[m_method]->GetFieldLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGLES::GUIShaderGetStep()
+{
+ if (m_pGUIshader[m_method])
+ return m_pGUIshader[m_method]->GetStepLoc();
+
+ return -1;
+}
+
bool CRenderSystemGLES::SupportsStereo(RENDER_STEREO_MODE mode)
{
switch(mode)
diff --git a/xbmc/rendering/gles/RenderSystemGLES.h b/xbmc/rendering/gles/RenderSystemGLES.h
index 693b30991f..e5f55c53a2 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.h
+++ b/xbmc/rendering/gles/RenderSystemGLES.h
@@ -39,6 +39,8 @@ enum ESHADERMETHOD
SM_TEXTURE_RGBA,
SM_TEXTURE_RGBA_OES,
SM_TEXTURE_RGBA_BLENDCOLOR,
+ SM_TEXTURE_RGBA_BOB,
+ SM_TEXTURE_RGBA_BOB_OES,
SM_ESHADERCOUNT
};
@@ -89,6 +91,8 @@ public:
GLint GUIShaderGetCoord1();
GLint GUIShaderGetUniCol();
GLint GUIShaderGetCoord0Matrix();
+ GLint GUIShaderGetField();
+ GLint GUIShaderGetStep();
protected:
virtual void SetVSyncImpl(bool enable) = 0;