aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/shaders/yuv2rgb_bob_gles.glsl33
-rw-r--r--xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp181
-rw-r--r--xbmc/cores/VideoRenderers/LinuxRendererGLES.h4
3 files changed, 112 insertions, 106 deletions
diff --git a/system/shaders/yuv2rgb_bob_gles.glsl b/system/shaders/yuv2rgb_bob_gles.glsl
index 292541aa77..f76b5a5ebc 100644
--- a/system/shaders/yuv2rgb_bob_gles.glsl
+++ b/system/shaders/yuv2rgb_bob_gles.glsl
@@ -18,7 +18,7 @@
*
*/
-precision mediump float;
+precision highp float;
uniform sampler2D m_sampY;
uniform sampler2D m_sampU;
uniform sampler2D m_sampV;
@@ -38,18 +38,37 @@ void main()
vec2 offsetY;
vec2 offsetU;
vec2 offsetV;
- float temp1 = mod(m_cordY.y, 2*m_stepY);
+ float temp1 = mod(m_cordY.y, 2.0*m_stepY);
offsetY = m_cordY;
offsetU = m_cordU;
offsetV = m_cordV;
- offsetY.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY);
- offsetU.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY)/2;
- offsetV.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY)/2;
+ offsetY.y -= (temp1 - m_stepY/2.0 + float(m_field)*m_stepY);
+ offsetU.y -= (temp1 - m_stepY/2.0 + float(m_field)*m_stepY)/2.0;
+ offsetV.y -= (temp1 - m_stepY/2.0 + float(m_field)*m_stepY)/2.0;
- yuv.rgba = vec4(texture2D(m_sampY, offsetY).r, texture2D(m_sampU, offsetU).r, texture2D(m_sampV, offsetV).r, 1.0);
+ float bstep = step(m_stepY, temp1);
+
+ // Blend missing line
+ vec2 belowY, belowU, belowV;
+
+ belowY.x = offsetY.x;
+ belowY.y = offsetY.y + (2.0*m_stepY*bstep);
+ belowU.x = offsetU.x;
+ belowU.y = offsetU.y + (m_stepY*bstep);
+ belowV.x = offsetV.x;
+ belowV.y = offsetV.y + (m_stepY*bstep);
+
+ vec4 yuvBelow, rgbBelow;
+
+ yuv.rgba = vec4(texture2D(m_sampY, offsetY).r, texture2D(m_sampU, offsetU).g, texture2D(m_sampV, offsetV).a, 1.0);
rgb = m_yuvmat * yuv;
rgb.a = m_alpha;
- gl_FragColor = rgb;
+
+ yuvBelow.rgba = vec4(texture2D(m_sampY, belowY).r, texture2D(m_sampU, belowU).g, texture2D(m_sampV, belowV).a, 1.0);
+ rgbBelow = m_yuvmat * yuvBelow;
+ rgbBelow.a = m_alpha;
+
+ gl_FragColor.rgba = mix(rgb, rgbBelow, 0.5);
}
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
index 1d99eca7fb..7c94afcc81 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
@@ -143,7 +143,8 @@ CLinuxRendererGLES::CLinuxRendererGLES()
m_flipindex = 0;
m_currentField = FIELD_FULL;
m_reloadShaders = 0;
- m_pYUVShader = NULL;
+ m_pYUVProgShader = NULL;
+ m_pYUVBobShader = NULL;
m_pVideoFilterShader = NULL;
m_scalingMethod = VS_SCALINGMETHOD_LINEAR;
m_scalingMethodGui = (ESCALINGMETHOD)-1;
@@ -203,12 +204,7 @@ CLinuxRendererGLES::~CLinuxRendererGLES()
m_rgbBuffer = NULL;
}
- if (m_pYUVShader)
- {
- m_pYUVShader->Free();
- delete m_pYUVShader;
- m_pYUVShader = NULL;
- }
+ ReleaseShaders();
}
bool CLinuxRendererGLES::ValidateRenderTarget()
@@ -585,14 +581,18 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (m_pYUVShader)
- m_pYUVShader->SetAlpha(alpha / 255.0f);
+ if (m_pYUVProgShader)
+ m_pYUVProgShader->SetAlpha(alpha / 255.0f);
+ if (m_pYUVBobShader)
+ m_pYUVBobShader->SetAlpha(alpha / 255.0f);
}
else
{
glDisable(GL_BLEND);
- if (m_pYUVShader)
- m_pYUVShader->SetAlpha(1.0f);
+ if (m_pYUVProgShader)
+ m_pYUVProgShader->SetAlpha(1.0f);
+ if (m_pYUVBobShader)
+ m_pYUVBobShader->SetAlpha(1.0f);
}
if ((flags & RENDER_FLAG_TOP) && (flags & RENDER_FLAG_BOT))
@@ -728,12 +728,7 @@ void CLinuxRendererGLES::LoadShaders(int field)
int requestedMethod = CSettings::Get().GetInt("videoplayer.rendermethod");
CLog::Log(LOGDEBUG, "GL: Requested render method: %d", requestedMethod);
- if (m_pYUVShader)
- {
- m_pYUVShader->Free();
- delete m_pYUVShader;
- m_pYUVShader = NULL;
- }
+ ReleaseShaders();
switch(requestedMethod)
{
@@ -786,21 +781,21 @@ void CLinuxRendererGLES::LoadShaders(int field)
// Try GLSL shaders if supported and user requested auto or GLSL.
if (glCreateProgram)
{
- // create regular progressive scan shader
- m_pYUVShader = new YUV2RGBProgressiveShader(false, m_iFlags, m_format);
+ // create regular scan shader
CLog::Log(LOGNOTICE, "GL: Selecting Single Pass YUV 2 RGB shader");
- if (m_pYUVShader && m_pYUVShader->CompileAndLink())
+ m_pYUVProgShader = new YUV2RGBProgressiveShader(false, m_iFlags, m_format);
+ m_pYUVBobShader = new YUV2RGBBobShader(false, m_iFlags, m_format);
+ if ((m_pYUVProgShader && m_pYUVProgShader->CompileAndLink())
+ && (m_pYUVBobShader && m_pYUVBobShader->CompileAndLink()))
{
m_renderMethod = RENDER_GLSL;
UpdateVideoFilter();
break;
}
- else if (m_pYUVShader)
+ else
{
- m_pYUVShader->Free();
- delete m_pYUVShader;
- m_pYUVShader = NULL;
+ ReleaseShaders();
CLog::Log(LOGERROR, "GL: Error enabling YUV2RGB GLSL shader");
// drop through and try SW
}
@@ -883,6 +878,22 @@ void CLinuxRendererGLES::LoadShaders(int field)
}
}
+void CLinuxRendererGLES::ReleaseShaders()
+{
+ if (m_pYUVProgShader)
+ {
+ m_pYUVProgShader->Free();
+ delete m_pYUVProgShader;
+ m_pYUVProgShader = NULL;
+ }
+ if (m_pYUVBobShader)
+ {
+ m_pYUVBobShader->Free();
+ delete m_pYUVBobShader;
+ m_pYUVBobShader = NULL;
+ }
+}
+
void CLinuxRendererGLES::UnInit()
{
CLog::Log(LOGDEBUG, "LinuxRendererGL: Cleaning up GL resources");
@@ -1044,7 +1055,8 @@ void CLinuxRendererGLES::RenderSinglePass(int index, int field)
{
YV12Image &im = m_buffers[index].image;
YUVFIELDS &fields = m_buffers[index].fields;
- YUVPLANES &planes = fields[field];
+ YUVPLANES &planes = fields[FIELD_FULL];
+ YUVPLANES &planesf = fields[field];
if (m_reloadShaders)
{
@@ -1072,26 +1084,32 @@ void CLinuxRendererGLES::RenderSinglePass(int index, int field)
glActiveTexture(GL_TEXTURE0);
VerifyGLState();
- m_pYUVShader->SetBlack(CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness * 0.01f - 0.5f);
- m_pYUVShader->SetContrast(CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast * 0.02f);
- m_pYUVShader->SetWidth(im.width);
- m_pYUVShader->SetHeight(im.height);
+ Shaders::BaseYUV2RGBShader *pYUVShader;
+ if (field != FIELD_FULL)
+ pYUVShader = m_pYUVBobShader;
+ else
+ pYUVShader = m_pYUVProgShader;
+
+ pYUVShader->SetBlack(CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness * 0.01f - 0.5f);
+ pYUVShader->SetContrast(CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast * 0.02f);
+ pYUVShader->SetWidth(im.width);
+ pYUVShader->SetHeight(im.height);
if (field == FIELD_TOP)
- m_pYUVShader->SetField(1);
+ pYUVShader->SetField(1);
else if(field == FIELD_BOT)
- m_pYUVShader->SetField(0);
+ pYUVShader->SetField(0);
- m_pYUVShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
- m_pYUVShader->Enable();
+ pYUVShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
+ pYUVShader->Enable();
GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
GLfloat m_vert[4][3];
GLfloat m_tex[3][4][2];
- GLint vertLoc = m_pYUVShader->GetVertexLoc();
- GLint Yloc = m_pYUVShader->GetYcoordLoc();
- GLint Uloc = m_pYUVShader->GetUcoordLoc();
- GLint Vloc = m_pYUVShader->GetVcoordLoc();
+ GLint vertLoc = pYUVShader->GetVertexLoc();
+ GLint Yloc = pYUVShader->GetYcoordLoc();
+ GLint Uloc = pYUVShader->GetUcoordLoc();
+ GLint Vloc = pYUVShader->GetVcoordLoc();
glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, 0, m_vert);
glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, 0, m_tex[0]);
@@ -1114,17 +1132,17 @@ void CLinuxRendererGLES::RenderSinglePass(int index, int field)
// Setup texture coordinates
for (int i=0; i<3; i++)
{
- m_tex[i][0][0] = m_tex[i][3][0] = planes[i].rect.x1;
- m_tex[i][0][1] = m_tex[i][1][1] = planes[i].rect.y1;
- m_tex[i][1][0] = m_tex[i][2][0] = planes[i].rect.x2;
- m_tex[i][2][1] = m_tex[i][3][1] = planes[i].rect.y2;
+ m_tex[i][0][0] = m_tex[i][3][0] = planesf[i].rect.x1;
+ m_tex[i][0][1] = m_tex[i][1][1] = planesf[i].rect.y1;
+ m_tex[i][1][0] = m_tex[i][2][0] = planesf[i].rect.x2;
+ m_tex[i][2][1] = m_tex[i][3][1] = planesf[i].rect.y2;
}
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
VerifyGLState();
- m_pYUVShader->Disable();
+ pYUVShader->Disable();
VerifyGLState();
glDisableVertexAttribArray(vertLoc);
@@ -1183,7 +1201,7 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field)
VerifyGLState();
// make sure the yuv shader is loaded and ready to go
- if (!m_pYUVShader || (!m_pYUVShader->OK()))
+ if (!m_pYUVProgShader || (!m_pYUVProgShader->OK()))
{
CLog::Log(LOGERROR, "GL: YUV shader not active, cannot do multipass render");
return;
@@ -1192,14 +1210,14 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field)
m_fbo.BeginRender();
VerifyGLState();
- m_pYUVShader->SetBlack(CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness * 0.01f - 0.5f);
- m_pYUVShader->SetContrast(CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast * 0.02f);
- m_pYUVShader->SetWidth(im.width);
- m_pYUVShader->SetHeight(im.height);
+ m_pYUVProgShader->SetBlack(CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness * 0.01f - 0.5f);
+ m_pYUVProgShader->SetContrast(CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast * 0.02f);
+ m_pYUVProgShader->SetWidth(im.width);
+ m_pYUVProgShader->SetHeight(im.height);
if (field == FIELD_TOP)
- m_pYUVShader->SetField(1);
+ m_pYUVProgShader->SetField(1);
else if(field == FIELD_BOT)
- m_pYUVShader->SetField(0);
+ m_pYUVProgShader->SetField(0);
VerifyGLState();
//TODO
@@ -1217,7 +1235,7 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field)
VerifyGLState();
- if (!m_pYUVShader->Enable())
+ if (!m_pYUVProgShader->Enable())
{
CLog::Log(LOGERROR, "GL: Error enabling YUV shader");
}
@@ -1257,7 +1275,7 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field)
// glEnd();
// VerifyGLState();
- m_pYUVShader->Disable();
+ m_pYUVProgShader->Disable();
glMatrixModview.PopLoad();
glMatrixProject.PopLoad();
@@ -1905,7 +1923,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source)
}
}
- bool deinterlacing;
+ bool deinterlacing = false;
if (m_currentField == FIELD_FULL)
deinterlacing = false;
else
@@ -1938,53 +1956,20 @@ void CLinuxRendererGLES::UploadYV12Texture(int source)
{
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 fields
- 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 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 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] );
- }
+ //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();
@@ -3015,7 +3000,7 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod()
#if !defined(TARGET_ANDROID) && (defined(__i386__) || defined(__x86_64__))
return VS_INTERLACEMETHOD_DEINTERLACE_HALF;
#else
- return VS_INTERLACEMETHOD_SW_BLEND;
+ return VS_INTERLACEMETHOD_RENDER_BOB;
#endif
}
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
index d8bf35dfda..c761d7da5b 100644
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
@@ -181,6 +181,7 @@ protected:
int NextYV12Texture();
virtual bool ValidateRenderTarget();
virtual void LoadShaders(int field=FIELD_FULL);
+ virtual void ReleaseShaders();
void SetTextureFilter(GLenum method);
void UpdateVideoFilter();
@@ -313,7 +314,8 @@ protected:
, unsigned width, unsigned height
, unsigned int stride, int bpp, void* data );
- Shaders::BaseYUV2RGBShader *m_pYUVShader;
+ Shaders::BaseYUV2RGBShader *m_pYUVProgShader;
+ Shaders::BaseYUV2RGBShader *m_pYUVBobShader;
Shaders::BaseVideoFilterShader *m_pVideoFilterShader;
ESCALINGMETHOD m_scalingMethod;
ESCALINGMETHOD m_scalingMethodGui;