]> git.vomp.tv Git - vompclient-marten.git/blob - glmocoshader.cc
Add handling reference frame pointers
[vompclient-marten.git] / glmocoshader.cc
1 /*\r
2     Copyright 2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 #include "glmocoshader.h"\r
21 #include "videovpeogl.h"\r
22 \r
23 #define BLOCK_TEXTURE_WIDTH 2048\r
24 #define BLOCK_TEXTURE_HEIGHT 1024\r
25 #define BLOCK_SIZE 64\r
26 #define BLOCK_PER_ROW 32\r
27 \r
28 const GLchar moco_vertex_shader[] =\r
29                 "attribute vec4 block_pos;\n"\r
30                 "attribute vec2 block_edge;\n"\r
31                 "attribute vec4 block_types;\n"\r
32                 "attribute vec2 index;\n"\r
33                 "attribute float cbp;\n"\r
34                 "uniform vec2 pict_scale;\n"\r
35         //      "attribute vec2 tex_coord;\n"\r
36                 "varying vec4 out_yblockpos_x;\n"\r
37                 "varying vec4 out_yblockpos_y;\n"\r
38                 "varying vec4 out_uvblockpos_xy;\n"\r
39                 "varying vec2 out_block_edge;\n"\r
40                 "varying vec4 out_block_types;\n"\r
41 \r
42                 "varying float out_unsupported;\n"\r
43 \r
44                 "const float one=1.0;\n"\r
45                 "const float c1024=1024.0;\n"\r
46                 "const float c32=32.0;\n"\r
47         //      "const float c1over32=0.03125;\n"\r
48                 "const float c1over32=1./32.;\n"\r
49 \r
50 \r
51                 "const float c65536=65536.;\n"\r
52 \r
53 \r
54 \r
55                 "const vec4  y_cbp=vec4(1.0,2.0,4.0,8.0);\n"\r
56                 "const vec2  uv_cbp=vec2(16.0,32.0);\n"\r
57                 "void main()\n"\r
58                 "{\n"\r
59                 // calculate cbp\r
60                 "  vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n"\r
61                 "  vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n"\r
62                 "  vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n"\r
63                 "  fmod_cbp_y.x=0.;\n"\r
64                 "  fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n"\r
65                 "  fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n"\r
66                 // resulting vector should indicate with block is present\r
67                 // now transform it to a sum (TODO vectorize this)\r
68                 "  vec4 fmod_cbp_y2=fmod_cbp_y;\n"\r
69                 "  vec2 fmod_cbp_uv2=fmod_cbp_uv;\n"\r
70                 "  fmod_cbp_y2.y+=fmod_cbp_y2.x;\n"\r
71                 "  fmod_cbp_y2.z+=fmod_cbp_y2.y;\n"\r
72                 "  fmod_cbp_y2.w+=fmod_cbp_y2.z;\n"\r
73                 "  fmod_cbp_uv2.x+=fmod_cbp_y2.w;\n"\r
74                 "  fmod_cbp_uv2.y+=fmod_cbp_uv2.x;\n"\r
75 \r
76                 // now calculate their position inside the short array\r
77                 "  float m_index=index.x/*+index.y*c65536*/-one;\n" //Not Endian save\r
78                 "  fmod_cbp_y2+=m_index;\n" //shift to the blocks\r
79                 "  fmod_cbp_uv2+=m_index;\n"\r
80                 //"  out_yblockpos_x=(mod(fmod_cbp_y2,c32));\n"\r
81             //"  out_uvblockpos_xy.xy=(mod(fmod_cbp_uv2,c32));\n"\r
82                 //"  out_yblockpos_y=floor((fmod_cbp_y2)/c32);\n"\r
83                 //"  out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)/c32);\n"\r
84 \r
85                 "  out_yblockpos_y=floor((fmod_cbp_y2)*c1over32);\n"\r
86                 "  out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)*c1over32);\n"\r
87                 "  out_yblockpos_x=fmod_cbp_y2-c32*out_yblockpos_y;\n"\r
88             "  out_uvblockpos_xy.xy=fmod_cbp_uv2-c32*out_uvblockpos_xy.zw;\n"\r
89 \r
90 \r
91 \r
92                 //Kick out uncoded blocks\r
93                 "  out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n"\r
94                 "  out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n"\r
95 \r
96         //      " if (block_types.y!=0.) {\n"\r
97         //      "  out_unsupported=1.;\n"\r
98         //      "} else {\n"\r
99         //      "  out_unsupported=0.;\n"\r
100         //      "}\n"\r
101 \r
102 \r
103                 "  out_block_edge=block_edge;\n"\r
104                 "  out_block_types=block_types;\n"\r
105                 "  vec4 out_pos=block_pos;\n"\r
106                 "  out_pos.xy+=block_edge;\n"\r
107                 "  out_pos.xy*=pict_scale;\n"\r
108                 "  out_pos.xy-=vec2(one,one);"\r
109                 "  out_pos.zw=vec2(one,one);"\r
110                 " gl_Position=out_pos;\n"\r
111                 "}\n";\r
112 \r
113 const GLchar moco_frag_shader[] =\r
114                 "precision mediump float;\n"\r
115                 "uniform sampler2D blocks;\n"\r
116                 "uniform sampler2D forward_pic;\n"\r
117                 "uniform sampler2D backward_pic;\n"\r
118                 "varying vec4 out_yblockpos_x;\n"\r
119                 "varying vec4 out_yblockpos_y;\n"\r
120                 "varying vec4 out_uvblockpos_xy;\n"\r
121                 "varying vec2 out_block_edge;\n"\r
122                 "varying vec4 out_block_types;\n" // change this we need so far only the dct type\r
123                 "varying float out_unsupported;\n"\r
124 \r
125                 "const float halfst=0.5;\n"\r
126                 "const float ctwo=2.0;\n"\r
127                 "const float cone=1.0;\n"\r
128                 "const float sieben=7.0;\n"\r
129                 "const float acht=8.0;\n"\r
130                 "const float s8=1./8.;\n"\r
131                 "const float s16=1./16.;\n"\r
132                 "const float c1over2048=1./2048.;\n"\r
133                 "const float c1over1024=1./1024.;\n"\r
134                 "const float c255=255.;\n"\r
135                 "const float c65280=65280.;\n"\r
136                 "const float c65536=65536.;\n"\r
137                 "const float cstep=32767.;\n"\r
138                 "\n"\r
139                 "float unpack_short(vec2 income) {\n"\r
140                 "   float temp=income.y*c65280+income.x*c255;\n"\r
141                 "   temp-=step(cstep,temp)*c65536;\n"\r
142                 "   return abs(temp/c255);\n" //temporary work around\r
143                 "}"\r
144         //      "uniform sampler2D textureV;\n"\r
145         //      "uniform sampler2D textureY;\n"\r
146 //              "varying vec2 out_texCoord;\n"\r
147                 "void main()\n"\r
148                 "{\n"\r
149                 // first figure out the block num for y, first decide between up and down, fix me field\r
150         //non field code\r
151                 " vec4 ypos_temp1;\n"\r
152                 " bool upper_half;\n"\r
153                 " float line_step;\n"\r
154                 " if (out_block_types.w!=0.) {\n" //test the dct type\r
155                 "  upper_half=mod(floor(out_block_edge.y*acht),ctwo)==cone;\n"\r
156                 "  line_step=cone;\n"\r
157                 "}else{\n"\r
158                 "  upper_half=halfst<out_block_edge.y;\n"\r
159                 "  line_step=ctwo;\n"\r
160                 "}\n"\r
161                 " if (upper_half) {\n"\r
162                 "  ypos_temp1=vec4(out_yblockpos_x.z,out_yblockpos_y.z,out_yblockpos_x.w,out_yblockpos_y.w);\n"\r
163                 "  } else {\n"\r
164                 "    ypos_temp1=vec4(out_yblockpos_x.x,out_yblockpos_y.x,out_yblockpos_x.y,out_yblockpos_y.y);\n"\r
165                 " }\n"\r
166     //  " vec4 ypos_temp1=mix(vec4(out_yblockpos_x.x,out_yblockpos_y.x,out_yblockpos_x.y,out_yblockpos_y.y),"\r
167         //      "                  vec4(out_yblockpos_x.z,out_yblockpos_y.z,out_yblockpos_x.w,out_yblockpos_y.w),step(halfst,out_block_edge.y));\n"\r
168                 //field code\r
169         //      " vec4 ypos_temp1=mix(vec4(out_yblockpos_x.x,out_yblockpos_y.x,out_yblockpos_x.y,out_yblockpos_y.y),"\r
170         //                      "                  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"\r
171 \r
172                 //decide between left and right\r
173                 " vec4 ypos_temp2;\n"\r
174                 "if (halfst<out_block_edge.x){\n"\r
175                 "  ypos_temp2.xy=ypos_temp1.zw;\n"\r
176                 " }else {\n"\r
177                 "  ypos_temp2.xy=ypos_temp1.xy;\n"\r
178                 " }\n"\r
179                 //now get the intra 8x8 Block coordinates\r
180                 " vec2 ypos_temp3=floor(mod(out_block_edge*vec2(ctwo,line_step),cone)*acht);\n"\r
181                 " ypos_temp2.x=(ypos_temp3.x+(ypos_temp3.y+acht*(ypos_temp2.x))*acht);\n"\r
182                 //" bool subsample=(mod(ypos_temp2.x,ctwo)>halfst);\n"\r
183                 " bool subsample=mod(ypos_temp3.x,ctwo)==cone;\n"\r
184                 " ypos_temp2.x*=halfst;\n"\r
185                 " ypos_temp2.xy*=c1over1024;\n"\r
186                 " ypos_temp1=texture2D(blocks,ypos_temp2.xy);\n" // now select the right data\r
187                 "if (subsample){\n"\r
188                 "  ypos_temp2.xy=ypos_temp1.zw;\n"\r
189                 //"  ypos_temp2=vec2(cone,0.);\n"\r
190                 " }else {\n"\r
191                 "  ypos_temp2.xy=ypos_temp1.xy;\n"\r
192                 " }\n"\r
193                 " gl_FragColor.r=unpack_short(ypos_temp2.rg);\n"\r
194 \r
195                 //now uv\r
196                 " ypos_temp3=floor(out_block_edge*acht);\n"\r
197                 " ypos_temp2.yw=floor(out_uvblockpos_xy.zw);\n"\r
198                 " ypos_temp2.xz=(ypos_temp3.x+(ypos_temp3.y+acht*(out_uvblockpos_xy.xy))*acht);\n"\r
199                                 //" bool subsample=(mod(ypos_temp2.x,ctwo)>halfst);\n"\r
200                 " subsample=mod(ypos_temp3.x,ctwo)==cone;\n"\r
201                 " ypos_temp2.xz*=halfst;\n"\r
202                 " ypos_temp2*=c1over1024;\n"\r
203 \r
204                 " ypos_temp1=texture2D(blocks,ypos_temp2.xy);\n" // now select the right data\r
205                 " if (subsample){\n"\r
206                 "  ypos_temp2.xy=ypos_temp1.zw;\n"\r
207                 " }else {\n"\r
208                 "  ypos_temp2.xy=ypos_temp1.xy;\n"\r
209                 " }\n"\r
210                 " gl_FragColor.g=unpack_short(ypos_temp2.rg);\n"\r
211 \r
212                 " ypos_temp1=texture2D(blocks,ypos_temp2.zw);\n" // now select the right data\r
213                 " if (subsample){\n"\r
214                 "  ypos_temp2.xy=ypos_temp1.zw;\n"\r
215                 " }else {\n"\r
216                 "  ypos_temp2.xy=ypos_temp1.xy;\n"\r
217                 " }\n"\r
218                 " gl_FragColor.b=unpack_short(ypos_temp2.rg);\n"\r
219                 " if (out_unsupported!=0.) {\n"\r
220                 "    gl_FragColor.rgb=vec3(cone,cone,0.0);\n"\r
221                 "}\n"\r
222 \r
223 \r
224                 //" ypos_temp2=mix(ypos_temp1.rg,ypos_temp1.ba,step(c1over2047,mod(ypos_temp2.x,c1over1023)));\n" //activate this\r
225 \r
226 \r
227                 //" gl_FragColor.r=subsample/acht;\n" //signed later TODO\r
228                 //" gl_FragColor.g=0.5;\n"\r
229                 //" gl_FragColor.b=0.5;\n"\r
230                 " gl_FragColor.a=1.0;\n"\r
231                 //" vec4 blocks=texture2D(blocks,gl_FragCoord.xy/600.);\n"\r
232 //              "help.x=texture2D(textureY,out_texCoord).r;\n"\r
233 //              "help.y=texture2D(textureU,out_texCoord).r;\n"\r
234 //              "help.z=texture2D(textureV,out_texCoord).r;\n" //-uv_corr;\n"\r
235    //   "  gl_FragColor.rgba=blocks;\n"\r
236         //      "  gl_FragColor.rgba=vec4(0.7,0.5,0.5,1.0);\n"\r
237                 //"  gl_FragColor.a=1.;\n"\r
238                 "}\n";\r
239 \r
240 GLMocoShader::GLMocoShader(): GLShader("GLMocoShader")\r
241 {\r
242 \r
243         frame_buf=0;\r
244         blocks_loc=0;\r
245 }\r
246 \r
247 GLMocoShader::~GLMocoShader()\r
248 {\r
249         //parent does everything\r
250 }\r
251 \r
252 int GLMocoShader::init() {\r
253 \r
254         if (!initShaders(moco_vertex_shader, moco_frag_shader)) {\r
255                 Log::getInstance()->log("GLMocoShader", Log::ERR, "init Shaders failed for GLMocoShader");\r
256                 return 0;\r
257         }\r
258         loc_pict_scale = glGetUniformLocation(shad_program, "pict_scale");\r
259         blocks_loc = glGetUniformLocation(shad_program, "blocks");\r
260         forward_pic_loc = glGetUniformLocation(shad_program, "forward_pic");\r
261         backward_pic_loc = glGetUniformLocation(shad_program, "backward_pic");\r
262 \r
263 //      frame_sampler_locY = glGetUniformLocation(shad_program, "textureY");\r
264         // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());\r
265 //      frame_sampler_locU = glGetUniformLocation(shad_program, "textureU");\r
266         //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError());\r
267 //      frame_sampler_locV = glGetUniformLocation(shad_program, "textureV");\r
268         glGenFramebuffers(1, &frame_buf);\r
269         //Log::getInstance()->log("GLMocoShader", Log::WARN, "genframe bufmark1 glerror %x",glGetError());\r
270         glGenTextures(1, &data_blocks);\r
271         glBindTexture(GL_TEXTURE_2D, data_blocks);\r
272         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BLOCK_TEXTURE_WIDTH >>1, BLOCK_TEXTURE_HEIGHT, 0, GL_RGBA,\r
273                                 GL_UNSIGNED_BYTE, NULL);\r
274         char buffer[BLOCK_TEXTURE_WIDTH*4];\r
275         memset(buffer,0,BLOCK_TEXTURE_WIDTH*4); // the last line is black, simplifies the shader algorithms\r
276 \r
277         glTexSubImage2D(GL_TEXTURE_2D,0,0,BLOCK_TEXTURE_HEIGHT-1,\r
278                         1024,1,\r
279                         GL_RGBA,GL_UNSIGNED_BYTE,\r
280                         buffer);\r
281 \r
282         glGenBuffers(1,&macro_block);\r
283         glBindBuffer(GL_ARRAY_BUFFER,macro_block);\r
284         glBufferData(GL_ARRAY_BUFFER,4096*4*sizeof(XvMCMacroBlock),NULL,GL_DYNAMIC_DRAW);\r
285         valid_macro_blocks=0;\r
286 \r
287 \r
288         glGenBuffers(1,&triangles);\r
289         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles);\r
290         GLushort *tri_indices=(GLushort *)malloc(sizeof(GLushort)*4096*6);\r
291         if (!tri_indices) {\r
292                 Log::getInstance()->log("GLMocoShader", Log::WARN, "allocating triindices failed");\r
293                 return 0;\r
294         }\r
295         GLushort *tri_indices_run=tri_indices;\r
296         for (int i=0;i<4096;i++) {\r
297                 *tri_indices_run=i+0*4096;  //strip\r
298                 tri_indices_run++;\r
299                 *tri_indices_run=i+2*4096;  //strip\r
300                 tri_indices_run++;\r
301                 *tri_indices_run=i+1*4096;  //strip\r
302                 tri_indices_run++;\r
303                 *tri_indices_run=i+3*4096;  //strip\r
304                 tri_indices_run++;\r
305                 *tri_indices_run=i+3*4096;  //strip\r
306                 tri_indices_run++;\r
307                 *tri_indices_run=i+1+0*4096;  //strip\r
308                 tri_indices_run++;\r
309         }\r
310 \r
311 \r
312 \r
313 \r
314 \r
315         glBufferData(GL_ELEMENT_ARRAY_BUFFER,4096*6*sizeof(GLushort),tri_indices,GL_STREAM_DRAW);\r
316         free(tri_indices);\r
317 \r
318         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);\r
319         glBindBuffer(GL_ARRAY_BUFFER,0);\r
320 \r
321 \r
322 \r
323         return 1;\r
324 \r
325 }\r
326 \r
327 int GLMocoShader::deinit()\r
328 {\r
329         glDeleteFramebuffers(1, &frame_buf);\r
330         glDeleteTextures(1, &data_blocks);\r
331         return deinitShaders();\r
332 }\r
333 \r
334 \r
335 \r
336 int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMacroBlock *m_blocks,unsigned int num_m_blocks)\r
337 {\r
338         unsigned int height=(num_blocks)/(BLOCK_PER_ROW);\r
339 \r
340         glBindTexture(GL_TEXTURE_2D, data_blocks);\r
341         glPixelStorei(GL_UNPACK_ALIGNMENT,1);\r
342 \r
343 \r
344 \r
345 \r
346 //      Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 glerror %x %d",glGetError(),height);\r
347         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,\r
348                 BLOCK_TEXTURE_WIDTH>>1,height,\r
349                 GL_RGBA,GL_UNSIGNED_BYTE,\r
350                 blocks);\r
351 //      Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
352         glTexSubImage2D(GL_TEXTURE_2D,0,0,height+1,\r
353                         (num_blocks%BLOCK_PER_ROW)>>1,1,\r
354                         GL_RGBA,GL_UNSIGNED_BYTE,\r
355                         blocks);\r
356 \r
357         //Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
358 \r
359 \r
360 \r
361         glBindTexture(GL_TEXTURE_2D, 0);\r
362 \r
363         valid_macro_blocks=num_m_blocks;\r
364         glBindBuffer(GL_ARRAY_BUFFER,macro_block);\r
365         XvMCMacroBlock *m_blocks_run=m_blocks;\r
366         XvMCMacroBlock *m_blocks_end=m_blocks+num_m_blocks;\r
367         while (m_blocks_run!=m_blocks_end) {\r
368                 m_blocks_run->pad0=0xFF00;\r
369                 m_blocks_run++;\r
370         }\r
371         // debug\r
372 /*      m_blocks[0].x=0;\r
373         m_blocks[0].y=0;\r
374         m_blocks[3]=m_blocks[2]=m_blocks[1]=m_blocks[0];\r
375         m_blocks[0].pad0=0xFF00;\r
376         m_blocks[1].pad0=0xFFFF;\r
377         m_blocks[2].pad0=0x0000;\r
378         m_blocks[3].pad0=0x00FF;\r
379         m_blocks[1].x=0;\r
380         m_blocks[1].y=0;\r
381         m_blocks[2].x=0;\r
382         m_blocks[2].y=0;\r
383         m_blocks[3].x=0;\r
384         m_blocks[3].y=0;*/\r
385 \r
386         glBufferSubData(GL_ARRAY_BUFFER, 0* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock),\r
387                         m_blocks);\r
388 \r
389 \r
390         m_blocks_run = m_blocks;\r
391         m_blocks_end = m_blocks + num_m_blocks;\r
392         while (m_blocks_run != m_blocks_end) {\r
393                 m_blocks_run->pad0 = 0xFFFF;\r
394                 m_blocks_run++;\r
395         }\r
396         glBufferSubData(GL_ARRAY_BUFFER, 4096* sizeof(XvMCMacroBlock), num_m_blocks * sizeof(XvMCMacroBlock),\r
397                         m_blocks);\r
398 \r
399 \r
400         m_blocks_run = m_blocks;\r
401         m_blocks_end = m_blocks + num_m_blocks;\r
402         while (m_blocks_run != m_blocks_end) {\r
403                 m_blocks_run->pad0 = 0x0000;\r
404                 m_blocks_run++;\r
405         }\r
406         glBufferSubData(GL_ARRAY_BUFFER, 2 * 4096* sizeof(XvMCMacroBlock),\r
407                         num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);\r
408 \r
409 \r
410         m_blocks_run = m_blocks;\r
411         m_blocks_end = m_blocks + num_m_blocks;\r
412         while (m_blocks_run != m_blocks_end) {\r
413                 m_blocks_run->pad0 = 0x00FF;\r
414                 m_blocks_run++;\r
415         }\r
416         glBufferSubData(GL_ARRAY_BUFFER, 3 * 4096* sizeof(XvMCMacroBlock),\r
417                         num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);\r
418 \r
419 \r
420         glBindBuffer(GL_ARRAY_BUFFER,0);\r
421 \r
422         return 1;\r
423 \r
424 \r
425 \r
426 }\r
427 \r
428 int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *backward)\r
429 {\r
430 \r
431 //      Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-2 glerror %x %x",glGetError(),frame_buf);\r
432 \r
433         //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-1 glerror %x %x",glGetError(),frame_buf);\r
434         glBindFramebuffer(GL_FRAMEBUFFER, frame_buf);\r
435         //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x %x %x",glGetError(),target->textures[0],target->textures[1]);\r
436 \r
437 \r
438         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,\r
439                         GL_TEXTURE_2D, target->textures[0], 0);\r
440         //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1apres glerror %x",glGetError());\r
441 \r
442 \r
443 \r
444 \r
445         //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError());\r
446 \r
447         //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2a glerror %x",glGetError());\r
448 \r
449         int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);\r
450         if (status == GL_FRAMEBUFFER_COMPLETE) {\r
451                 glViewport(0, 0, target->width,target->height);\r
452         //      Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2b glerror %x",glGetError());\r
453 \r
454                 XvMCMacroBlock * helperp=NULL;\r
455 \r
456                 glClearColor(0.0f,0.5f,0.5f,1.f); //this black\r
457                 glClear(GL_COLOR_BUFFER_BIT);\r
458                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2c glerror %x",glGetError());\r
459 \r
460                 glUseProgram(shad_program);\r
461                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError());\r
462 \r
463 \r
464                 const GLfloat pict_scale[]={  32./((float)target->width),32./((float)target->height)};\r
465 \r
466                 glUniform2fv(loc_pict_scale,1,(const GLfloat*)&pict_scale);\r
467 \r
468 \r
469 \r
470                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles);\r
471                                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark5 glerror %x",glGetError());\r
472                 glBindBuffer(GL_ARRAY_BUFFER,macro_block);\r
473 \r
474 \r
475 \r
476                 glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE,\r
477                                 sizeof(XvMCMacroBlock), NULL);\r
478 \r
479                 glEnableVertexAttribArray(0);\r
480 \r
481                 glVertexAttribPointer(1, 2, GL_UNSIGNED_BYTE, GL_TRUE,sizeof(XvMCMacroBlock), (const void *) &(helperp->pad0));\r
482                 glEnableVertexAttribArray(1);\r
483 \r
484                 glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->macroblock_type));\r
485                 glEnableVertexAttribArray(2);\r
486 \r
487                 glVertexAttribPointer(3, 1, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->coded_block_pattern));\r
488                 glEnableVertexAttribArray(3);\r
489                 glVertexAttribPointer(4, 2, GL_UNSIGNED_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->index));\r
490                 glEnableVertexAttribArray(4);\r
491 \r
492 \r
493                 glActiveTexture(GL_TEXTURE0);\r
494                 glBindTexture(GL_TEXTURE_2D,data_blocks);\r
495                 glUniform1i(blocks_loc,0);\r
496                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
497                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
498                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
499                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
500 \r
501                 if (forward) {\r
502                         glActiveTexture(GL_TEXTURE1);\r
503                         glBindTexture(GL_TEXTURE_2D,forward->textures[0]);\r
504                         glUniform1i(forward_pic_loc,1);\r
505                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
506                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
507                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
508                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
509                 }\r
510 \r
511                 if (backward) {\r
512                         glActiveTexture(GL_TEXTURE2);\r
513                         glBindTexture(GL_TEXTURE_2D,backward->textures[1]);\r
514                         glUniform1i(backward_pic_loc,2);\r
515                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
516                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
517                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
518                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
519                 }\r
520 \r
521                 glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6,\r
522                         GL_UNSIGNED_SHORT, NULL);\r
523 \r
524 \r
525                 /*\r
526                 glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), 0);\r
527                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError());\r
528                 glEnableVertexAttribArray(0);\r
529 \r
530                 glVertexAttribPointer(1, 2, GL_UNSIGNED_BYTE, GL_TRUE,sizeof(XvMCMacroBlock), (const void *) &(helperp->pad0));\r
531                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError());\r
532                 glEnableVertexAttribArray(1);*/\r
533 \r
534         //      Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark4 glerror %x",glGetError());\r
535 \r
536 \r
537                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark6 glerror %x",glGetError());\r
538 \r
539         //      glDrawElements(GL_TRIANGLE_STRIP,/*valid_macro_blocks*/4,GL_UNSIGNED_SHORT,0);\r
540                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark7 glerror %x %x",glGetError(),valid_macro_blocks);\r
541                 //cleanup\r
542 \r
543                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);\r
544                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark5 glerror %x",glGetError());\r
545                 glBindBuffer(GL_ARRAY_BUFFER,0);\r
546 \r
547                 glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
548                 glBindTexture(GL_TEXTURE_2D, 0);\r
549                 //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark8 glerror %x",glGetError());\r
550         } else {\r
551                 glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
552                 Log::getInstance()->log("GLMocoShader", Log::WARN, "framebuffer not complete %x",status);\r
553                 return -1;\r
554         }\r
555 \r
556         glFinish(); // since the main rendering is done in a different thread we have to make sure rendering is finished before passing the texture\r
557         // call this only in the last stage of rendering the moco frame\r
558         return 0;\r
559 \r
560 \r
561 \r
562 }\r
563 \r
564 /*\r
565 \r
566 int GLMocoShader::PrepareRendering(GLuint y_tex, GLuint u_tex, GLuint v_tex) { // This Function setups the rendering pipeline according to the shaders standards\r
567 \r
568         //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError());\r
569 \r
570 \r
571         //Log::getInstance()->log("OSD", Log::WARN, "mark2 glerror %x",glGetError());\r
572 \r
573 \r
574         glActiveTexture( GL_TEXTURE2);\r
575         glBindTexture(GL_TEXTURE_2D, v_tex);\r
576         glUniform1i(frame_sampler_locV, 2);\r
577         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
578         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
579 \r
580         glActiveTexture( GL_TEXTURE1);\r
581         glBindTexture(GL_TEXTURE_2D, u_tex);\r
582         glUniform1i(frame_sampler_locU, 1);\r
583         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
584         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
585 \r
586         glActiveTexture( GL_TEXTURE0);\r
587         glBindTexture(GL_TEXTURE_2D, y_tex);\r
588         glUniform1i(frame_sampler_locY, 0);\r
589         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
590         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
591         return 1;\r
592 \r
593 }*/\r
594 \r
595 int GLMocoShader::BindAttributes()\r
596 {\r
597         glBindAttribLocation(shad_program,0,"block_pos");\r
598         glBindAttribLocation(shad_program,1,"block_edge");\r
599         glBindAttribLocation(shad_program,2,"block_types");\r
600         glBindAttribLocation(shad_program,3,"cbp");\r
601         glBindAttribLocation(shad_program,4,"index");\r
602         //glBindAttribLocation(shad_program,1,"tex_coord");\r
603         return 1;\r
604 }\r