From f5e4a85d6157f9e889fc9c85794379899ae4e1a8 Mon Sep 17 00:00:00 2001
From: Marten Richter <marten.richter@freenet.de>
Date: Sun, 8 Jul 2012 16:28:51 +0200
Subject: [PATCH] MoComp nearly bug free

---
 glmocoshader.cc | 118 ++++++++++++++++++++++++++++++++++++++----------
 osdopengl.cc    |   2 +-
 vfeed.cc        |   2 +-
 videovpeogl.cc  |  16 +++++--
 4 files changed, 109 insertions(+), 29 deletions(-)
 mode change 100644 => 100755 vfeed.cc

diff --git a/glmocoshader.cc b/glmocoshader.cc
index 5f0cd6c..cbeabce 100755
--- a/glmocoshader.cc
+++ b/glmocoshader.cc
@@ -72,19 +72,19 @@ const GLchar moco_vertex_shader[] =
 		"void main()\n"
 		"{\n"
 		// calculate cbp
-		"  vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n"
+		//"  vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n"
 
 		// old cbp code
 	//	"  vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n"
-	//	"  vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n"
+	//	"  vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp.xy);\n"
 	//	"  fmod_cbp_y.x=0.;\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_y=mod(cbp_vec,vec4(uv_cbp.zyx,y_cbp.w));\n"
+//this code is better but nor really working
+	/*	"  vec4 fmod_cbp_y=mod(cbp_vec,vec4(uv_cbp.zyx,y_cbp.w));\n"
 		"  vec2 fmod_cbp_uv=mod(cbp_vec.xy,y_cbp.zy);\n"
 		"  fmod_cbp_y=vec4(lessThanEqual(vec4(uv_cbp.yx,y_cbp.wz),fmod_cbp_y));\n"
 	    "  fmod_cbp_uv=vec2(lessThanEqual(y_cbp.yx,fmod_cbp_uv));\n"
@@ -95,16 +95,63 @@ const GLchar moco_vertex_shader[] =
 		"  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"
+		"  fmod_cbp_uv2.y+=fmod_cbp_uv2.x;\n"*/
+
+
+		"  float tcbp=cbp;\n"
+		"  float tpos=czero;\n"
+		"  vec4 fmod_cbp_y=vec4(czero,czero,czero,czero);\n"
+		"  vec2 fmod_cbp_uv=vec2(czero,czero);\n"
+		"  vec4 fmod_cbp_y2=vec4(czero,czero,czero,czero);\n"
+		"  vec2 fmod_cbp_uv2=vec2(czero,czero);\n"
+		"  if (tcbp>=uv_cbp.y){\n"
+		"    fmod_cbp_y.x=one;\n"
+		"    fmod_cbp_y2.x=tpos;\n"
+		"    tpos++;\n"
+		"    tcbp-=uv_cbp.y;\n"
+		"  }\n"
+		"  if (tcbp>=uv_cbp.x){\n"
+		"    fmod_cbp_y.y=one;\n"
+		"    fmod_cbp_y2.y=tpos;\n"
+		"    tpos++;\n"
+		"    tcbp-=uv_cbp.x;\n"
+		"  }\n"
+		"  if (tcbp>=y_cbp.w){\n"
+		"    fmod_cbp_y.z=one;\n"
+		"    fmod_cbp_y2.z=tpos;\n"
+		"    tpos++;\n"
+		"    tcbp-=y_cbp.w;\n"
+		"  }\n"
+		"  if (tcbp>=y_cbp.z){\n"
+		"    fmod_cbp_y.w=one;\n"
+		"    fmod_cbp_y2.w=tpos;\n"
+		"    tpos++;\n"
+		"    tcbp-=y_cbp.z;\n"
+		"  }\n"
+		"  if (tcbp>=y_cbp.y){\n"
+		"    fmod_cbp_uv.x=one;\n"
+		"    fmod_cbp_uv2.x=tpos;\n"
+		"    tpos++;\n"
+		"    tcbp-=y_cbp.y;\n"
+		"  }\n"
+		"  if (tcbp>=y_cbp.x){\n"
+		"    fmod_cbp_uv.y=one;\n"
+		"    fmod_cbp_uv2.y=tpos;\n"
+	//	"    tpos++;\n"
+	//	"    tcbp-=y_cbp.y;\n"
+		"  }\n"
+
+
+
+
+
+
+
 
 		// now calculate their position inside the short array
-		"  float m_index=index.x/*+index.y*c65536*/-one;\n" //Not Endian save
+		"  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"
 
 		"  out_yblockpos_y=floor((fmod_cbp_y2)*c1over32);\n"
 		"  out_uvblockpos_xy.zw=floor((fmod_cbp_uv2)*c1over32);\n"
@@ -117,14 +164,14 @@ const GLchar moco_vertex_shader[] =
 	//	"  out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n"
 	//	"  out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n"
 
-		"  out_yblockpos_y=mix(vec4(c1024,c1024,c1024,c1024)-one,out_yblockpos_y,fmod_cbp_y);\n"
-		"  out_uvblockpos_xy.zw=mix(vec2(c1024,c1024)-one,out_uvblockpos_xy.zw,fmod_cbp_uv);\n"
+		"  out_yblockpos_y=mix(vec4(c1024,c1024,c1024,c1024),out_yblockpos_y,fmod_cbp_y);\n"
+		"  out_uvblockpos_xy.zw=mix(vec2(c1024,c1024),out_uvblockpos_xy.zw,fmod_cbp_uv);\n"
 
 
 		// set start positions
-		"  vec4 motion_vertical=vec4(block_types.z,block_types.z,block_types.z,block_types.z);\n"
-		"  vec4 mod_motion_vertical=mod(motion_vertical,y_cbp);\n"
-		"  mod_motion_vertical=sign(vec4(mod_motion_vertical.yzw,block_types.z)-mod_motion_vertical);\n"
+	//	"  vec4 motion_vertical=vec4(block_types.z,block_types.z,block_types.z,block_types.z);\n"
+	//	"  vec4 mod_motion_vertical=mod(motion_vertical,vec4(y_cbp.yzw,uv_cbp.x));\n"
+	//	"  mod_motion_vertical=vec4(lessThanEqual(y_cbp,mod_motion_vertical));\n"
 
 		"  out_moco_pos.xy=(block_pos.xy+block_edge.xy)*uv_cbp.x/*16*/+one;"
 		"  out_unsupported=czero;\n"
@@ -150,18 +197,40 @@ const GLchar moco_vertex_shader[] =
 		"        out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n"
 		//"  	     out_unsupported=2.;\n"
 		"     } else if (block_types.y==y_cbp.x /*1*/) {" //Field
-		"        out_moco_forward=vec4(PMV1.xy,PMV1.xy);\n"
-		"        out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n"
-		"        out_moco_forward.y+=mod_motion_vertical.x;\n"
+		"        out_moco_forward=vec4(PMV1.xy,PMV2.xy);\n"
+		"        out_moco_backward=vec4(PMV1.zw,PMV2.zw);\n"
+
+		"        float motion_vert=block_types.z;\n"
+		"        out_moco_forward.w-=one;\n"
+		"        out_moco_backward.w-=one;\n"
+		"        if (motion_vert>= y_cbp.w) {\n" //second_backward
+		"            motion_vert-=y_cbp.w;\n"
+		"            out_moco_backward.w+=one;\n"
+		"         }\n"
+		"        if (motion_vert>= y_cbp.z) {\n" //second_forward
+		"            motion_vert-=y_cbp.z;\n"
+		"            out_moco_forward.w+=one;\n"
+		"         }\n"
+		"        if (motion_vert>= y_cbp.y) {\n" //first_backward
+		"            motion_vert-=y_cbp.y;\n"
+		"            out_moco_backward.y+=one;\n"
+		"         }\n"
+		"        if (motion_vert>= y_cbp.x) {\n" //second_forward
+		//"            motion_vert-=y_cbp.z;\n"
+		"            out_moco_forward.y+=one;\n"
+		"         }\n"
+	/*	"        out_moco_forward.y+=mod_motion_vertical.x;\n"
 		"        out_moco_backward.y+=mod_motion_vertical.y;\n"
 		"        out_moco_forward.w-=one-mod_motion_vertical.z;\n"
-		"        out_moco_backward.w-=one-mod_motion_vertical.w;\n"
+		"        out_moco_backward.w-=one-mod_motion_vertical.w;\n"*/
 		"         out_misc_info.y=one;\n" // step to for field based
 	//	"  	     out_unsupported=2.;\n"
 		"     } else {\n"
 		"  	     out_unsupported=1.;\n"
 		"     }\n"
 		"  }\n"
+	//	"   if (cbp==63. || cbp==0.) out_unsupported=2.;\n"
+	//	"   if (fmod_cbp_y.w==1. && mod(cbp,8.)>=4.) out_unsupported=2.;\n"
 
 
 
@@ -461,7 +530,7 @@ int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMa
 
 
 
-//	Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 glerror %x %d",glGetError(),height);
+	Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 %d %d %d",height,num_blocks,num_m_blocks);
 	glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
 		BLOCK_TEXTURE_WIDTH>>1,height,
 		GL_RGBA,GL_UNSIGNED_BYTE,
@@ -484,7 +553,10 @@ int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMa
 	XvMCMacroBlock *m_blocks_end=m_blocks+num_m_blocks;
 	while (m_blocks_run!=m_blocks_end) {
 		m_blocks_run->pad0=0xFF00;
+	//	Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks coded block %x %x %d",
+	//			m_blocks_run->coded_block_pattern, m_blocks_run->macroblock_type,m_blocks_run->index);
 		m_blocks_run++;
+
 	}
 	// debug
 /*	m_blocks[0].x=0;
@@ -605,7 +677,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
 		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));
+		glVertexAttribPointer(3, 1, GL_UNSIGNED_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);
@@ -630,7 +702,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
 
 
 		if (forward) {
-			Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo forward %x",forward->textures[0]);
+		//	Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo forward %x",forward->textures[0]);
 			glActiveTexture(GL_TEXTURE1);
 			glBindTexture(GL_TEXTURE_2D,forward->textures[0]);
 			glUniform1i(forward_pic_loc,1);
@@ -643,7 +715,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
 
 		if (backward) {
 			glActiveTexture(GL_TEXTURE2);
-			Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo backward %x",backward->textures[0]);
+		//	Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo backward %x",backward->textures[0]);
 			glBindTexture(GL_TEXTURE_2D,backward->textures[0]);
 			glUniform1i(backward_pic_loc,2);
 			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
diff --git a/osdopengl.cc b/osdopengl.cc
index f0bc96b..9ba5a4e 100755
--- a/osdopengl.cc
+++ b/osdopengl.cc
@@ -420,7 +420,7 @@ void OsdOpenGL::threadMethod()
 			if (!frame) frame=video->getReadyOGLFrame();
 			if (frame) {
 				InternalRendering(frame);
-			//	MILLISLEEP(1000);
+				//MILLISLEEP(1000);
 				lastrendertime=getTimeMS();
 				video->returnOGLFrame(frame); //please recycle it
 				frame=NULL;
diff --git a/vfeed.cc b/vfeed.cc
old mode 100644
new mode 100755
index 6640a13..b0fefab
--- a/vfeed.cc
+++ b/vfeed.cc
@@ -76,7 +76,7 @@ void VFeed::threadMethod()
     }
     else
     {
-      //Log::getInstance()->log("VFeed", Log::DEBUG, "No data delay");
+      //Log::getInstance()->log("VFeed", Log::DEBUG, "No data delay FPS");
       MILLISLEEP(5);
     }
   }
diff --git a/videovpeogl.cc b/videovpeogl.cc
index 1035ec2..2e24791 100755
--- a/videovpeogl.cc
+++ b/videovpeogl.cc
@@ -333,7 +333,7 @@ void VideoVPEOGL::recycleOGLRefFrames()
 	list<VPEOGLFrame*> keep;
 	list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
 	while (itty!=recycle_ref_ogl_frames.end()) {
-		Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
+	//	Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
 		if ((*itty)->pict_num==ogl_forward_ref_frame_num
 				|| (*itty)->pict_num==ogl_backward_ref_frame_num)
 		{
@@ -446,6 +446,7 @@ void VideoVPEOGL::threadMethod()
 				int width,height,pixfmt;
 				//First get a free ogl image
 				VPEOGLFrame* out_frame=NULL;
+				//int msleep=0;
 				while (!out_frame) {
 					ogl_frame_mutex.Lock();
 				//	Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
@@ -460,7 +461,13 @@ void VideoVPEOGL::threadMethod()
 						pixfmt=libavpixfmt;
 						out_frame=free_ogl_frames.front();
 						free_ogl_frames.pop_front();
-					} else MILLISLEEP(2);
+					} else {
+						ogl_frame_mutex.Unlock();
+						MILLISLEEP(2);
+					//	msleep+=2;
+						ogl_frame_mutex.Lock();
+					}
+				//	if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
 					ogl_frame_mutex.Unlock();
 				}
 				bool failed=false;
@@ -658,7 +665,7 @@ void VideoVPEOGL::threadMethod()
 				target_time.tv_sec+=1;
 			}
 			threadWaitForSignalTimed(&target_time);
-			//Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
+			//Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
 		}
 		threadCheckExit();
 	}
@@ -2460,6 +2467,7 @@ int VideoVPEOGL::DecodePacketlibav()
 			} else {
 				libav_hastime=false;
 				dec_frame_libav_mutex.Unlock();
+				Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
 				threadSignal();
 				// No free buffers
 				return 0;
@@ -2508,7 +2516,7 @@ UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
 			dec_frame_libav_free.pop_front();
 			dec_frame_libav_mutex.Unlock();
 		} else {
-			Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
+			Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
 			dec_frame_libav_mutex.Unlock();
 			// No free buffers
 			return 0;
-- 
2.39.5