Thread: [Jahshaka-cvs] SF.net SVN: editopia:[300] cinesuite/cineplay-cinecode/trunk/src/ OpenGLStore.cpp
Status: Beta
Brought to you by:
jahshaka
From: <tim...@us...> - 2009-02-17 17:00:01
|
Revision: 300 http://editopia.svn.sourceforge.net/editopia/?rev=300&view=rev Author: timdewhirst Date: 2009-02-17 16:59:55 +0000 (Tue, 17 Feb 2009) Log Message: ----------- cinesuite * have a slow yuv420p converter Modified Paths: -------------- cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp Modified: cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp =================================================================== --- cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp 2009-02-17 16:59:20 UTC (rev 299) +++ cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp 2009-02-17 16:59:55 UTC (rev 300) @@ -159,7 +159,21 @@ void Draw( const QRect &r ); }; + class GLYuv420pSlowConvertFormat : public GLUploadFormat + { + private: + GLRgbaFormat* uf; + public: + GLYuv420pSlowConvertFormat(); + ~GLYuv420pSlowConvertFormat(); + std::wstring Pf() { return L"yuv420p"; } + bool IsSupported() { return uf->IsSupported(); } + void Init() { uf->Init(); } + void UpdateImage( const ml::image_type_ptr &image ); + void Draw( const QRect& r ) { uf->Draw( r ); } + }; + int nextPower(int val) { int pw = 1; @@ -742,7 +756,23 @@ glBindTexture( GL_TEXTURE_2D, 0 ); } + //////////////////////////////////// + GLYuv420pSlowConvertFormat::GLYuv420pSlowConvertFormat() + : uf( new GLRgbaFormat ) + {} + + GLYuv420pSlowConvertFormat::~GLYuv420pSlowConvertFormat() + { + delete uf; + } + void GLYuv420pSlowConvertFormat::UpdateImage( const ml::image_type_ptr& image ) + { + ml::image_type_ptr imageAsRgba( il::convert( image, L"r8g8b8a8" ) ); + uf->UpdateImage( imageAsRgba ); + } + + //////////////////////////////////// class GLStore::GLStorePrivate : public ml::store_type { @@ -891,6 +921,7 @@ new GLBgraFormat, new GLAbgrFormat, new GLRgbaFormat, + new GLYuv420pSlowConvertFormat, NULL }; int i=0; @@ -920,6 +951,7 @@ GLUploadFormat* formats[] = { new GLYuv420pFPFormat, new GLYuv420pSlowFormat, new GLYuv420pFormat, + new GLYuv420pSlowConvertFormat, NULL }; int i=0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tim...@us...> - 2009-11-25 16:37:56
|
Revision: 303 http://editopia.svn.sourceforge.net/editopia/?rev=303&view=rev Author: timdewhirst Date: 2009-11-25 16:37:48 +0000 (Wed, 25 Nov 2009) Log Message: ----------- cinecode * add support for yuv422p Modified Paths: -------------- cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp Modified: cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp =================================================================== --- cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp 2009-02-18 09:32:58 UTC (rev 302) +++ cinesuite/cineplay-cinecode/trunk/src/OpenGLStore.cpp 2009-11-25 16:37:48 UTC (rev 303) @@ -47,11 +47,16 @@ GLuint CreateTexture(int &inOutWidth, int &inoutHeight); void DrawTexQuad(float *verts, float *texcoords); void PillarLetterBox(float *verts, float aspect, const QRect &drawRect); - void SpliceBuffer( const unsigned char *yPixels, - const unsigned char *uPixels, - const unsigned char *vPixels, - int w, int h, - unsigned char *outbuffer ); + void SpliceBuffer420( const unsigned char *yPixels, + const unsigned char *uPixels, + const unsigned char *vPixels, + int w, int h, + unsigned char *outbuffer ); + void SpliceBuffer422( const unsigned char *yPixels, + const unsigned char *uPixels, + const unsigned char *vPixels, + int w, int h, + unsigned char *outbuffer ); private: bool m_initialised; @@ -125,7 +130,23 @@ void Draw( const QRect &r ); }; + class GLYuv422pFormat : public GLUploadFormat + { + protected: + GLuint m_tex; + GLhandleARB m_program; + unsigned char* m_uploadBuffer; + public: + GLYuv422pFormat(); + ~GLYuv422pFormat(); + std::wstring Pf() { return L"yuv422p"; } + bool IsSupported(); + void Init(); + void UpdateImage( const ml::image_type_ptr &image ); + void Draw( const QRect &r ); + }; + class GLYuv420pFPFormat : public GLUploadFormat { protected: @@ -224,11 +245,11 @@ } } - void GLUploadFormat::SpliceBuffer( const unsigned char *yPixels, - const unsigned char *uPixels, - const unsigned char *vPixels, - int w, int h, - unsigned char *outbuffer ) + void GLUploadFormat::SpliceBuffer420( const unsigned char *yPixels, + const unsigned char *uPixels, + const unsigned char *vPixels, + int w, int h, + unsigned char *outbuffer ) { //This is a yuv420 planar to yuv444 kinda translation, for the upload speed of an rgba buffer int sz = w * h; @@ -273,6 +294,33 @@ } + void GLUploadFormat::SpliceBuffer422( const unsigned char *yPixels, + const unsigned char *uPixels, + const unsigned char *vPixels, + int w, int h, + unsigned char *outbuffer ) + { + //This is a yuv422p to yuv4444 kinda translation, for the upload speed of an rgba buffer + int sz = w * h; + unsigned char *ptr = outbuffer; + + for(int y=0;y<h;++y) + { + for(int x=0; x<w; x+=2) + { + *ptr++ = *yPixels++; + *ptr++ = *uPixels; + *ptr++ = *vPixels; + *ptr++ = 0; + *ptr++ = *yPixels++; + *ptr++ = *uPixels++; + *ptr++ = *vPixels++; + *ptr++ = 0; + } + } + + } + GLuint GLUploadFormat::CreateTexture(int &width, int &height) { GLuint tex; @@ -491,7 +539,7 @@ int h = m_iHeight; glBindTexture( GL_TEXTURE_2D, m_tex ); - SpliceBuffer(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); + SpliceBuffer420(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_uploadBuffer ); } } @@ -518,7 +566,139 @@ glUseProgramObjectARB(0); } + //////////////////////////////////// + + GLYuv422pFormat::GLYuv422pFormat() + : m_tex( 0 ), + m_uploadBuffer( NULL ) + {} + + + bool GLYuv422pFormat::IsSupported() + { + return glShaderSourceARB; + } + + + void GLYuv422pFormat::Init() + { + m_program = glCreateProgramObjectARB(); + GLhandleARB fragProg = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + + GLint succ; + const GLcharARB* src = "\ + uniform sampler2D inColor0;\n\ + \n\ + const vec4 shift = vec4( 0.0625, 0.5, 0.5, 0.0 ); \n\ + \n\ + void main( void )\n\ + {\n\ + vec4 col = texture2D( inColor0, gl_TexCoord[0].xy ); \n\ + col = col - shift; \n\ + gl_FragColor.r = 1.1640625 * col.r + 1.5957 * col.b ; \n\ + gl_FragColor.g = 1.1640625 * col.r - 0.8125 * col.b - 0.390625 * col.g; \n\ + gl_FragColor.b = 1.1640625 * col.r + 2.0176 * col.g; \n\ + }";; + glShaderSourceARB( fragProg, 1, &src, 0 ); + glCompileShaderARB( fragProg ); + glGetObjectParameterivARB( fragProg, GL_OBJECT_COMPILE_STATUS_ARB, &succ ); + if(succ == 0) + { + char buffer[250]; + GLsizei length = 250; + glGetShaderInfoLog(fragProg, 250, &length, buffer); + ++length; + } + + glAttachObjectARB( m_program, fragProg ); + + glLinkProgramARB( m_program ); + glGetObjectParameterivARB( m_program, GL_OBJECT_LINK_STATUS_ARB, &succ ); + + glUseProgramObjectARB(m_program); + glUseProgramObjectARB(0); + + GLUploadFormat::Init(); + } + + + GLYuv422pFormat::~GLYuv422pFormat() + { + if ( !WasInitialised() ) + return; + + if(m_uploadBuffer) + delete[] m_uploadBuffer; + m_uploadBuffer = 0; + + if ( m_program ) + glDeleteObjectARB(m_program); + + if(m_tex) + glDeleteTextures(1, &m_tex); + } + + + void GLYuv422pFormat::UpdateImage( const ml::image_type_ptr &image ) + { + m_iWidth = image->width(); + m_iHeight = image->height(); + + if(m_iWidth > m_texWidth || m_iHeight > m_texHeight) + { + if(m_tex) + glDeleteTextures(1, &m_tex); + int w = m_iWidth; + int h = m_iHeight; + m_tex = CreateTexture(w, h); + m_texWidth = w; + m_texHeight = h; + + //software splice buffer big enough also + if(m_uploadBuffer) + delete[] m_uploadBuffer; + m_uploadBuffer = new unsigned char[w * h * 4]; + } + + unsigned char *yPixels = image->data(); + unsigned char *uPixels = image->data(1); + unsigned char *vPixels = image->data(2); + + if(yPixels) + { + int w = m_iWidth; + int h = m_iHeight; + + glBindTexture( GL_TEXTURE_2D, m_tex ); + SpliceBuffer422(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); + glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_uploadBuffer ); + } + } + + + void GLYuv422pFormat::Draw( const QRect &r ) + { + glUseProgramObjectARB(m_program); + + float aspect = (float)m_iWidth / (float)m_iHeight; + float verts[4] = {-1.0f, 1.0f, -1.0f, 1.0f}; //l,r,b,t + + PillarLetterBox(verts, aspect, r); + + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, m_tex ); + + //this should be 1/2 a texel less + float texcoords[4] = {0.0f, m_iWidth / (float)m_texWidth, 0.0f, m_iHeight / (float)m_texHeight}; + + DrawTexQuad(verts, texcoords); + + glBindTexture( GL_TEXTURE_2D, 0 ); + glUseProgramObjectARB(0); + } + + //////////////////////////////////// @@ -611,7 +791,7 @@ int h = m_iHeight; glBindTexture( GL_TEXTURE_2D, m_tex ); - SpliceBuffer(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); + SpliceBuffer420(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_uploadBuffer ); } } @@ -724,7 +904,7 @@ glLoadMatrixf(Matrix_YCbCr2RGB); glBindTexture( GL_TEXTURE_2D, m_yTex ); - SpliceBuffer(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); + SpliceBuffer420(yPixels, uPixels, vPixels, w, h, m_uploadBuffer); glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_uploadBuffer ); glPixelTransferf(GL_RED_BIAS, 0.0); @@ -918,6 +1098,7 @@ GLUploadFormat* formats[] = { new GLYuv420pFPFormat, new GLYuv420pSlowFormat, new GLYuv420pFormat, + new GLYuv422pFormat, new GLBgraFormat, new GLAbgrFormat, new GLRgbaFormat, @@ -951,6 +1132,7 @@ GLUploadFormat* formats[] = { new GLYuv420pFPFormat, new GLYuv420pSlowFormat, new GLYuv420pFormat, + new GLYuv422pFormat, new GLYuv420pSlowConvertFormat, NULL }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |