From b97852376dbf02f6a95e03a8e3b6d0ec8667c5a9 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 17 Jun 2012 22:11:20 +0200 Subject: [PATCH] First steps towards Shader MoComp, not displaying properly yet --- GNUmakefile | 2 +- glmocoshader.cc | 347 ++++++++++++++++++++++++++++++++++++++++-------- glmocoshader.h | 5 +- osdopengl.cc | 21 ++- osdopengl.h | 2 + videovpeogl.cc | 15 ++- videovpeogl.h | 2 +- 7 files changed, 325 insertions(+), 69 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 99dc70d..4e386e1 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -58,7 +58,7 @@ $(info Raspberry pi flags) LDFLAGS = -Wall LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lGLESv2 -lopenmaxil -lbcm_host -lavcodec -lavformat -lavutil -OBJECTS += main.o threadp.o osdopengl.o surfaceopengl.o ledraspberry.o mtdraspberry.o videovpeogl.o audiovpe.o wjpegsimple.o remotelinux.o glshader.o glosdshader.o glyuv400shader.o glmocoshader.o +OBJECTS += main.o threadp.o osdopengl.o surfaceopengl.o ledraspberry.o mtdraspberry.o videovpeogl.o audiovpe.o wjpegsimple.o remotelinux.o glshader.o glosdshader.o glyuv400shader.o glyuv444shader.o glmocoshader.o LIBS+= -ljpeg CROSSLIBS = INCLUDES = -DVOMP_PLATTFORM_RASPBERRY -I/opt/vc/include diff --git a/glmocoshader.cc b/glmocoshader.cc index 3f29910..22c0eb2 100755 --- a/glmocoshader.cc +++ b/glmocoshader.cc @@ -20,50 +20,142 @@ #include "glmocoshader.h" #include "videovpeogl.h" +#define BLOCK_TEXTURE_WIDTH 2048 +#define BLOCK_TEXTURE_HEIGHT 1024 +#define BLOCK_SIZE 64 +#define BLOCK_PER_ROW 32 + const GLchar moco_vertex_shader[] = - "attribute vec4 vec_pos;\n" - "attribute vec2 tex_coord;\n" - "varying vec2 out_texCoord;\n" + "attribute vec4 block_pos;\n" + "attribute vec2 block_edge;\n" + "attribute vec4 block_types;\n" + "attribute vec2 index;\n" + "attribute float cbp;\n" + "uniform vec2 pict_scale;\n" + // "attribute vec2 tex_coord;\n" + "varying vec4 out_yblockpos_x;\n" + "varying vec4 out_yblockpos_y;\n" + "varying vec4 out_uvblockpos_xy;\n" + "varying vec2 out_block_edge;\n" + + "const float one=1.0;\n" + "const float c1024=1024.0;\n" + "const float c32=32.0;\n" + + + "const float c65536=65536.;\n" + + + + "const vec4 y_cbp=vec4(1.0,2.0,4.0,8.0);\n" + "const vec2 uv_cbp=vec2(16.0,32.0);\n" "void main()\n" "{\n" - " gl_Position=vec_pos;\n" - " out_texCoord=tex_coord;\n" + // calculate cbp + " vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n" + " vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n" + " vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n" + " fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n" + " fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n" + // resulting vector should indicate with block is present + // now transform it to a sum (TODO vectorize this) + " vec4 fmod_cbp_y2=fmod_cbp_y;\n" + " vec2 fmod_cbp_uv2=fmod_cbp_uv;\n" + " fmod_cbp_y2.y+=fmod_cbp_y2.x;\n" + " fmod_cbp_y2.z+=fmod_cbp_y2.y;\n" + " fmod_cbp_y2.w+=fmod_cbp_y2.z;\n" + " fmod_cbp_uv2.x+=fmod_cbp_y2.w;\n" + " fmod_cbp_uv2.y+=fmod_cbp_uv2.x;\n" + + // now calculate their position inside the short array + " float m_index=index.x+index.y*c65536;\n" //Not Endian save + " fmod_cbp_y2+=m_index;\n" //shift to the blocks + " fmod_cbp_uv2+=m_index;\n" + " out_yblockpos_x=mod(fmod_cbp_y2,c32);\n" + " out_uvblockpos_xy.xy=mod(fmod_cbp_uv2,c32);\n" + " out_yblockpos_y=floor((fmod_cbp_y2)/c32);\n" + " out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)/c32);\n" + + //Kick out uncoded blocks + " out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n" + " out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n" + + + " out_block_edge=block_edge;\n" + " vec4 out_pos=block_pos;\n" + " out_pos.xy+=block_edge;\n" + " out_pos.xy*=pict_scale;\n" + " out_pos.xy-=vec2(one,one);" + " out_pos.zw=vec2(one,one);" + " gl_Position=out_pos;\n" "}\n"; const GLchar moco_frag_shader[] = "precision mediump float;\n" - "uniform sampler2D textureU;\n" - "uniform sampler2D textureV;\n" - "uniform sampler2D textureY;\n" - "const float uv_corr=0.5;\n" - "const float y_corr=0.0625;\n" - "const mat3 yuvtransform= mat3( 1.164 ,0.0 ,1.596 ,\n" - " 1.164 ,-0.391,-0.813 ,\n" - " 1.164,2.018 , 0.0 );\n" -// "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n" -// " 0.0 ,-0.3960,2.029 ,\n" -// " 1.140,-0.581 , 0.0 );\n" -// "const mat3 yuvtransform= mat3( 1. ,0 ,0. ,\n" -// " 0.0 ,1.,0. ,\n" -// " 0.,0. , 1.0 );\n" -// "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n" -// " 0.0 ,-0.03960,0.2029 ,\n" -// " 0.1140,-0.0581 , 0.0 );\n" - "varying vec2 out_texCoord;\n" + "uniform sampler2D blocks;\n" + "varying vec4 out_yblockpos_x;\n" + "varying vec4 out_yblockpos_y;\n" + "varying vec4 out_uvblockpos_xy;\n" + "varying vec2 out_block_edge;\n" + "const float halfst=0.5;\n" + "const float ctwo=2.0;\n" + "const float sieben=7.0;\n" + "const float acht=8.0;\n" + "const float s8=1./8.;\n" + "const float s16=1./16.;\n" + "const float c1over2047=1./2047.;\n" + "const float c1over1023=1./1023.;\n" + "const float c255=255.;\n" + "const float c65280=65280.;\n" + "const float c65536=65536.;\n" + "const float cstep=32767.;\n" + "\n" + "float unpack_short(vec2 income) {\n" + " float temp=income.y*c65280+income.x*c255;\n" + " temp-=step(cstep,temp)*c65536;\n" + " return abs(temp/c255);\n" //temporary work around + "}" + // "uniform sampler2D textureV;\n" + // "uniform sampler2D textureY;\n" +// "varying vec2 out_texCoord;\n" "void main()\n" "{\n" - " vec3 help;\n" - "help.x=texture2D(textureY,out_texCoord).r-y_corr;\n" - "help.y=texture2D(textureU,out_texCoord).r-uv_corr;\n" - "help.z=texture2D(textureV,out_texCoord).r-uv_corr;\n" //-uv_corr;\n" - " gl_FragColor.rgb=help*yuvtransform;\n" - " gl_FragColor.a=1.;\n" + // first figure out the block num for y, first decide between up and down, fix me field + //non field code + // " vec4 ypos_temp1=mix(vec4(out_yblockpos_x.x,out_yblockpos_y.x,out_yblockpos_x.y,out_yblockpos_y.y)," + // " vec4(out_yblockpos_x.z,out_yblockpos_y.z,out_yblockpos_x.w,out_yblockpos_y.w),step(halfst,out_block_edge.y));\n" + //field code + " vec4 ypos_temp1=mix(vec4(out_yblockpos_x.x,out_yblockpos_y.x,out_yblockpos_x.y,out_yblockpos_y.y)," + " vec4(out_yblockpos_x.z,out_yblockpos_y.z,out_yblockpos_x.w,out_yblockpos_y.w),step(s16,mod(out_block_edge.y,s8)));\n" + + //decide between left and right + " vec2 ypos_temp2=mix(ypos_temp1.xy,ypos_temp1.zw,step(halfst,out_block_edge.x));\n" + //now get the intra 8x8 Block coordinates + " vec2 ypos_temp3=mod(out_block_edge,halfst)*ctwo;\n" + " ypos_temp2.x=(ypos_temp3.x*sieben+(ypos_temp3.y*sieben+acht*ypos_temp2.x)*acht)*c1over2047;\n" + " ypos_temp2.y*=c1over1023;\n" + " ypos_temp1=texture2D(blocks,ypos_temp2);\n" // now select the right data + " ypos_temp2=mix(ypos_temp1.rg,ypos_temp1.ba,step(c1over2047,mod(ypos_temp2.x,c1over1023)));\n" //activate this + + " gl_FragColor.r=unpack_short(ypos_temp2.rg);\n" //signed later TODO + //" gl_FragColor.r=ypos_temp1.b;\n" //signed later TODO + " gl_FragColor.g=0.5;\n" + " gl_FragColor.b=0.5;\n" + " gl_FragColor.a=1.0;\n" + //" vec4 blocks=texture2D(blocks,gl_FragCoord.xy/600.);\n" +// "help.x=texture2D(textureY,out_texCoord).r;\n" +// "help.y=texture2D(textureU,out_texCoord).r;\n" +// "help.z=texture2D(textureV,out_texCoord).r;\n" //-uv_corr;\n" + // " gl_FragColor.rgba=blocks;\n" + // " gl_FragColor.rgba=vec4(0.7,0.5,0.5,1.0);\n" + //" gl_FragColor.a=1.;\n" "}\n"; -GLMocoShader::GLMocoShader(): GLShader("GLYuv400Shader") +GLMocoShader::GLMocoShader(): GLShader("GLMocoShader") { frame_buf=0; + blocks_loc=0; } GLMocoShader::~GLMocoShader() @@ -72,19 +164,32 @@ GLMocoShader::~GLMocoShader() } int GLMocoShader::init() { + if (!initShaders(moco_vertex_shader, moco_frag_shader)) { + Log::getInstance()->log("GLMocoShader", Log::ERR, "init Shaders failed for GLMocoShader"); return 0; } + loc_pict_scale = glGetUniformLocation(shad_program, "pict_scale"); + blocks_loc = glGetUniformLocation(shad_program, "blocks"); + // frame_sampler_locY = glGetUniformLocation(shad_program, "textureY"); // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError()); // frame_sampler_locU = glGetUniformLocation(shad_program, "textureU"); //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError()); // frame_sampler_locV = glGetUniformLocation(shad_program, "textureV"); glGenFramebuffers(1, &frame_buf); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "genframe bufmark1 glerror %x",glGetError()); glGenTextures(1, &data_blocks); glBindTexture(GL_TEXTURE_2D, data_blocks); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1024, 1024, 0, GL_LUMINANCE_ALPHA, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BLOCK_TEXTURE_WIDTH >>1, BLOCK_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + char buffer[BLOCK_TEXTURE_WIDTH*4]; + memset(buffer,0,BLOCK_TEXTURE_WIDTH*4); // the last line is black, simplifies the shader algorithms + + glTexSubImage2D(GL_TEXTURE_2D,0,0,BLOCK_TEXTURE_HEIGHT-1, + 1024,1, + GL_RGBA,GL_UNSIGNED_BYTE, + buffer); glGenBuffers(1,¯o_block); glBindBuffer(GL_ARRAY_BUFFER,macro_block); @@ -101,19 +206,24 @@ int GLMocoShader::init() { } GLushort *tri_indices_run=tri_indices; for (int i=0;i<4096;i++) { - *tri_indices_run=i+2*4096; //strip - tri_indices_run++; *tri_indices_run=i+0*4096; //strip tri_indices_run++; - *tri_indices_run=i+3*4096; //strip + *tri_indices_run=i+2*4096; //strip tri_indices_run++; *tri_indices_run=i+1*4096; //strip tri_indices_run++; - *tri_indices_run=i+1*4096; //strip + *tri_indices_run=i+3*4096; //strip + tri_indices_run++; + *tri_indices_run=i+3*4096; //strip tri_indices_run++; - *tri_indices_run=i+1+2*4096; //strip + *tri_indices_run=i+1+0*4096; //strip tri_indices_run++; } + + + + + glBufferData(GL_ELEMENT_ARRAY_BUFFER,4096*6*sizeof(GLushort),tri_indices,GL_STREAM_DRAW); free(tri_indices); @@ -129,59 +239,93 @@ int GLMocoShader::init() { int GLMocoShader::deinit() { glDeleteFramebuffers(1, &frame_buf); - glDeleteTextures(1, &frame_buf); + glDeleteTextures(1, &data_blocks); return deinitShaders(); } + + int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMacroBlock *m_blocks,unsigned int num_m_blocks) { - unsigned int height=(num_blocks+127)/128; + unsigned int height=(num_blocks)/(BLOCK_PER_ROW); glBindTexture(GL_TEXTURE_2D, data_blocks); glPixelStorei(GL_UNPACK_ALIGNMENT,1); + + + + Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 glerror %x %d",glGetError(),height); glTexSubImage2D(GL_TEXTURE_2D,0,0,0, - 1024,height, - GL_LUMINANCE,GL_UNSIGNED_BYTE, + BLOCK_TEXTURE_WIDTH>>1,height, + GL_RGBA,GL_UNSIGNED_BYTE, blocks); - //Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError()); + Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError()); + glTexSubImage2D(GL_TEXTURE_2D,0,0,height+1, + (num_blocks%BLOCK_PER_ROW)>>1,1, + GL_RGBA,GL_UNSIGNED_BYTE, + blocks); + + Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError()); + + + + glBindTexture(GL_TEXTURE_2D, 0); valid_macro_blocks=num_m_blocks; glBindBuffer(GL_ARRAY_BUFFER,macro_block); XvMCMacroBlock *m_blocks_run=m_blocks; XvMCMacroBlock *m_blocks_end=m_blocks+num_m_blocks; while (m_blocks_run!=m_blocks_end) { - m_blocks_run->pad0=0x0000; + m_blocks_run->pad0=0xFF00; m_blocks_run++; } - glBufferSubData(GL_ARRAY_BUFFER, 0, num_m_blocks * sizeof(XvMCMacroBlock), + // debug +/* m_blocks[0].x=0; + m_blocks[0].y=0; + m_blocks[3]=m_blocks[2]=m_blocks[1]=m_blocks[0]; + m_blocks[0].pad0=0xFF00; + m_blocks[1].pad0=0xFFFF; + m_blocks[2].pad0=0x0000; + m_blocks[3].pad0=0x00FF; + m_blocks[1].x=0; + m_blocks[1].y=0; + m_blocks[2].x=0; + m_blocks[2].y=0; + m_blocks[3].x=0; + m_blocks[3].y=0;*/ + + glBufferSubData(GL_ARRAY_BUFFER, 0* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock), m_blocks); + m_blocks_run = m_blocks; m_blocks_end = m_blocks + num_m_blocks; while (m_blocks_run != m_blocks_end) { - m_blocks_run->pad0 = 0x00FF; + m_blocks_run->pad0 = 0xFFFF; m_blocks_run++; } - glBufferSubData(GL_ARRAY_BUFFER, 4096, num_m_blocks * sizeof(XvMCMacroBlock), + glBufferSubData(GL_ARRAY_BUFFER, 4096* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock), m_blocks); + m_blocks_run = m_blocks; m_blocks_end = m_blocks + num_m_blocks; while (m_blocks_run != m_blocks_end) { - m_blocks_run->pad0 = 0xFF00; + m_blocks_run->pad0 = 0x0000; m_blocks_run++; } - glBufferSubData(GL_ARRAY_BUFFER, 2 * 4096, + glBufferSubData(GL_ARRAY_BUFFER, 2 * 4096* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock), m_blocks); + m_blocks_run = m_blocks; m_blocks_end = m_blocks + num_m_blocks; while (m_blocks_run != m_blocks_end) { - m_blocks_run->pad0 = 0xFFFF; + m_blocks_run->pad0 = 0x00FF; m_blocks_run++; } - glBufferSubData(GL_ARRAY_BUFFER, 3 * 4096, + glBufferSubData(GL_ARRAY_BUFFER, 3 * 4096* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock), m_blocks); @@ -193,29 +337,116 @@ int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMa } -int GLMocoShader::doMoCo(VPEOGLFrame *target, VPE_FrameBuf* source) +int GLMocoShader::doMoCo(VPEOGLFrame *target) { +// Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-2 glerror %x %x",glGetError(),frame_buf); + + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-1 glerror %x %x",glGetError(),frame_buf); glBindFramebuffer(GL_FRAMEBUFFER, frame_buf); - Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x",glGetError()); + Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x %x %x",glGetError(),target->textures[0],target->textures[1]); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target->textures[0], 0); - Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError()); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1apres glerror %x",glGetError()); + + + + + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError()); + + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2a glerror %x",glGetError()); int status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status == GL_FRAMEBUFFER_COMPLETE) { + glViewport(0, 0, target->width,target->height); + // Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2b glerror %x",glGetError()); + + XvMCMacroBlock * helperp=NULL; + + glClearColor(0.0f,0.5f,0.5f,1.f); //this black + glClear(GL_COLOR_BUFFER_BIT); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2c glerror %x",glGetError()); + glUseProgram(shad_program); - Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError()); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError()); + + + const GLfloat pict_scale[]={ 32./((float)target->width),32./((float)target->height)}; + + glUniform2fv(loc_pict_scale,1,(const GLfloat*)&pict_scale); + + + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark5 glerror %x",glGetError()); + glBindBuffer(GL_ARRAY_BUFFER,macro_block); + + glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE, + sizeof(XvMCMacroBlock), NULL); + + glEnableVertexAttribArray(0); + + glVertexAttribPointer(1, 2, GL_UNSIGNED_BYTE, GL_TRUE,sizeof(XvMCMacroBlock), (const void *) &(helperp->pad0)); + glEnableVertexAttribArray(1); + + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->macroblock_type)); + glEnableVertexAttribArray(2); + + glVertexAttribPointer(3, 1, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->coded_block_pattern)); + glEnableVertexAttribArray(3); + glVertexAttribPointer(4, 2, GL_UNSIGNED_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->index)); + glEnableVertexAttribArray(4); + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,data_blocks); + glUniform1i(blocks_loc,0); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); + + glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6, + GL_UNSIGNED_SHORT, NULL); + + + /* + glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), 0); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError()); + glEnableVertexAttribArray(0); + + glVertexAttribPointer(1, 2, GL_UNSIGNED_BYTE, GL_TRUE,sizeof(XvMCMacroBlock), (const void *) &(helperp->pad0)); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError()); + glEnableVertexAttribArray(1);*/ + + // Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark4 glerror %x",glGetError()); + + + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark6 glerror %x",glGetError()); + + // glDrawElements(GL_TRIANGLE_STRIP,/*valid_macro_blocks*/4,GL_UNSIGNED_SHORT,0); + Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark7 glerror %x %x",glGetError(),valid_macro_blocks); + //cleanup + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark5 glerror %x",glGetError()); glBindBuffer(GL_ARRAY_BUFFER,0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark8 glerror %x",glGetError()); } else { glBindFramebuffer(GL_FRAMEBUFFER, 0); - Log::getInstance()->log("GLMocoShader", Log::WARN, "framebuffer not complete"); + Log::getInstance()->log("GLMocoShader", Log::WARN, "framebuffer not complete %x",status); return -1; } + + glFinish(); // since the main rendering is done in a different thread we have to make sure rendering is finished before passing the texture + // call this only in the last stage of rendering the moco frame return 0; @@ -255,7 +486,11 @@ int GLMocoShader::PrepareRendering(GLuint y_tex, GLuint u_tex, GLuint v_tex) { / int GLMocoShader::BindAttributes() { - glBindAttribLocation(shad_program,0,"vec_pos"); - glBindAttribLocation(shad_program,1,"tex_coord"); + glBindAttribLocation(shad_program,0,"block_pos"); + glBindAttribLocation(shad_program,1,"block_edge"); + glBindAttribLocation(shad_program,2,"block_types"); + glBindAttribLocation(shad_program,3,"cbp"); + glBindAttribLocation(shad_program,4,"index"); + //glBindAttribLocation(shad_program,1,"tex_coord"); return 1; } diff --git a/glmocoshader.h b/glmocoshader.h index 51ed2c7..b37262b 100755 --- a/glmocoshader.h +++ b/glmocoshader.h @@ -38,7 +38,7 @@ public: int uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMacroBlock *m_blocks,unsigned int num_m_blocks); - int doMoCo(VPEOGLFrame *target, VPE_FrameBuf* source); + int doMoCo(VPEOGLFrame *target); protected: virtual int BindAttributes(); @@ -46,9 +46,12 @@ protected: GLuint data_blocks; GLuint triangles; GLuint macro_block; + GLint loc_pict_scale; + GLint blocks_loc; unsigned int valid_macro_blocks; + }; diff --git a/osdopengl.cc b/osdopengl.cc index 1547caf..4784aef 100755 --- a/osdopengl.cc +++ b/osdopengl.cc @@ -125,7 +125,7 @@ int OsdOpenGL::init(void* device) EGLint number; if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %d",eglGetError()); + Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %x",eglGetError()); glmutex.Unlock(); return 0; } @@ -137,7 +137,7 @@ int OsdOpenGL::init(void* device) egl_context=eglCreateContext(egl_display,egl_ourconfig,EGL_NO_CONTEXT,attr_context); if (egl_context==EGL_NO_CONTEXT) { - Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %d",eglGetError()); + Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %x",eglGetError()); glmutex.Unlock(); return 0; } @@ -225,6 +225,12 @@ int OsdOpenGL::init(void* device) return 0; } + if (!yuv444_shader.init()) { + Log::getInstance()->log("OSD", Log::WARN, "Init Yuv444 Shader failed"); + glmutex.Unlock(); + return 0; + } + /* gen_shader=CreateShader(generic_vertex_shader, GL_VERTEX_SHADER); osd_shader=CreateShader(osd_frag_shader, GL_FRAGMENT_SHADER); @@ -380,6 +386,7 @@ int OsdOpenGL::shutdown() osd_shader.deinit(); yuv400_shader.deinit(); + yuv444_shader.deinit(); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(egl_display, egl_surface); @@ -413,6 +420,7 @@ void OsdOpenGL::threadMethod() if (!frame) frame=video->getReadyOGLFrame(); if (frame) { InternalRendering(frame); + MILLISLEEP(1500); lastrendertime=getTimeMS(); video->returnOGLFrame(frame); //please recycle it frame=NULL; @@ -566,6 +574,7 @@ void OsdOpenGL::InternalRendering(VPEOGLFrame* frame){ glViewport(0, 0, display_width,display_height); + glClearColor(0.0f,0.0f,0.0f,1.f); glClear(GL_COLOR_BUFFER_BIT); @@ -605,7 +614,13 @@ void OsdOpenGL::InternalRendering(VPEOGLFrame* frame){ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);*/ - yuv400_shader.PrepareRendering(frame->textures[0],frame->textures[1],frame->textures[2]); + switch (frame->type) { + case 1: + yuv400_shader.PrepareRendering(frame->textures[0],frame->textures[1],frame->textures[2]);break; + case 2: + yuv444_shader.PrepareRendering(frame->textures[0]);break; + } + diff --git a/osdopengl.h b/osdopengl.h index 5b354e1..75288f2 100755 --- a/osdopengl.h +++ b/osdopengl.h @@ -38,6 +38,7 @@ #include "glosdshader.h" #include "glyuv400shader.h" +#include "glyuv444shader.h" @@ -141,6 +142,7 @@ private: GLint osd_sampler_loc;*/ GLOsdShader osd_shader; GLYuv400Shader yuv400_shader; + GLYuv444Shader yuv444_shader; diff --git a/videovpeogl.cc b/videovpeogl.cc index 8b90009..3a8ea28 100755 --- a/videovpeogl.cc +++ b/videovpeogl.cc @@ -113,7 +113,7 @@ int VideoVPEOGL::initUsingOSDObjects() egl_display=i_egl_display; egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context); if (egl_context==EGL_NO_CONTEXT) { - Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %d",eglGetError()); + Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError()); return 0; } // We create a dummy surface here, in order to allow two contexts @@ -123,7 +123,7 @@ int VideoVPEOGL::initUsingOSDObjects() }; egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer); if (egl_surface==EGL_NO_SURFACE) { - Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %d",eglGetError()); + Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError()); return 0; } @@ -271,13 +271,13 @@ int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int he return 1; } -int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride) +int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height) { Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444"); // Y glGenTextures(1, &outframe->textures[0]); glBindTexture(GL_TEXTURE_2D, outframe->textures[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, stride, height, 0, GL_RGBA, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); outframe->textures[1]=outframe->textures[2]=0; // no handles here @@ -287,7 +287,7 @@ int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int he outframe->type=2; outframe->height=height; outframe->width=width; - outframe->stride=stride; + outframe->stride=width; // does not make any sense otherwiese return 1; } @@ -369,7 +369,7 @@ void VideoVPEOGL::threadMethod() if (decoding_mode==VPE_NO_XVMC) { if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true; }else { - if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true; //We use a YUV 444 texture in this case + if (!AllocateYUV444OglTexture(out_frame,width,height)) failed=true; //We use a YUV 444 texture in this case // the shaders are easier to implement } } @@ -411,6 +411,7 @@ void VideoVPEOGL::threadMethod() } else { //DCT Blocks upload } + moco_shader->doMoCo(out_frame); // Excute motion compensation } @@ -1528,7 +1529,7 @@ int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic) pix_xvmc->allocated_data_blocks=num_dct_blocks; if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1; else pix_xvmc->idct=0; - pix_xvmc->unsigned_intra=0; // let see what happens + pix_xvmc->unsigned_intra=1; // let see what happens pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num; pix_xvmc->start_mv_blocks_num=0; pix_xvmc->filled_mv_blocks_num=0; diff --git a/videovpeogl.h b/videovpeogl.h index 95620e8..c098762 100755 --- a/videovpeogl.h +++ b/videovpeogl.h @@ -316,7 +316,7 @@ class VideoVPEOGL : public Video, public Thread_TYPE Mutex ogl_frame_mutex; int AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride); - int AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride); + int AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height); virtual void threadMethod(); virtual void threadPostStopCleanup(); -- 2.39.2