#define BLOCK_SIZE 64\r
#define BLOCK_PER_ROW 32\r
\r
+// This implementation is for framed coded pictures only!\r
+// I did not find any DVB recording with field coded pictures\r
+// so I do not think they exist here, anyway I suspect we\r
+// need a totally different shader in this case\r
+// so first write the frame coded shader\r
+// and then later add if necessary field based support.\r
+\r
const GLchar moco_vertex_shader[] =\r
"attribute vec4 block_pos;\n"\r
"attribute vec2 block_edge;\n"\r
"attribute vec4 block_types;\n"\r
"attribute vec2 index;\n"\r
+ "attribute vec4 PMV1;\n"\r
+ "attribute vec4 PMV2;\n"\r
"attribute float cbp;\n"\r
"uniform vec2 pict_scale;\n"\r
// "attribute vec2 tex_coord;\n"\r
"varying vec4 out_yblockpos_y;\n"\r
"varying vec4 out_uvblockpos_xy;\n"\r
"varying vec2 out_block_edge;\n"\r
- "varying vec4 out_block_types;\n"\r
+ "varying vec4 out_misc_info;\n"\r
\r
"varying float out_unsupported;\n"\r
+ "varying vec4 out_moco_pos;\n"\r
+ "varying vec4 out_moco_forward;\n"\r
+ "varying vec4 out_moco_backward;\n"\r
+\r
\r
"const float one=1.0;\n"\r
+ "const float czero=0.0;\n"\r
+ "const float chalf=0.5;\n"\r
"const float c1024=1024.0;\n"\r
"const float c32=32.0;\n"\r
// "const float c1over32=0.03125;\n"\r
" float m_index=index.x/*+index.y*c65536*/-one;\n" //Not Endian save\r
" fmod_cbp_y2+=m_index;\n" //shift to the blocks\r
" fmod_cbp_uv2+=m_index;\n"\r
- //" out_yblockpos_x=(mod(fmod_cbp_y2,c32));\n"\r
- //" out_uvblockpos_xy.xy=(mod(fmod_cbp_uv2,c32));\n"\r
- //" out_yblockpos_y=floor((fmod_cbp_y2)/c32);\n"\r
- //" out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)/c32);\n"\r
+ " out_yblockpos_x=(mod(fmod_cbp_y2,c32));\n"\r
+ " out_uvblockpos_xy.xy=(mod(fmod_cbp_uv2,c32));\n"\r
+ " out_yblockpos_y=floor((fmod_cbp_y2)/c32);\n"\r
+ " out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)/c32);\n"\r
\r
" out_yblockpos_y=floor((fmod_cbp_y2)*c1over32);\n"\r
" out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)*c1over32);\n"\r
" out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n"\r
" out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n"\r
\r
- // " if (block_types.y!=0.) {\n"\r
- // " out_unsupported=1.;\n"\r
- // "} else {\n"\r
- // " out_unsupported=0.;\n"\r
- // "}\n"\r
+ // set start positions\r
+ " vec4 motion_vertical=vec4(block_types.z,block_types.z,block_types.z,block_types.z);\n"\r
+ " vec4 mod_motion_vertical=mod(motion_vertical,y_cbp);\n"\r
+ " mod_motion_vertical=sign(vec4(mod_motion_vertical.yzw,block_types.z)-mod_motion_vertical);\n"\r
+\r
+ " out_moco_pos.xy=(block_pos.xy+block_edge.xy)*uv_cbp.x/*16*/+one;"\r
+ " out_unsupported=czero;\n"\r
+ " out_moco_pos.zw=vec2(czero,czero);\n"\r
+ " out_misc_info.y=one;\n" // this is the y step\r
+ " if (block_types.x<uv_cbp.x /* 16*/) {\n" // not intra coded\r
+ " float forward_backward=mod(block_types.x,y_cbp.w /* 8*/);\n"\r
+ " out_moco_pos.zw=vec2(one,czero);\n"\r
+ " if (forward_backward>y_cbp.z /* 4*/) {\n"\r
+ " out_moco_pos.zw=vec2(chalf,chalf);\n"\r
+ //" out_unsupported=2.;\n"\r
+ " } else if (forward_backward>y_cbp.y /* 2*/ ) {\n" //backward\r
+ " out_moco_pos.zw=vec2(czero,one);\n"\r
+ //" out_unsupported=2.;\n"\r
+ " } else {\n" //forward\r
+ " out_moco_pos.zw=vec2(one,czero);\n"\r
+ " } \n"\r
+ " if ((out_moco_pos.w+out_moco_pos.z)>y_cbp.x) {"\r
+ " out_moco_pos.zw*=chalf;\n"\r
+ " }\n"\r
+ " if (block_types.y==y_cbp.y /*2*/) {" //Frame\r
+ " out_moco_forward=vec4(PMV1.xy,PMV1.xy);\n"\r
+ " out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n"\r
+ //" out_unsupported=2.;\n"\r
+ " } else if (block_types.y==y_cbp.x /*1*/) {" //Field\r
+ " out_moco_forward=vec4(PMV1.xy,PMV2.xy);\n"\r
+ " out_moco_backward=vec4(PMV1.zw,PMV2.zw);\n"\r
+ " out_moco_forward.y+=mod_motion_vertical.x;\n"\r
+ " out_moco_backward.y+=mod_motion_vertical.y;\n"\r
+ " out_moco_forward.w-=one-mod_motion_vertical.z;\n"\r
+ " out_moco_backward.w-=one-mod_motion_vertical.w;\n"\r
+ " out_misc_info.y=one;\n" // step to for field based\r
+ // " out_unsupported=2.;\n"\r
+ " } else {\n"\r
+ " out_unsupported=1.;\n"\r
+ " }\n"\r
+ " }\n"\r
\r
\r
" out_block_edge=block_edge;\n"\r
- " out_block_types=block_types;\n"\r
+ " out_misc_info.x=block_types.w;\n"\r
" vec4 out_pos=block_pos;\n"\r
" out_pos.xy+=block_edge;\n"\r
" out_pos.xy*=pict_scale;\n"\r
"uniform sampler2D blocks;\n"\r
"uniform sampler2D forward_pic;\n"\r
"uniform sampler2D backward_pic;\n"\r
+ "uniform vec2 pict_size;\n"\r
"varying vec4 out_yblockpos_x;\n"\r
"varying vec4 out_yblockpos_y;\n"\r
"varying vec4 out_uvblockpos_xy;\n"\r
"varying vec2 out_block_edge;\n"\r
- "varying vec4 out_block_types;\n" // change this we need so far only the dct type\r
+ "varying vec4 out_misc_info;\n"// misc info x= DCT info, y= field based offsets\r
"varying float out_unsupported;\n"\r
+ "varying vec4 out_moco_forward;\n"\r
+ "varying vec4 out_moco_backward;\n"\r
+ "varying vec4 out_moco_pos;\n"\r
\r
"const float halfst=0.5;\n"\r
"const float ctwo=2.0;\n"\r
"const float cone=1.0;\n"\r
+ "const float czero=0.0;\n"\r
"const float sieben=7.0;\n"\r
"const float acht=8.0;\n"\r
"const float s8=1./8.;\n"\r
"float unpack_short(vec2 income) {\n"\r
" float temp=income.y*c65280+income.x*c255;\n"\r
" temp-=step(cstep,temp)*c65536;\n"\r
- " return abs(temp/c255);\n" //temporary work around\r
+ " return temp/c255;\n"\r
"}"\r
// "uniform sampler2D textureV;\n"\r
// "uniform sampler2D textureY;\n"\r
// first figure out the block num for y, first decide between up and down, fix me field\r
//non field code\r
" vec4 ypos_temp1;\n"\r
+ " vec4 our_fragcol=vec4(czero,czero,czero,cone);\n"\r
" bool upper_half;\n"\r
" float line_step;\n"\r
- " if (out_block_types.w!=0.) {\n" //test the dct type\r
+ " if (out_misc_info.x!=0.) {\n" //test the dct type\r
" upper_half=mod(floor(out_block_edge.y*acht),ctwo)==cone;\n"\r
" line_step=cone;\n"\r
"}else{\n"\r
" }else {\n"\r
" ypos_temp2.xy=ypos_temp1.xy;\n"\r
" }\n"\r
- " gl_FragColor.r=unpack_short(ypos_temp2.rg);\n"\r
+ " our_fragcol.r=unpack_short(ypos_temp2.rg);\n"\r
\r
//now uv\r
" ypos_temp3=floor(out_block_edge*acht);\n"\r
" }else {\n"\r
" ypos_temp2.xy=ypos_temp1.xy;\n"\r
" }\n"\r
- " gl_FragColor.g=unpack_short(ypos_temp2.rg);\n"\r
+ " our_fragcol.g=unpack_short(ypos_temp2.rg);\n"\r
\r
" ypos_temp1=texture2D(blocks,ypos_temp2.zw);\n" // now select the right data\r
" if (subsample){\n"\r
" }else {\n"\r
" ypos_temp2.xy=ypos_temp1.xy;\n"\r
" }\n"\r
- " gl_FragColor.b=unpack_short(ypos_temp2.rg);\n"\r
- " if (out_unsupported!=0.) {\n"\r
- " gl_FragColor.rgb=vec3(cone,cone,0.0);\n"\r
+ " our_fragcol.b=unpack_short(ypos_temp2.rg);\n"\r
+ //MOCO\r
+ // decide if it is top or bottom\r
+ " vec4 moco_work;\n"\r
+ " if (mod(floor(out_moco_pos.y),ctwo)!=cone) {\n"\r
+ " moco_work=vec4(out_moco_forward.xy,out_moco_backward.xy);\n"\r
+ "} else {\n"\r
+ " moco_work=vec4(out_moco_forward.zw,out_moco_backward.zw);\n"\r
+ "}\n"\r
+ // now we handle the y fetching\r
+ " vec4 moco_temp;\n"\r
+ " vec4 subpixel=floor(mod(moco_work,ctwo))*halfst; \n"\r
+ " moco_temp=floor(moco_work*halfst+halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy));\n"\r
+ " vec4 c00,c01,c10,c11;\n"\r
+\r
+ " c00=texture2D(forward_pic,moco_temp.xy*pict_size);\n"\r
+ " c01=texture2D(forward_pic,(moco_temp.xy+vec2(czero,out_misc_info.y))*pict_size);\n"\r
+ " c10=texture2D(forward_pic,(moco_temp.xy+vec2(cone,czero))*pict_size);\n"\r
+ " c11=texture2D(forward_pic,(moco_temp.xy+vec2(cone,out_misc_info.y))*pict_size);\n"\r
+ " our_fragcol.r+=mix(mix(c00.r,c10.r,subpixel.x),mix(c01.r,c11.r,subpixel.x),subpixel.y)*out_moco_pos.z;\n"\r
+\r
+\r
+ " c00=texture2D(backward_pic,moco_temp.zw*pict_size);\n"//backward\r
+ " c01=texture2D(backward_pic,(moco_temp.zw+vec2(czero,out_misc_info.y))*pict_size);\n"\r
+ " c10=texture2D(backward_pic,(moco_temp.zw+vec2(cone,czero))*pict_size);\n"\r
+ " c11=texture2D(backward_pic,(moco_temp.zw+vec2(cone,out_misc_info.y))*pict_size);\n"\r
+ " our_fragcol.r+=mix(mix(c00.r,c10.r,subpixel.z),mix(c01.r,c11.r,subpixel.z),subpixel.w)*out_moco_pos.w;\n"\r
+ // now handle UV\r
+ " subpixel=floor(mod(moco_work*halfst,ctwo))*halfst; \n"\r
+ " moco_temp=(floor(moco_work*halfst*halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy)*halfst))*ctwo;\n"\r
+\r
+ " c00=texture2D(forward_pic,moco_temp.xy*pict_size);\n"\r
+ " c01=texture2D(forward_pic,(moco_temp.xy+vec2(czero,ctwo*out_misc_info.y))*pict_size);\n"\r
+ " c10=texture2D(forward_pic,(moco_temp.xy+vec2(ctwo,czero))*pict_size);\n"\r
+ " c11=texture2D(forward_pic,(moco_temp.xy+vec2(ctwo,ctwo*out_misc_info.y))*pict_size);\n"\r
+ " our_fragcol.gb+=mix(mix(c00.gb,c10.gb,subpixel.x),mix(c01.gb,c11.gb,subpixel.x),subpixel.y)*out_moco_pos.z;\n"\r
+\r
+ " c00=texture2D(backward_pic,moco_temp.zw*pict_size);\n"\r
+ " c01=texture2D(backward_pic,(moco_temp.zw+vec2(czero,ctwo*out_misc_info.y))*pict_size);\n"\r
+ " c10=texture2D(backward_pic,(moco_temp.zw+vec2(ctwo,czero))*pict_size);\n"\r
+ " c11=texture2D(backward_pic,(moco_temp.zw+vec2(ctwo,ctwo*out_misc_info.y))*pict_size);\n"\r
+ " our_fragcol.gb+=mix(mix(c00.gb,c10.gb,subpixel.z),mix(c01.gb,c11.gb,subpixel.z),subpixel.w)*out_moco_pos.w;\n"\r
+\r
+ " gl_FragColor.rgb=vec3(our_fragcol.r,halfst,halfst);\n"\r
+ " if (out_unsupported==1.) {\n"\r
+ " gl_FragColor.gb=vec2(cone,0.0);\n"\r
+ "}else if (out_unsupported==2.) {\n"\r
+ " gl_FragColor.gb=vec2(0.0,cone);\n"\r
"}\n"\r
\r
\r
blocks_loc = glGetUniformLocation(shad_program, "blocks");\r
forward_pic_loc = glGetUniformLocation(shad_program, "forward_pic");\r
backward_pic_loc = glGetUniformLocation(shad_program, "backward_pic");\r
+ pict_size_loc = glGetUniformLocation(shad_program, "pict_size");\r
\r
// frame_sampler_locY = glGetUniformLocation(shad_program, "textureY");\r
// Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());\r
GL_RGBA,GL_UNSIGNED_BYTE,\r
blocks);\r
// Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
- glTexSubImage2D(GL_TEXTURE_2D,0,0,height+1,\r
- (num_blocks%BLOCK_PER_ROW)>>1,1,\r
+ glTexSubImage2D(GL_TEXTURE_2D,0,0,height,\r
+ ((num_blocks%BLOCK_PER_ROW)>>1)*BLOCK_SIZE,1,\r
GL_RGBA,GL_UNSIGNED_BYTE,\r
- blocks);\r
+ blocks+height*BLOCK_PER_ROW*BLOCK_SIZE);\r
\r
//Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
\r
glUniform2fv(loc_pict_scale,1,(const GLfloat*)&pict_scale);\r
\r
\r
+ const GLfloat pict_size[]={ 1./((float)target->width),1./((float)target->height)};\r
+ glUniform2fv(pict_size_loc,1,(const GLfloat*)&pict_size);\r
\r
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles);\r
//Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark5 glerror %x",glGetError());\r
glVertexAttribPointer(4, 2, GL_UNSIGNED_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->index));\r
glEnableVertexAttribArray(4);\r
\r
+ glVertexAttribPointer(5, 4, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->PMV[0][0][0]));\r
+ glEnableVertexAttribArray(5);\r
+\r
+ glVertexAttribPointer(6, 4, GL_SHORT, GL_FALSE,sizeof(XvMCMacroBlock), (const void *) &(helperp->PMV[1][0][0]));\r
+ glEnableVertexAttribArray(6);\r
+\r
+\r
+\r
\r
glActiveTexture(GL_TEXTURE0);\r
glBindTexture(GL_TEXTURE_2D,data_blocks);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
\r
+\r
if (forward) {\r
+ Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo forward %x",forward->textures[0]);\r
glActiveTexture(GL_TEXTURE1);\r
glBindTexture(GL_TEXTURE_2D,forward->textures[0]);\r
glUniform1i(forward_pic_loc,1);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
+\r
}\r
\r
if (backward) {\r
glActiveTexture(GL_TEXTURE2);\r
- glBindTexture(GL_TEXTURE_2D,backward->textures[1]);\r
+ Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo backward %x",backward->textures[0]);\r
+ glBindTexture(GL_TEXTURE_2D,backward->textures[0]);\r
glUniform1i(backward_pic_loc,2);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
+\r
}\r
\r
+\r
glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6,\r
GL_UNSIGNED_SHORT, NULL);\r
\r
glBindBuffer(GL_ARRAY_BUFFER,0);\r
\r
glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
+ glActiveTexture(GL_TEXTURE0);\r
+ glBindTexture(GL_TEXTURE_2D, 0);\r
+ glActiveTexture(GL_TEXTURE1);\r
+ glBindTexture(GL_TEXTURE_2D, 0);\r
+ glActiveTexture(GL_TEXTURE2);\r
glBindTexture(GL_TEXTURE_2D, 0);\r
//Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark8 glerror %x",glGetError());\r
} else {\r
glBindAttribLocation(shad_program,2,"block_types");\r
glBindAttribLocation(shad_program,3,"cbp");\r
glBindAttribLocation(shad_program,4,"index");\r
+ glBindAttribLocation(shad_program,5,"PMV1");\r
+ glBindAttribLocation(shad_program,6,"PMV2");\r
+\r
//glBindAttribLocation(shad_program,1,"tex_coord");\r
return 1;\r
}\r
return 1;
}
-int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height)
+int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
{
Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
// Y
outframe->type=2;
outframe->height=height;
outframe->width=width;
- outframe->stride=width; // does not make any sense otherwiese
+ outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
return 1;
}
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)) failed=true; //We use a YUV 444 texture in this case
+ if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true; //We use a YUV 444 texture in this case
// the shaders are easier to implement
}
}
Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
- if (((int)pix_fmt->p_future_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_future_surface))
+ if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
{
//Now determine the frame, that fits
ogl_frame_mutex.Lock();
for (int i=0;i<all_ogl_frames.size();i++) {
if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
{
- ogl_backward_ref_frame=ogl_forward_ref_frame; //mpeg life time axioms
- ogl_backward_ref_frame_num=ogl_forward_ref_frame_num;
- ogl_forward_ref_frame=all_ogl_frames[i];
- ogl_forward_ref_frame_num=(int)pix_fmt->p_future_surface;
+ ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
+ ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
+ ogl_backward_ref_frame=all_ogl_frames[i];
+ ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
break;
}
}
}
- if (((int)pix_fmt->p_past_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_past_surface))
+ if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
{
//Now determine the frame, that fits
ogl_frame_mutex.Lock();
for (int i=0;i<all_ogl_frames.size();i++) {
if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
{
- ogl_backward_ref_frame=all_ogl_frames[i];
- ogl_backward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
+ ogl_forward_ref_frame=all_ogl_frames[i];
+ ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
break;
}
}
}
out_frame->pict_num=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num;
- moco_shader->doMoCo(out_frame,ogl_forward_ref_frame,ogl_backward_ref_frame);
+
+ moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
+ (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
// Excute motion compensation
}
void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
{
if ((y+height)==src->height) {
- //Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface);
+ /* Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
+ ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
+ if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
+ Log::getInstance()->log("Video", Log::ERR, "Non frame pict supported! Yet! Please send sample to authors!"); exit(0);
+ }
((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
}