From: davilla Date: Thu, 17 Oct 2013 23:12:06 +0000 (-0400) Subject: gles: fixed, add missing nv12 render format X-Git-Tag: Gotham_alpha9~84 X-Git-Url: http://code.vuplus.com/gitweb/?a=commitdiff_plain;h=0b24f567b687fd715c1e6f41ce2f324c6292fda7;p=vuplus_xbmc gles: fixed, add missing nv12 render format --- diff --git a/system/shaders/yuv2rgb_basic_gles.glsl b/system/shaders/yuv2rgb_basic_gles.glsl index 963b1de..07bae91 100644 --- a/system/shaders/yuv2rgb_basic_gles.glsl +++ b/system/shaders/yuv2rgb_basic_gles.glsl @@ -28,10 +28,14 @@ varying vec2 m_cordV; uniform float m_alpha; uniform mat4 m_yuvmat; +// handles both YV12 and NV12 formats void main() { vec4 yuv, rgb; - yuv.rgba = vec4(texture2D(m_sampY, m_cordY).r, texture2D(m_sampU, m_cordU).r, texture2D(m_sampV, m_cordV).r, 1.0); + yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r + , texture2D(m_sampU, m_cordU).g + , texture2D(m_sampV, m_cordV).a + , 1.0); rgb = m_yuvmat * yuv; rgb.a = m_alpha; diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 505f194..196e460 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -569,6 +569,7 @@ unsigned int CLinuxRendererGLES::PreInit() m_NumYV12Buffers = 2; m_formats.push_back(RENDER_FMT_YUV420P); + m_formats.push_back(RENDER_FMT_NV12); m_formats.push_back(RENDER_FMT_BYPASS); #if defined(HAVE_LIBOPENMAX) m_formats.push_back(RENDER_FMT_OMXEGL); @@ -779,7 +780,12 @@ void CLinuxRendererGLES::LoadShaders(int field) m_textureCreate = &CLinuxRendererGLES::CreateSurfaceTexture; m_textureDelete = &CLinuxRendererGLES::DeleteSurfaceTexture; } - + else if (m_format == RENDER_FMT_NV12) + { + m_textureUpload = &CLinuxRendererGLES::UploadNV12Texture; + m_textureCreate = &CLinuxRendererGLES::CreateNV12Texture; + m_textureDelete = &CLinuxRendererGLES::DeleteNV12Texture; + } else { // default to YV12 texture handlers @@ -1729,7 +1735,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source) , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) , im->stride[1]*2, im->plane[1] ); - LoadPlane( fields[FIELD_TOP][2], GL_LUMINANCE, buf.flipindex + 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->plane[2] ); @@ -1738,7 +1744,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source) , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) , im->stride[1]*2, im->plane[1] + im->stride[1] ); - LoadPlane( fields[FIELD_BOT][2], GL_LUMINANCE, buf.flipindex + 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->plane[2] + im->stride[2] ); @@ -1749,7 +1755,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source) , im->width >> im->cshift_x, im->height >> im->cshift_y , im->stride[1], im->plane[1] ); - LoadPlane( fields[FIELD_FULL][2], GL_LUMINANCE, buf.flipindex + LoadPlane( fields[FIELD_FULL][2], GL_ALPHA, buf.flipindex , im->width >> im->cshift_x, im->height >> im->cshift_y , im->stride[2], im->plane[2] ); } @@ -1881,12 +1887,201 @@ bool CLinuxRendererGLES::CreateYV12Texture(int index) } else { + GLenum format; + GLint internalformat; + if (p == 2) //V plane needs an alpha texture + { + format = GL_ALPHA; + internalformat = GL_ALPHA; + } + else + { + format = GL_LUMINANCE; + internalformat = GL_LUMINANCE; + } + if(m_renderMethod & RENDER_POT) CLog::Log(LOGDEBUG, "GL: Creating YUV POT texture of size %d x %d", plane.texwidth, plane.texheight); else CLog::Log(LOGDEBUG, "GL: Creating YUV NPOT texture of size %d x %d", plane.texwidth, plane.texheight); - glTexImage2D(m_textureTarget, 0, GL_LUMINANCE, plane.texwidth, plane.texheight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(m_textureTarget, 0, internalformat, plane.texwidth, plane.texheight, 0, format, GL_UNSIGNED_BYTE, NULL); + } + + 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); + VerifyGLState(); + } + } + glDisable(m_textureTarget); + return true; +} + +//******************************************************************************************************** +// NV12 Texture loading, creation and deletion +//******************************************************************************************************** +void CLinuxRendererGLES::UploadNV12Texture(int source) +{ + YUVBUFFER& buf = m_buffers[source]; + YV12Image* im = &buf.image; + YUVFIELDS& fields = buf.fields; + + if (!(im->flags & IMAGE_FLAG_READY)) + return; + bool deinterlacing; + if (m_currentField == FIELD_FULL) + deinterlacing = false; + else + deinterlacing = true; + + glEnable(m_textureTarget); + VerifyGLState(); + + glPixelStorei(GL_UNPACK_ALIGNMENT, im->bpp); + + if (deinterlacing) + { + // Load Odd Y field + LoadPlane( fields[FIELD_TOP][0] , GL_LUMINANCE, buf.flipindex + , im->width, im->height >> 1 + , im->stride[0]*2, im->plane[0] ); + + // Load Even Y field + LoadPlane( fields[FIELD_BOT][0], GL_LUMINANCE, buf.flipindex + , im->width, im->height >> 1 + , im->stride[0]*2, im->plane[0] + im->stride[0]) ; + + // Load Odd UV Fields + LoadPlane( fields[FIELD_TOP][1], GL_LUMINANCE_ALPHA, buf.flipindex + , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) + , im->stride[1]*2, im->plane[1] ); + + // Load Even UV Fields + LoadPlane( fields[FIELD_BOT][1], GL_LUMINANCE_ALPHA, buf.flipindex + , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) + , im->stride[1]*2, im->plane[1] + im->stride[1] ); + + } + else + { + // Load Y plane + LoadPlane( fields[FIELD_FULL][0], GL_LUMINANCE, buf.flipindex + , im->width, im->height + , im->stride[0], im->plane[0] ); + + // Load UV plane + LoadPlane( fields[FIELD_FULL][1], GL_LUMINANCE_ALPHA, buf.flipindex + , im->width >> im->cshift_x, im->height >> im->cshift_y + , im->stride[1], im->plane[1] ); + } + + VerifyGLState(); + + CalculateTextureSourceRects(source, 3); + + glDisable(m_textureTarget); + return; +} + +bool CLinuxRendererGLES::CreateNV12Texture(int index) +{ + // since we also want the field textures, pitch must be texture aligned + YV12Image &im = m_buffers[index].image; + YUVFIELDS &fields = m_buffers[index].fields; + + // Delete any old texture + DeleteNV12Texture(index); + + im.height = m_sourceHeight; + im.width = m_sourceWidth; + im.cshift_x = 1; + im.cshift_y = 1; + im.bpp = 1; + + im.stride[0] = im.width; + im.stride[1] = im.width; + im.stride[2] = 0; + + im.plane[0] = NULL; + im.plane[1] = NULL; + im.plane[2] = NULL; + + // Y plane + im.planesize[0] = im.stride[0] * im.height; + // packed UV plane + im.planesize[1] = im.stride[1] * im.height / 2; + // third plane is not used + im.planesize[2] = 0; + + for (int i = 0; i < 2; i++) + im.plane[i] = new BYTE[im.planesize[i]]; + + glEnable(m_textureTarget); + for(int f = 0;f> fieldshift; + + if (m_renderMethod & RENDER_SW) + { + planes[1].texwidth = 0; + planes[1].texheight = 0; + planes[2].texwidth = 0; + planes[2].texheight = 0; + } + else + { + 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; + } + + if(m_renderMethod & RENDER_POT) + { + for(int p = 0; p < 3; p++) + { + planes[p].texwidth = NP2(planes[p].texwidth); + planes[p].texheight = NP2(planes[p].texheight); + } + } + + for(int p = 0; p < 2; p++) + { + YUVPLANE &plane = planes[p]; + if (plane.texwidth * plane.texheight == 0) + continue; + + glBindTexture(m_textureTarget, plane.id); + if (m_renderMethod & RENDER_SW) + { + glTexImage2D(m_textureTarget, 0, GL_RGBA, plane.texwidth, plane.texheight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + } + else + { + if (p == 1) + glTexImage2D(m_textureTarget, 0, GL_LUMINANCE_ALPHA, plane.texwidth, plane.texheight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); + else + glTexImage2D(m_textureTarget, 0, GL_LUMINANCE, plane.texwidth, plane.texheight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); } glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -1897,8 +2092,44 @@ bool CLinuxRendererGLES::CreateYV12Texture(int index) } } glDisable(m_textureTarget); + return true; } +void CLinuxRendererGLES::DeleteNV12Texture(int index) +{ + YV12Image &im = m_buffers[index].image; + YUVFIELDS &fields = m_buffers[index].fields; + + if( fields[FIELD_FULL][0].id == 0 ) return; + + // finish up all textures, and delete them + g_graphicsContext.BeginPaint(); //FIXME + for(int f = 0;fGetIndex(); +#endif buf.fields[0][0].id = buf.mediacodec->GetTextureID(); buf.mediacodec->UpdateTexImage(); buf.mediacodec->GetTransformMatrix(m_textureMatrix); @@ -2397,14 +2630,16 @@ void CLinuxRendererGLES::AddProcessor(CDVDMediaCodecInfo *mediacodec, int index) { #ifdef DEBUG_VERBOSE unsigned int time = XbmcThreads::SystemClockMillis(); + int mindex = -1; #endif - int mindex = -1; YUVBUFFER &buf = m_buffers[index]; if (mediacodec) { buf.mediacodec = mediacodec->Retain(); +#ifdef DEBUG_VERBOSE mindex = buf.mediacodec->GetIndex(); +#endif // releaseOutputBuffer must be in same thread as // dequeueOutputBuffer. We are in DVDPlayerVideo // thread here, so we are safe. diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h index 7742145..687b7c9 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h @@ -192,6 +192,10 @@ protected: void DeleteYV12Texture(int index); bool CreateYV12Texture(int index); + void UploadNV12Texture(int index); + void DeleteNV12Texture(int index); + bool CreateNV12Texture(int index); + void UploadCVRefTexture(int index); void DeleteCVRefTexture(int index); bool CreateCVRefTexture(int index); diff --git a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp index 48302ff..21a4ee2 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp +++ b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp @@ -228,6 +228,12 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, ERenderF m_hProj = -1; m_hModel = -1; m_hAlpha = -1; + if (m_format == RENDER_FMT_YUV420P) + m_defines += "#define XBMC_YV12\n"; + else if (m_format == RENDER_FMT_NV12) + m_defines += "#define XBMC_NV12\n"; + else + CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); VertexShader()->LoadSource("yuv2rgb_vertex_gles.glsl", m_defines); #endif