diff options
author | Chris "Koying" Browet <cbro@semperpax.com> | 2015-01-06 17:13:32 +0100 |
---|---|---|
committer | Chris "koying" Browet <cbro@semperpax.com> | 2015-01-20 14:17:08 +0100 |
commit | e4e9f7a74b0f7e5ebf7ccced65778710be8bbd7d (patch) | |
tree | d97713ee5a8fbfaeef15fe46cf6bc42c84fd353e | |
parent | c0ac9c470719d97a5ac6630b94cd70ae9c60ae07 (diff) |
ADD: [gles] BOB deinterlacing
-rw-r--r-- | system/shaders/guishader_frag_rgba_bob.glsl | 47 | ||||
-rw-r--r-- | system/shaders/guishader_frag_rgba_bob_oes.glsl | 49 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 143 | ||||
-rw-r--r-- | xbmc/guilib/GUIShader.cpp | 6 | ||||
-rw-r--r-- | xbmc/guilib/GUIShader.h | 4 | ||||
-rw-r--r-- | xbmc/rendering/gles/RenderSystemGLES.cpp | 20 | ||||
-rw-r--r-- | xbmc/rendering/gles/RenderSystemGLES.h | 4 |
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; |