www.pudn.com > wm2.5.zip > interpred.c


  /* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004, Advanced Audio Video Coding Standard, Part II 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
 
#include "define.h" 
#include "global.h" 
#include "motion_esti.h" 
#include "interpred.h" 
#include "macroblock.h" 
#include "rdopt.h" 
#include "block.h" 
#include "vlc.h" 
#include "IREG.h" 
 
#include  
#include  
#include  
 
#include  
 
extern MacroblockData   MbData, *pgMbData; 
extern int AffectedByLeftover(int x_pos, int y_pos, int ref); 
const int csiInter_Block_Size[4][2] = {{16,16},{16,8},{8,16},{8,8}}; 
const int csiInter_Subblk_Size[4][2] = {{8,8},{8,4},{4,8},{4,4}};    //qwang 2004-3-20 
const int BITSMBTYPE[6] = {1, 3, 3, 5, 5, 5};                        //qwang 2004-3-20 
const int BITSSUBBLKTYPE[4] = {1, 3, 3, 5};                          //qwang 2004-3-20 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Select one mode for sub block  
+ parameters     : void  
+ return		     : 8x8, 8x4, 4x8, 4x4 
+ descriptions   :  
+                   
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
int Subblk_Inter_Modes_Decision(int ref,int b8, int pic_pel_y, int pic_pel_x, int lambda_factor)      //qwang 2004-3-20 
{ 
    static int  bx0[4] = {0,2,0,2}; 
    static int  by0[4] = {0,0,2,2}; 
	int   mcost, mincost = 1<<20; 
	int   subblktype; 
	int   pic_block_y,pic_block_x; 
	int   b4; 
	int   v,h; 
	int   step_h; 
	int   step_v; 
	int   step_h0; 
	int   step_v0; 
	int   pic_pixel_x, pic_pixel_y; 
	int   j, i; 
	int   refframe=ref; 
	int   coeff_cost; 
	 
	for(subblktype=1; subblktype<=4; subblktype++) 
	{ 
		coeff_cost = 0; 
		mcost  = 0; 
		step_h0   = 2; 
		step_v0   = 2; 
		step_h    = (csiInter_Subblk_Size[subblktype-1][0]>>2); 
		step_v    = (csiInter_Subblk_Size[subblktype-1][1]>>2); 
		pic_pixel_x = pic_pel_x; 
		pic_pixel_y = pic_pel_y; 
		 
		for (v=by0[b8]; vmb_y*4 + v; 
			pic_pixel_y += (v-by0[b8]) * 4; 
			 
			for (h=bx0[b8]; hmb_x*4 + h; 
				pic_pixel_x += (h-bx0[b8])* 4; 
				 
				//--- motion search for block --- 
				b4 = (v-by0[b8]) * 2 + (h-bx0[b8]); 
				mcost += Subblock_Motion_Search (ref, b8,subblktype,b4,4*pic_block_y,4*pic_block_x,pic_pixel_y,pic_pixel_x,lambda_factor); 
				 
//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
                if (input.IREGEnable) 
                { 
                    mcost = min(mcost, 1<<30); 
                } 
#endif // _ISOLATED_REGION_ 
				 
				//--- set motion vectors and reference frame (for motion vector prediction) --- 
				for (j=0; jbest_mode_subblk_ref[ref][b8] = subblktype; 
			 
			Save_Subblk_Motion_Vector(subblktype, b8); 
		}			 
		 
		for(b4=0; b4<4; b4++) 
		{ 
			tmp_mv[0][pgMbData->mb_y*4 +((b8>>1)<<1) + (b4>>1)][pgMbData->mb_x*4 +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb_tmp[b8][b4][0]; 
			tmp_mv[1][pgMbData->mb_y*4 +((b8>>1)<<1) + (b4>>1)][pgMbData->mb_x*4 +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb_tmp[b8][b4][1]; 
			refFrArr  [pgMbData->mb_y*4 +((b8>>1)<<1) + (b4>>1)][pgMbData->mb_x*4 +((b8 &1)<<1) + (b4 &1)] = refframe; 
		}		 
         
		if(input.rdopt) 
			Save_Subblk_Motion_Vector_RDO(subblktype, b8, ref);	 
	} 
	 
	return mincost; 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Inter_Modes_Decision 
+ parameters     : void  
+ return		     : the best cost of inter modes including 16x16,16x8,8x16,8x8 
+ descriptions   : created  by xyji: 2004/02/12 
+                  modified by jhzheng: 2004/02/15 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
int Inter_Modes_Decision(void)         //qwang 2004-3-20  //zhangnan 
{ 
	int   mcost, mincost = 1<<20 ,mincost_ref = 1<<20,motion_cost_ref; 
	int   blocktype; 
	int   v,h; 
	int   b8, b4; 
	int   i,j; 
	int   pic_block_y,pic_block_x; 
	int   pic_pel_x, pic_pel_y; 
	int   step_h; 
	int   step_v; 
	int   min_ref = 0;   
	int   ref; 
	int   refframe;   
	int   max_ref     = pgImage->nb_references; 
	int   ref_ref; 
	int   lambda_factor; 
	int   subblktype; 
	int   best_ref; 
	int   coeff_cost; 
	int   rdcost, minrdcost; 
	int   rate, distortion; 
 
//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
	int m,n; 
	if(input.IREGEnable) 
	{ 
		for(i=0;i<2;i++) 
			for(j=0;j<4;j++) 
				for(m=0;m<4;m++) 
					for(n=0;n<4;n++) 
						typemap[i][j][m][n]=1;  //initial : enable  
	 } 
#endif //_ISOLATED_REGION_ 
 
	if(!input.rdopt) 
		lambda_factor = LAMBDA_FACTOR (pgMbData->lambda); 
	else 
		lambda_factor = LAMBDA_FACTOR(pgMbData->lamda_motion); 
 
//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
    if (input.IREGEnable) 
    { 
        if (iIREGState==input.IREGRate || iIREGState==2*input.IREGRate) 
        { 
             
                max_ref = 1;      
		} 
    }     
#endif // _ISOLATED_REGION_ 
 
	for(blocktype =1; blocktype <=4; blocktype ++) 
	{ 
		mcost = 0; 
		step_h    = (csiInter_Block_Size[blocktype-1][0]>>3); 
		step_v    = (csiInter_Block_Size[blocktype-1][1]>>3); 
		 
		for(v = 0 ; v < 2 ; v += step_v) 
		{ 
			pic_pel_y = pgMbData->mb_y * 16 + v * 8; 
			pic_block_y = pgImage->block_y + v * 2; 
			for( h = 0 ; h < 2 ; h += step_h) 
			{ 
				pic_pel_x = pgMbData->mb_x * 16 + h * 8; 
				pic_block_x = pgImage->block_x + h * 2; 
				b8 = v * 2 + h; 
				 
				mincost_ref = 1<<20; 
				 
				for (ref=min_ref; refmb_y][pgImage->mb_x] != 0) 
                        { 
                            iIntegerPixFlag = 0;  //initial: integer is disable 
                            iSubPixFlag1    = 1;  //subpix is disable   
                        } 
                        else 
                        { 
                             
                                iIntegerPixFlag = 1; 
                                iSubPixFlag1    = 0;   // leftover initial : integer and subpix all enable 
                        } 
                    } 
#endif // _ISOLATED_REGION_ 
					refframe  = ref; 
					motion_cost_ref = 0; 
					 
					if(blocktype < 4)          //16x16, 16x8, 8x16 Motion Estimation 
					{ 
						motion_cost_ref = Block_Motion_Search (ref,blocktype,b8,pic_pel_y,pic_pel_x,lambda_factor); 
					//cbzhu 0412 
#ifdef _ISOLATED_REGION_ 
                        if (input.IREGEnable) 
                        { 
                            if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
                            { 
                                if (iIntegerPixFlag == 0 || iSubPixFlag1 == 1) 
                                { 
									if(ref==0) 
									{ 
										if(blocktype==1) 
											for(m=0;m<4;m++) 
												for(n=0;n<4;n++) 
													typemap[0][blocktype-1][m][n]=0; 
										else if (blocktype==2) 
											for(m=0;m<2;m++) 
												for(n=0;n<4;n++) 
													typemap[0][blocktype-1][b8+m][n]=0; 
										else if (blocktype==3) 
											for(m=0;m<3;m+=2) 
												for(n=0;n<4;n++) 
													typemap[0][blocktype-1][b8+m][n]=0; 
												 
										if(max_ref==1) 
										{ 
											if(blocktype==1) 
												for(m=0;m<4;m++) 
													for(n=0;n<4;n++) 
														typemap[1][blocktype-1][m][n]=0; 
											else if (blocktype==2) 
												for(m=0;m<2;m++) 
													for(n=0;n<4;n++) 
														typemap[1][blocktype-1][b8+m][n]=0; 
											else if (blocktype==3) 
												for(m=0;m<3;m+=2) 
													for(n=0;n<4;n++) 
														typemap[1][blocktype-1][b8+m][n]=0; 
										} 
										motion_cost_ref = (1<<20)-1; 
									} 
									if(ref==1) 
									{ 
										if(blocktype==1) 
											for(m=0;m<4;m++) 
												for(n=0;n<4;n++) 
													typemap[1][blocktype-1][m][n]=0; 
										else if (blocktype==2) 
											for(m=0;m<2;m++) 
												for(n=0;n<4;n++) 
													typemap[1][blocktype-1][b8+m][n]=0; 
										else if (blocktype==3) 
											for(m=0;m<3;m+=2) 
												for(n=0;n<4;n++) 
													typemap[1][blocktype-1][b8+m][n]=0; 
										motion_cost_ref = (1<<20); 
									} 
								} 
                            } 
                        }                         
                         
#endif // _ISOLATED_REGION_ 
					} 
					else                       //P8x8 mode decision 
					{ 
						motion_cost_ref= Subblk_Inter_Modes_Decision (ref,b8,pic_pel_y,pic_pel_x,lambda_factor); 
					//cbzhu 0412 
#ifdef _ISOLATED_REGION_ 
                        if (input.IREGEnable) 
                        { 
                            if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
                            { 
                                if (iIntegerPixFlag == 0 || iSubPixFlag1 == 1) 
                                { 
									if(ref==0) 
									{ 
										for(n=0;n<4;n++)typemap[0][blocktype-1][b8][n]=0; 
										if(max_ref==1) 
													for(n=0;n<4;n++)typemap[1][blocktype-1][b8][n]=0; 
										motion_cost_ref = (1<<20)-1; 
									} 
									if(ref==1) 
									{ 
										for(n=0;n<4;n++)typemap[1][blocktype-1][b8][n]=0; 
										motion_cost_ref = (1<<20); 
									} 
                                } 
                            } 
                        } 
#endif // _ISOLATED_REGION_ 
					} 
					 
					if(blocktype < 4) 
						for (j=0; jmvb_ref[b8][b4][0] = pgMbData->mvb_tmp[b8][b4][0]; 
								pgMbData->mvb_ref[b8][b4][1] = pgMbData->mvb_tmp[b8][b4][1]; 
								pgMbData->pred_mv_ref[b8][b4][0] = pgMbData->pred_mv_tmp[b8][b4][0]; 
								pgMbData->pred_mv_ref[b8][b4][1] = pgMbData->pred_mv_tmp[b8][b4][1]; 
								ref_ref=refframe; 
							} 
						}//zhangnan 
					}//if (motion_cost_ref < mincost_ref) 
					else  
					{ 
						if (blocktype==1) 
						{//16x16 
							for (j=0; jblock_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb_ref[b8][b4][0]; 
								tmp_mv[1][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb_ref[b8][b4][1]; 
								refFrArr  [pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] = ref_ref; 
							} 
						}//zhangnan 
					}// if (motion_cost_ref < mincost_ref) //zhangnan 
				}  
				 
				if(input.rdopt) 
				{ 
					if(blocktype==4) 
					{ 
						minrdcost = 1<<20; 
						best_ref = refFrArr  [pgImage->block_y +((b8>>1)<<1) ][pgImage->block_x +((b8 &1)<<1) ]; 
						for(subblktype=1; subblktype<=4; subblktype++) 
						{ 
							coeff_cost = 0; 
							coeff_cost_4x4[0]=coeff_cost_4x4[1]=coeff_cost_4x4[2]=coeff_cost_4x4[3] = 0; // dongjie 
							for(b4 = 0; b4 < 4; b4++) 
							{ 
								pgMbData->mvb[b8][b4][0] = subblk_MV[subblktype][best_ref][b8][b4][0]; 
								pgMbData->mvb[b8][b4][1] = subblk_MV[subblktype][best_ref][b8][b4][1]; 
								pgMbData->pred_mv[b8][b4][0] = subblk_Pred_MV[subblktype][best_ref][b8][b4][0]; 
								pgMbData->pred_mv[b8][b4][1] = subblk_Pred_MV[subblktype][best_ref][b8][b4][1]; 
							} 
						 
							pgMbHeader->mb_type = 4;                       
							pgMbHeader->subblk_type[b8] = subblktype;      
							 
							Save_RD_State(); 
							 
							//bits for sub_blk mode 
							ue_linfo(subblktype-1); 
							 
							//Not: all zero ref: ref index 
							rate = 1; 
							 
							//--- Get MVD info --- 
							for(b4=0; b4<4; b4++) 
							{ 
								pgMbHeader->mvd[b8][b4][0] = pgMbData->mvb[b8][b4][0] - pgMbData->pred_mv[b8][b4][0]; 
								pgMbHeader->mvd[b8][b4][1] = pgMbData->mvb[b8][b4][1] - pgMbData->pred_mv[b8][b4][1]; 
							} 
							 
							Load_8x8_Residual(b8); 
 
							//WJP 040903 
							if(subblktype==1 && (!input.ABT_RDO) && input.ABT) 
							{ 
								abt_transform_B8(b8);																												 
								abt_quant_B8(pgMbData->qp_mb, b8, &coeff_cost);								 
							} 
							else 
							{ 
								for(b4=0; b4<4; b4++) 
								{ 
									Transform_B4(b8,b4); 
									Quant_B4(pgMbData->qp_mb, b8, b4, &coeff_cost); 
								} 
								// dongjie 
								if(pgMbHeader->cbp_4x4[b8]==0) 
									pgMbHeader->cbp &= (~(1<cbp |= (1<cbp &= (63 - (1<pred_residual[b8][b4][j][i] = 0; 
							} 
							// dongjie 
							else 
							{ 
								for(b4=0;b4<4;b4++) 
								{ 
									if(coeff_cost_4x4[b4] <= LUMACOEFFCOST4x4) 
									{ 
										pgMbHeader->cbp_4x4[b8] &= (15 - (1<pred_residual[b8][b4][j][i] = 0; 
									} 
								} 
							} 
							// end								 
							//WJP 040903 
							if(pgMbHeader->cbp & (1<cbp_4x4[b8] & (1<qp_mb,b8); 
								abt_Itransform_B8(b8);								 
							} 
							else 
							{ 
								for(b4=0;b4<4;b4++) 
								{ 
									Dequant_B4(pgMbData->qp_mb, b8, b4); 
									Inv_Transform_B4(b8, b4);									 
								} 
							} 
							for(b4=0; b4<4; b4++) 
							{ 
								Recon_B4(b8, b4, 0); 
								for(j=0; j<4; j++) 
									for(i=0; i<4; i++)	 
									{ 
										imgY[(pgMbData->mb_y<<4) + (b8/2)*8+(b4/2)*4+j][(pgMbData->mb_x<<4) + (b8%2)*8+(b4%2)*4+i] = imgY1[j][i];  
									} 
							} 
							//WJP END 
							rate += (pgcurrBitStream->byte_pos-pgRDStream->byte_pos)*8 +(pgRDStream->bits_to_go-pgcurrBitStream->bits_to_go);  
							Restore_RD_State(); 
							 
							distortion = 0; 
							for(j=(b8>>1)*8; j<(b8>>1)*8 + 8; j++) 
								for(i=(b8%2)*8; i<(b8%2)*8+8; i++)	 
								{ 
									distortion += quadarr[pgMbData->org_luma[j][i]-imgY[(pgMbData->mb_y<<4) + j][(pgMbData->mb_x<<4) + i]];  
								} 
								 
							rdcost = (int)(distortion + pgMbData->lamda_mode * rate); 
							 
							if(rdcostbest_mode_subblk[b8] = subblktype; 
								for(b4 = 0; b4 < 4; b4++) 
								{ 
									tmp_mv[0][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = subblk_MV[subblktype][best_ref][b8][b4][0]; 
									tmp_mv[1][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = subblk_MV[subblktype][best_ref][b8][b4][1]; 
								} 
							} 
						} 
					} 
				} 
				//sw 
				if(!input.rdopt) 
				{ 
					if (refFrArr  [pgImage->block_y +((b8>>1)<<1) ][pgImage->block_x +((b8 &1)<<1) ] ==0) 
						pgMbData->best_mode_subblk[b8] = pgMbData->best_mode_subblk_ref[0][b8]; 
					else 
						pgMbData->best_mode_subblk[b8] = pgMbData->best_mode_subblk_ref[1][b8]; 
				} 
			}					  
		} 
		 
		mcost += MODE_COST(lambda_factor, BITSMBTYPE[blocktype]);           //qwang 2004-3-24 
		 
		if(!input.rdopt) 
		{ 
			if(mcost < mincost) 
			{ 
				mincost  = mcost; 
				pgMbData->best_mode = blocktype; // P8x8 used when blocktype == 4  
         
				for(b8=0; b8<4; b8++) 
					for(b4=0; b4<4; b4++) 
					{ 
						refFrArr_tmp[pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] = refFrArr[pgImage->block_y+((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] ; 
					} 
           
				Save_Motion_Vector(blocktype); 
			} 
		} 
		else 
		{ 
			for(b8=0; b8<4; b8++) 
				for(b4=0; b4<4; b4++) 
				{ 
					sInter_Ref[blocktype][b8][b4] = refFrArr[pgImage->block_y+((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] ; 
				} 
			Save_Motion_Vector_RDO(blocktype, best_ref); 
		} 
	} 
 
	if(!input.rdopt) 
	{ 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				refFrArr[pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] = refFrArr_tmp[pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] ; 
			} 
	} 
 
 	return mincost; 
} 
 
 
int Subblock_Motion_Search(int ref, int b8, int subblktype, int b4, int picy, int picx, int pic_pel_y, int pic_pel_x, int lambda_factor)   //qwang 2004-3-20 
{ 
	int mincost = 1<<30 ; 
	int offx ,off_y , k; 
	int i,j; 
	int**     ref_array = refFrArr ; 
	int***    mv_array  = tmp_mv   ; 
	int       mb_x      = picx-pgImage->pix_x;  //zhangnan  2004-04-16 
	int       mb_y      = picy-pgImage->pix_y;    
	int       block_x   = (mb_x>>2); 
	int       block_y   = (mb_y>>2); 
	int       bsx       = csiInter_Subblk_Size[subblktype-1][0]; 
	int       bsy       = csiInter_Subblk_Size[subblktype-1][1];      //zhangnan  2004-04-16 
	int       pred_mv[2]; 
  int       xpos, ypos; 
 
  SetMotionVectorPredictor(pred_mv, ref, mb_x, mb_y, bsx, bsy); 
	 
	sInter_Pred_MV[b8][b4][0] = pred_mv[0]; 
	sInter_Pred_MV[b8][b4][1] = pred_mv[1];  //zhangnan 
	 
	//--- Integer MV from Prediction 
	sInteger_MV[0] = sInter_Pred_MV[b8][b4][0] / 4 ; // >>2 OR /4 ???  
	sInteger_MV[1] = sInter_Pred_MV[b8][b4][1] / 4 ;   
	 
    //--- adjust search center so that the (0,0)-vector is inside --- 
	sInteger_MV[0] = max (-SEARCHRANGE, min (SEARCHRANGE, sInteger_MV[0])); 
	sInteger_MV[1] = max (-SEARCHRANGE, min (SEARCHRANGE, sInteger_MV[1])); 
 
	//--- get residual MV info  
	sResidual_MV[0] = sInter_Pred_MV[b8][b4][0] - sInteger_MV[0]*4; 
	sResidual_MV[1] = sInter_Pred_MV[b8][b4][1] - sInteger_MV[1]*4; 
 
	offx = off_y = 0; 
  ypos = sInteger_MV[1]  + pic_pel_y; 
  xpos = sInteger_MV[0]  + pic_pel_x; 
   
#ifndef _FULL_SEARCH_ 
	mincost = FME_Integer_Pel_Block_Motion_Search(ref, offx,off_y,b8, P8x8, b4, subblktype, mincost,lambda_factor, ypos, xpos); 
#else 
	mincost = Full_Integer_Pel_Block_Motion_Search(ref,offx,off_y,b8, P8x8, b4,subblktype,mincost,lambda_factor, ypos, xpos); 
#endif 
 
  if(input.hadamard) 
	  mincost = 1<<20; 
   
    ypos = 	sInteger_MV[1]*4 + sInter_MV[b8][b4][1] -  
    QUARTER_CENTER_OFFSET + (pic_pel_y << 2); 
    xpos = sInteger_MV[0]*4 + sInter_MV[b8][b4][0] -  
    QUARTER_CENTER_OFFSET + (pic_pel_x << 2); 
   
#ifndef _FULL_SEARCH_ 
	mincost = FME_Sub_Pel_Block_Motion_Search(ref, 0,0, b8, b4, subblktype,mincost,lambda_factor, ypos, xpos); 
#else 
	mincost = Sub_Pel_Block_Motion_Search(ref,0,0,b8, P8x8,b4,subblktype,mincost,lambda_factor,ypos, xpos); 
#endif 
 
	sInter_MV[b8][b4][0] += sInteger_MV[0]*4 - (offx  << 2);	//sInter_Pred_MV[blockindex][0]/4*4; 
	sInter_MV[b8][b4][1] += sInteger_MV[1]*4 - (off_y << 2);	//sInter_Pred_MV[blockindex][1]/4*4; 
 
  if(subblktype == 1) 
  { 
    for(k=0; k<4; k++) 
    { 
      sInter_MV[b8][k][0] = sInter_MV[b8][0][0]; 
      sInter_MV[b8][k][1] = sInter_MV[b8][0][1]; 
    } 
  } 
  else if(subblktype == 2) 
  { 
    sInter_MV[b8][b4+1][0] = sInter_MV[b8][b4][0]; 
    sInter_MV[b8][b4+1][1] = sInter_MV[b8][b4][1]; 
  } 
  else if(subblktype == 3) 
  {     
    sInter_MV[b8][b4+2][0] = sInter_MV[b8][b4][0]; 
    sInter_MV[b8][b4+2][1] = sInter_MV[b8][b4][1]; 
  } 
 
  for (i=0; i < (bsx>>2); i++) 
	{ 
		for (j=0; j < (bsy>>2); j++) 
		{ 
			all_mv[block_x+i][block_y+j][subblktype+3][0] = sInter_MV[b8][b4][0]; 
			all_mv[block_x+i][block_y+j][subblktype+3][1] = sInter_MV[b8][b4][1]; 
		} 
	} 
 
	return mincost; 
} 
 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Block_Motion_Search 
+ parameters 1   : blocktype (mode type)  
+ parameters 2   : blockindex(block index based on blocktype) 
+ return 		 : cost of the current block 
+ descriptions   : created  by xyji: 2004/02/12 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
int Block_Motion_Search(int ref, int blktype, int blkindex, int pic_pel_y, int pic_pel_x, int lambda_factor)   //qwang 2004-3-20 
{ 
	int mincost = 1<<30 , cost ; 
	int offx ,off_y ; 
	int i,j; 
	int       mb_x      = pic_pel_x-pgImage->pix_x;  //zhangnan  2004-04-16 
	int       mb_y      = pic_pel_y-pgImage->pix_y;    
	int       block_x   = (mb_x>>2); 
	int       block_y   = (mb_y>>2); 
	int       bsx       = csiInter_Block_Size[blktype-1][0]; 
	int       bsy       = csiInter_Block_Size[blktype-1][1];      //zhangnan  2004-04-16 
	int       pred_mv[2]; 
	int       ypos, xpos; 
	//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
	int ireg_flag ; 
	int x,y,refx,refy; 
#endif //_ISOLATED_REGION_ 
 
	SetMotionVectorPredictor(pred_mv,ref, mb_x, mb_y, bsx, bsy); 
 
	sInter_Pred_MV[blkindex][0][0] = pred_mv[0]; 
	sInter_Pred_MV[blkindex][0][1] = pred_mv[1]; 
 
	//--- Integer MV from Prediction 
	sInteger_MV[0] = sInter_Pred_MV[blkindex][0][0] / 4 ; // >>2 OR /4  
	sInteger_MV[1] = sInter_Pred_MV[blkindex][0][1] / 4 ; 
	 
  //--- adjust search center so that the (0,0)-vector is inside --- 
	sInteger_MV[0] = max (-SEARCHRANGE, min (SEARCHRANGE, sInteger_MV[0])); 
	sInteger_MV[1] = max (-SEARCHRANGE, min (SEARCHRANGE, sInteger_MV[1])); 
 
	//--- get residual MV info  
	sResidual_MV[0] = sInter_Pred_MV[blkindex][0][0] - sInteger_MV[0]*4; 
	sResidual_MV[1] = sInter_Pred_MV[blkindex][0][1] - sInteger_MV[1]*4; 
 
	offx = off_y = 0; 
	ypos = sInteger_MV[1]  + pic_pel_y; 
	xpos = sInteger_MV[0]  + pic_pel_x; 
 
#ifndef _FULL_SEARCH_ 
	mincost = FME_Integer_Pel_Block_Motion_Search(ref,offx,off_y,blkindex,blktype,0, 3 , mincost,lambda_factor, ypos, xpos); 
#else 
	mincost = Full_Integer_Pel_Block_Motion_Search(ref,offx,off_y,blkindex,blktype,0,-1,mincost,lambda_factor, ypos, xpos); 
#endif                                                               
//cbzhu 0412 
#ifdef _ISOLATED_REGION_ 
    if (input.IREGEnable) 
    { 
        if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
        { 
            if (iIntegerPixFlag == 0) 
            {    
                return (1 << 30); 
            } 
        } 
 
    } 
     
#endif // _ISOLATED_REGION_ 
    ypos = sInteger_MV[1]*4 + sInter_MV[blkindex][0][1] -  
    QUARTER_CENTER_OFFSET + (pic_pel_y << 2); 
    xpos = sInteger_MV[0]*4 + sInter_MV[blkindex][0][0] -  
    QUARTER_CENTER_OFFSET + (pic_pel_x << 2); 
   
#ifndef _FULL_SEARCH_ 
	 
	if(input.hadamard) 
		mincost = 1<<20; 
	mincost = Sub_Pel_Block_Motion_Search(ref,0,0,blkindex,blktype,0,-1,mincost,lambda_factor, ypos, xpos); 
 
#else 
 
	if(input.hadamard) 
		mincost = 1<<20; 
	mincost = Sub_Pel_Block_Motion_Search(ref,0,0,blkindex,blktype,0,-1,mincost,lambda_factor, ypos, xpos); 
#endif 
	//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
    if (input.IREGEnable) 
    { 
        if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
        { 
            if (iSubPixFlag1 == 1) 
            { 
                return (1 << 30); 
            } 
        } 
    } 
     
#endif // _ISOLATED_REGION_ 
	 
	// Get the Skip Mode cost by jhzheng [16:25 2004/02/27] 
	if ((blktype == 1) && (ref==0)) 
	{ 
		Find_SkipMode_MotionVector(); 
     
		ypos = sSkip_MV[1] - QUARTER_CENTER_OFFSET + (pic_pel_y << 2); 
		xpos = sSkip_MV[0] - QUARTER_CENTER_OFFSET + (pic_pel_x << 2); 
		cost = Get_SkipCostMB(ref,0,0,mincost, ypos, xpos); 
		//cbzhu 12-15 
#ifdef _ISOLATED_REGION_ 
        if (input.IREGEnable) 
        { 
            if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
            { 
                ireg_flag = 0; 
                for (y = 0; y < MB_BLOCK_SIZE; y++) 
                {         
                    for (x = 0; x < MB_BLOCK_SIZE; x++) 
                    { 
                        refx = (pic_pel_x << 2) + ( x << 2 ) + sSkip_MV[0]; 
                        refy = (pic_pel_y << 2) + ( y << 2 ) + sSkip_MV[1]; 
                        ireg_flag = AffectedByLeftover(refx, refy, ref); 
                        if ( ireg_flag ) 
                        { 
                            break; 
                        } 
                         
                    } 
                    if ( ireg_flag ) 
                    { 
                        break; 
                    } 
                } 
 
                 
                if ( ireg_flag )  
                { 
                    cost = 1<<30; 
                } 
            } 
        }//if (input->IREGEnable) 
         
#endif // _ISOLATED_REGION_ 
		 
		if (cost < mincost) 
		{ 
			mincost = cost; 
			sInter_MV[blkindex][0][0] = sSkip_MV[0]; 
			sInter_MV[blkindex][0][1] = sSkip_MV[1]; 
 
			// must set sInter_MV = sInter_Pred_MV !!! 
			sInteger_MV[0] = sInteger_MV[1] = 0; 
			offx = off_y = 0; 
		}	 
	} 
 
	sInter_MV[blkindex][0][0] += sInteger_MV[0]*4 - (offx  << 2);	//sInter_Pred_MV[blockindex][0]/4*4; 
	sInter_MV[blkindex][0][1] += sInteger_MV[1]*4 - (off_y << 2);	//sInter_Pred_MV[blockindex][1]/4*4; 
	 
	for (i=0; i < (bsx>>2); i++) 
	{ 
		for (j=0; j < (bsy>>2); j++) 
		{ 
			all_mv[block_x+i][block_y+j][blktype][0] = sInter_MV[blkindex][0][0]; 
			all_mv[block_x+i][block_y+j][blktype][1] = sInter_MV[blkindex][0][1]; 
		} 
	} 
 
	return mincost; 
} 
 
 
/*! 
 *********************************************************************** 
 * \brief 
 *    setting the motion vector predictor 
 *********************************************************************** 
 */ 
void 
SetMotionVectorPredictor (int  pmv[2],           //zhangnan 
                          int  ref_frame, 
                          int  mb_x, 
                          int  mb_y, 
                          int  blockshape_x, 
                          int  blockshape_y) 
{ 
  int pic_block_x          = pgImage->block_x + (mb_x>>2); 
  int pic_block_y          = pgImage->block_y + (mb_y>>2); 
  int mb_width             = pgImage->img_width/16; 
  //WJP FOR SLICE 
  int mb_available_up      = (pgImage->mb_y == 0          ) ? 0 :  
							 (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-mb_width].slice_nr); 
  int mb_available_left    = (pgImage->mb_x == 0          ) ? 0 :  
							 (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-1].slice_nr); 
  int mb_available_upleft  = (pgImage->mb_x == 0 || pgImage->mb_y == 0) ? 0 : 
							 (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-mb_width-1].slice_nr); 
  int mb_available_upright = (pgImage->mb_x >= mb_width-1 || pgImage->mb_y == 0) ? 0 : 
							 (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-mb_width+1].slice_nr); 
  //WJP END 
  int block_available_up, block_available_left, block_available_upright, block_available_upleft; 
  int mv_a, mv_b, mv_c, mv_d, pred_vec[2]; 
  int mvPredType, rFrameL, rFrameU, rFrameUR; 
  int hv; 
  int a_c, b_c, a_b;//qhg 
  int ABC;//qhg 
  int a[2],b[2],c[2];//qhg 
 
  // D B C  
  // A X    
   
  // 1 A, B, D are set to 0 if unavailable        
  // 2 If C is not available it is replaced by D  
  block_available_up   = mb_available_up   || (mb_y > 0); 
  block_available_left = mb_available_left || (mb_x > 0); 
 
  if (mb_y > 0) 
  { 
    if (mb_x < 8)  // first column of 8x8 blocks 
    { 
      if (mb_y==8) 
      { 
        if (blockshape_x == 16)      block_available_upright = 0; 
        else                         block_available_upright = 1; 
      } 
      else 
      { 
        if (mb_x+blockshape_x != 8)  block_available_upright = 1; 
        else                         block_available_upright = 0; 
      } 
    } 
    else 
    { 
      if (mb_x+blockshape_x != 16)   block_available_upright = 1; 
      else                           block_available_upright = 0; 
    } 
  } 
  else if (mb_x+blockshape_x != MB_BLOCK_SIZE) 
  { 
    block_available_upright = block_available_up; 
  } 
  else 
  { 
    block_available_upright = mb_available_upright; 
  } 
   
  if (mb_x > 0) 
  { 
    block_available_upleft = (mb_y > 0 ? 1 : block_available_up); 
  } 
  else if (mb_y > 0) 
  { 
    block_available_upleft = block_available_left; 
  } 
  else 
  { 
    block_available_upleft = mb_available_upleft; 
  } 
   
  mvPredType = MVPRED_MEDIAN; 
//  rFrameL    = block_available_left    ? refFrArr[pic_block_y]  [pic_block_x-1] : -1; 
  rFrameL    = block_available_left    ? refFrArr[pic_block_y+blockshape_y/4 -1]  [pic_block_x-1] : -1; //JX 05-4-1 
  rFrameU    = block_available_up      ? refFrArr[pic_block_y-1][pic_block_x]   : -1; 
  //added by MZ 
  if(block_available_upright)  
    block_available_upright  = block_available_upright && (refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4]!=-1); 
  if(block_available_upleft) 
    block_available_upleft = block_available_upleft && (refFrArr[pic_block_y-1][pic_block_x-1 ]!=-1); 
   
  rFrameUR   = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] : 
               block_available_upleft  ? refFrArr[pic_block_y-1][pic_block_x-1] : -1; 
   
  //Prediction if only one of the neighbors uses the reference frame 
  if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) 
    mvPredType = MVPRED_L; 
  else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) 
    mvPredType = MVPRED_U; 
  else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) 
    mvPredType = MVPRED_UR; 
  // Directional predictions  
  else if(blockshape_x == 8 && blockshape_y == 16) 
  { 
    if(mb_x == 0) 
    { 
      if(rFrameL == ref_frame) 
        mvPredType = MVPRED_L; 
    } 
    else 
    { 
      if(rFrameUR == ref_frame) 
        mvPredType = MVPRED_UR; 
    } 
  } 
  else if(blockshape_x == 16 && blockshape_y == 8) 
  { 
    if(mb_y == 0) 
    { 
      if(rFrameU == ref_frame) 
        mvPredType = MVPRED_U; 
    } 
    else 
    { 
      if(rFrameL == ref_frame) 
        mvPredType = MVPRED_L; 
    } 
  } 
   
#define MIN(a,b,c) (ab?a>c?a:c:b>c?b:c)//WJP FOR MV prediction 050320 
  a_b=a_c=b_c=0; 
  //printf("%d \n" , pgImage->current_mb_nr); 
  for (hv=0; hv < 2; hv++) 
  { 
    //mv_a = block_available_left    ? tmp_mv[hv][pic_block_y  ][4+pic_block_x-1]              : 0; 
	mv_a = block_available_left    ? tmp_mv[hv][pic_block_y + (blockshape_y/4) -1 ][4+pic_block_x-1]: 0; 
    mv_b = block_available_up      ? tmp_mv[hv][pic_block_y-1][4+pic_block_x]                : 0; 
    mv_d = block_available_upleft  ? tmp_mv[hv][pic_block_y-1][4+pic_block_x-1]              : 0; 
    mv_c = block_available_upright ? tmp_mv[hv][pic_block_y-1][4+pic_block_x+blockshape_x/4] : mv_d; 
	//qhg 
	a[hv] = mv_a; 
	b[hv] = mv_b; 
	c[hv] = mv_c; 
    a_b+= abs(mv_a-mv_b); 
	a_c+= abs(mv_a-mv_c); 
	b_c+= abs(mv_b-mv_c); 
   
    switch (mvPredType) 
    { 
    case MVPRED_MEDIAN: 
/*WJP FOR MV prediction 050320 
      if(!(block_available_upleft || block_available_up || block_available_upright)) 
        pred_vec[hv] = mv_a; 
      else 
	  { //qhg		   
		  if(hv==1) 
		  { 
			  ABC = MIN(a_b,a_c,b_c); 
			   
			  if(ABC==a_b) 
			  { 
				  if(ABC==a_c) 
				  { 
					  pred_vec[0] = a[0]; 
					  pred_vec[1] = a[1]; 
				  } 
				  else if(ABC==b_c) 
				  { 
					  pred_vec[0] = b[0]; 
					  pred_vec[1] = b[1]; 
				  } 
				  else 
				  { 
					  pred_vec[0] = (a[0]+b[0]+1)>>1; 
					  pred_vec[1] = (a[1]+b[1]+1)>>1; 
				  } 
			  } 
			  else if(ABC==a_c) 
			  { 
				  if(ABC==b_c) 
				  { 
					  pred_vec[0] = c[0]; 
					  pred_vec[1] = c[1];			 
				  } 
				  else 
				  { 
					  pred_vec[0] = (a[0]+c[0]+1)>>1; 
					  pred_vec[1] = (a[1]+c[1]+1)>>1; 
				  } 
			  } 
			  else 
			  { 
				  pred_vec[0] = (b[0]+c[0]+1)>>1; 
				  pred_vec[1] = (b[1]+c[1]+1)>>1; 
			  } 
		  } 
	  } 
*/ 
		if(hv == 1) 
		{ 
			ABC = MAX(a_b,a_c,b_c); 
			if(ABC == a_b) 
			{ 
				pred_vec[0] = c[0]; 
				pred_vec[1] = c[1]; 
			} 
			else if(ABC == b_c) 
			{ 
				pred_vec[0] = a[0]; 
				pred_vec[1] = a[1]; 
			} 
			else 
			{ 
				pred_vec[0] = b[0]; 
				pred_vec[1] = b[1]; 
			} 
		} 
		//WJP END 
		break; 
       
    case MVPRED_L: 
      pred_vec[hv] = mv_a; 
      break; 
    case MVPRED_U: 
      pred_vec[hv] = mv_b; 
      break; 
    case MVPRED_UR: 
      pred_vec[hv] = mv_c; 
      break; 
    default: 
      break; 
    }     
  } 
   
  if ( pgImage->half_pixel_mv_flag == 0) // 1/4 MV 
  { 
      pmv[0] = pred_vec[0]; //qhg 
      pmv[1] = pred_vec[1]; 
  } 
  else // 1/2 MV 
  { 
      pmv[0] = pred_vec[0] << 1; //qhg 
      pmv[1] = pred_vec[1] << 1; 
  } 
 
#undef MIN 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Get_SkipModeMB 
+ parameters     : void 
+ return		 : int 
+ descriptions   : Get cost for skip mode of a macroblock 
+				   created  by  jhzheng : 2004/02/27 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
int Get_SkipCostMB(int ref, int cand_x, int cand_y, int mincost, int ypos, int xpos) 
{ 
	int cost = -(pgMbData->lambda<<3); 
    int diff[16]; 
	int y,x,i,j, k; 
	int refy,refx,oriy,orix; 
  int y_pos, x_pos; 
  int width4  = (pgImage->img_width  + (PAD_SIZE<<1) - 1)<<2; 
  int height4 = (pgImage->img_height + (PAD_SIZE<<1) - 1)<<2; 
	 
	pgMbData->skip_cost = 0; 
 
	for (y=0; y<16; y+=4) 
	{ 
		oriy = y; 
		refy = QUARTER_CENTER_OFFSET + cand_y + (y<<2); 
		for (x=0; x<16; x+=4) 
		{ 
			orix = x; 
			refx = QUARTER_CENTER_OFFSET + cand_x + (x<<2); 
			k = 0; 
      if(!input.hadamard) 
      { 
        for(j=0; j<4; j++) 
          for(i = 0 ; i < 4 ; i ++) 
          { 
            y_pos = ypos+ QUARTER_CENTER_OFFSET+ (j<<2) + cand_y + (y<<2) + (PAD_SIZE<<2); 
            x_pos = xpos+ QUARTER_CENTER_OFFSET+ (i<<2) + cand_x + (x<<2) + (PAD_SIZE<<2); 
             
            x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4  + (x_pos & 3)) : x_pos; 
            y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; 
 
            cost += absm(pgMbData->org_luma[oriy+j][orix+i] -  
              reference_quater_pel_frame[ref][y_pos][x_pos]);   //???? qwang 2004-3-21 
            pgMbData->skip_cost += quadarr[pgMbData->org_luma[oriy+j][orix+i] -  
              reference_quater_pel_frame[ref][y_pos][x_pos]];  
          } 
      }else 
      { 
        for(j=0; j<4; j++) 
          for(i = 0 ; i < 4 ; i++) 
          { 
            y_pos = ypos+ QUARTER_CENTER_OFFSET+ (j<<2) + cand_y + (y<<2) + (PAD_SIZE<<2); 
            x_pos = xpos+ QUARTER_CENTER_OFFSET+ (i<<2) + cand_x + (x<<2) + (PAD_SIZE<<2); 
             
            x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4  + (x_pos & 3)) : x_pos; 
            y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; 
             
            diff[k++] = (pgMbData->org_luma[oriy+j][orix+i] -  
              reference_quater_pel_frame[ref][y_pos][x_pos]);   //???? qwang 2004-3-21 
            pgMbData->skip_cost += quadarr[pgMbData->org_luma[oriy+j][orix+i] -  
               reference_quater_pel_frame[ref][y_pos][x_pos]];  
          } 
          cost += SATD(diff); 
      } 
    } 
		if (cost > mincost) 
		{ 
			break; 
		} 
	} 
 
	return cost; 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Get skip mode rd cost 
+ parameters     : void 
+ return		 : int 
+ descriptions   : Get cost for skip mode of a macroblock 
+				    
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Get_Skip_RD_Cost_MB() 
{ 
	int i, j; 
	int b8, b4; 
	int rate1, rate2; 
 
	for(j=0; j<4; j++) 
	for(i=0; i<4; i++) 
	{ 
		pgMbData->mvb[j][i][0] = sSkip_MV[0]; 
		pgMbData->mvb[j][i][1] = sSkip_MV[1];  
		tmp_mv[0][pgMbData->mb_y*4+j][pgMbData->mb_x*4+i+4] = sSkip_MV[0]; 
		tmp_mv[1][pgMbData->mb_y*4+j][pgMbData->mb_x*4+i+4] = sSkip_MV[1]; 
	}		 
	 
	for(b8=0; b8<4; b8++) 
		for(b4=0; b4<4; b4++) 
		{ 
			refFrArr[pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)]=0; 
		} 
 
	Load_Ref_Luma(); 
	Load_Ref_Chroma(); 
	 
	for(b8 = 4 ; b8 < 6 ; b8++) 
	{ 
		for (j=0; j<8; j++) 
		{ 
			for (i=0; i<8; i++) 
			{ 
				pgMbData->pred_sample[b8][i/4+(j/4)*2][j%4][i%4] = pgMbData->pred_sample_c[b8][j][i]; 
				pgMbData->skip_cost += quadarr[pgMbData->org_chroma[b8-4][j][i]-pgMbData->pred_sample_c[b8][j][i]]; 
			} 
		} 
	} 
 
	Save_RD_State(); 
	rate2 = ue_linfo(pgImage->cod_counter);	 
	rate1 = ue_linfo(pgImage->cod_counter+1); 
	Restore_RD_State(); 
	 
	//pgMbData->skip_cost += pgMbData->lamda_mode*(rate2-rate1);//WJP 
	pgMbData->skip_cost += pgMbData->lamda_mode*(rate1-rate2); 
	 
	//cbzhu 
#ifdef _ISOLATED_REGION_ 
    if (input.IREGEnable) 
    { 
        int ireg_flag; 
        int y, x; 
        int refx, refy; 
        int pic_pel_x, pic_pel_y; 
        pic_pel_x = pgImage->mb_x * MB_BLOCK_SIZE; 
        pic_pel_y = pgImage->mb_y * MB_BLOCK_SIZE; 
 
        if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) 
        { 
            ireg_flag = 0; 
            for (y = 0; y < MB_BLOCK_SIZE; y++) 
            {         
                for (x = 0; x < MB_BLOCK_SIZE; x++) 
                { 
                    refx = (pic_pel_x << 2) + ( x << 2 ) + sSkip_MV[0]; 
                    refy = (pic_pel_y << 2) + ( y << 2 ) + sSkip_MV[1]; 
                    ireg_flag = AffectedByLeftover(refx, refy, 0); 
                    if ( ireg_flag ) 
                    { 
                        break; 
                    } 
                } 
                if ( ireg_flag ) 
                { 
                    break; 
                } 
            } 
            if ( ireg_flag )  
            { 
                pgMbData->skip_cost = 1<<30; 
            } 
        } 
    }//if (input->IREGEnable) 
#endif // _ISOLATED_REGION_ 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : FindSkipModeMotionVector 
+ parameters     : void 
+ return		 : void 
+ descriptions   : Find motion vector for the Skip mode 
+				   created  by  jhzheng : 2004/02/27 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Find_SkipMode_MotionVector(void)     //zhangnan  
  { 
	  int pmv[2]; 
	  int mb_available_up   = (pgMbData->mb_y == 0)  ? 0 : (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-pgImage->img_width/16].slice_nr);//WJP FOR SLICE 
	  int mb_available_left = (pgMbData->mb_x == 0)  ? 0 : (pgMbData->slice_nr == pgImage->mb_data_forlf[pgImage->current_mb_nr-1].slice_nr);//WJP FOR SLICE 
	  int zeroMotionAbove   = !mb_available_up  ? 1 : refFrArr[pgImage->block_y-1][pgImage->block_x]  == 0 && tmp_mv[0][pgImage->block_y-1][4+pgImage->block_x  ] == 0 && tmp_mv[1][pgImage->block_y-1][4+pgImage->block_x  ] == 0 ? 1 : 0; 
	  //int zeroMotionLeft    = !mb_available_left? 1 : refFrArr[pgImage->block_y][pgImage->block_x-1]  == 0 && tmp_mv[0][pgImage->block_y+][4+pgImage->block_x-1] == 0 && tmp_mv[1][pgImage->block_y][4+pgImage->block_x-1] == 0 ? 1 : 0; 
    // MZ 050403 
    int zeroMotionLeft    = !mb_available_left? 1 : refFrArr[pgImage->block_y+BLOCK_SIZE-1][pgImage->block_x-1]  == 0 && tmp_mv[0][pgImage->block_y+BLOCK_SIZE-1][4+pgImage->block_x-1] == 0 && tmp_mv[1][pgImage->block_y+BLOCK_SIZE-1][4+pgImage->block_x-1] == 0 ? 1 : 0; 
	   
    if (zeroMotionAbove || zeroMotionLeft) 
    { 
      sSkip_MV[0] = sSkip_MV[1] = 0; 
    } 
    else 
    { 
      SetMotionVectorPredictor(pmv,0, 0,0, 16, 16); 
       
      sSkip_MV[0] = pmv[0]; 
      sSkip_MV[1] = pmv[1]; 
    } 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : Init_Inter_Image 
+ parameters     : void 
+ return		 : void 
+ descriptions   : created  by xyji & jhzheng : 2004/02/12 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Init_Inter_Sequence(void) 
{	 
	int k, l, i, bits, imin, imax; 
	 
	int number_of_subpel_positions = 4 * (2 * SEARCHRANGE + 3); 
	int max_mv_bits                = 3 + 2 * (int)ceil (log(number_of_subpel_positions+1) / log(2) + 1e-10); 
	int max_mvd                    = (1<<( max_mv_bits >>1)   )-1; 
		 
	if ((gMV_Bits = (short*)calloc(2*max_mvd+1, sizeof(short))) == NULL) 
		printf("Init_Inter_Sequence: mvbits");	 
 
	//--- set array offsets --- 
	gMV_Bits   += max_mvd; 
	//--- init array: motion vector bits --- 
	gMV_Bits[0] = 1; 
	 
	for (bits=3; bits<=max_mv_bits; bits+=2) 
	{ 
		imax = 1    << (bits >> 1); 
		imin = imax >> 1; 
		 
		for (i = imin; i < imax; i++) 
			gMV_Bits[-i] = gMV_Bits[i] = bits; 
	} 
 
	pgMbData->Spiral_index[0][0] = pgMbData->Spiral_index[0][1] = 0; 
#ifdef _FULL_SEARCH_ 
	// when use Full Search Algorithm, l value <= SearchRange 
	for (k=1, l=1; l<=SEARCHRANGE; l++) 
#else 
	//          5x5 : 2*2 + 1 
	// when use Fast Search Algorithm, l value <= 2 OK 
	for (k=1, l=1; l<=2; l++) 
#endif 
	{ 
		for (i=-l+1; i< l; i++) 
		{ 
			pgMbData->Spiral_index[k][0] =  i;  pgMbData->Spiral_index[k++][1] = -l; 
			pgMbData->Spiral_index[k][0] =  i;  pgMbData->Spiral_index[k++][1] =  l; 
		} 
		for (i=-l;   i<=l; i++) 
		{ 
			pgMbData->Spiral_index[k][0] = -l;  pgMbData->Spiral_index[k++][1] =  i; 
			pgMbData->Spiral_index[k][0] =  l;  pgMbData->Spiral_index[k++][1] =  i; 
		} 
	} 
 
	pgMbData->Diamond_index[0][0] = -1;		pgMbData->Diamond_index[0][1] =  0; 
	pgMbData->Diamond_index[1][0] =  0;		pgMbData->Diamond_index[1][1] =  1; 
	pgMbData->Diamond_index[2][0] =  1;		pgMbData->Diamond_index[2][1] =  0; 
	pgMbData->Diamond_index[3][0] =  0;		pgMbData->Diamond_index[3][1] = -1; 
 
	pgMbData->Hexagon_index[0][0] =  2;		pgMbData->Hexagon_index[0][1] =  0; 
	pgMbData->Hexagon_index[1][0] =  1;		pgMbData->Hexagon_index[1][1] = -2; 
	pgMbData->Hexagon_index[2][0] = -1;		pgMbData->Hexagon_index[2][1] = -2; 
	pgMbData->Hexagon_index[3][0] = -2;		pgMbData->Hexagon_index[3][1] =  0; 
	pgMbData->Hexagon_index[4][0] = -1;		pgMbData->Hexagon_index[4][1] =  2; 
	pgMbData->Hexagon_index[5][0] =  1;		pgMbData->Hexagon_index[5][1] =  2; 
 
	pgMbData->BigHexagon_index[ 0][0] =  0;	pgMbData->BigHexagon_index[ 0][1] =  4; 
	pgMbData->BigHexagon_index[ 1][0] = -2;	pgMbData->BigHexagon_index[ 1][1] =  3; 
	pgMbData->BigHexagon_index[ 2][0] = -4;	pgMbData->BigHexagon_index[ 2][1] =  2; 
	pgMbData->BigHexagon_index[ 3][0] = -4;	pgMbData->BigHexagon_index[ 3][1] =  1; 
	pgMbData->BigHexagon_index[ 4][0] = -4;	pgMbData->BigHexagon_index[ 4][1] =  0; 
	pgMbData->BigHexagon_index[ 5][0] = -4;	pgMbData->BigHexagon_index[ 5][1] = -1; 
	pgMbData->BigHexagon_index[ 6][0] = -4;	pgMbData->BigHexagon_index[ 6][1] = -2; 
	pgMbData->BigHexagon_index[ 7][0] = -2;	pgMbData->BigHexagon_index[ 7][1] = -3; 
	pgMbData->BigHexagon_index[ 8][0] =  0;	pgMbData->BigHexagon_index[ 8][1] = -4; 
	pgMbData->BigHexagon_index[ 9][0] =  2;	pgMbData->BigHexagon_index[ 9][1] = -3; 
	pgMbData->BigHexagon_index[10][0] =  4;	pgMbData->BigHexagon_index[10][1] = -2; 
	pgMbData->BigHexagon_index[11][0] =  4;	pgMbData->BigHexagon_index[11][1] = -1; 
	pgMbData->BigHexagon_index[12][0] =  4;	pgMbData->BigHexagon_index[12][1] =  0; 
	pgMbData->BigHexagon_index[13][0] =  4;	pgMbData->BigHexagon_index[13][1] =  1; 
	pgMbData->BigHexagon_index[14][0] =  4;	pgMbData->BigHexagon_index[14][1] =  2; 
	pgMbData->BigHexagon_index[15][0] =  2;	pgMbData->BigHexagon_index[15][1] =  3; 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : save motion vector for each block 
+ parameters     :  
+ return		 :  
+ descriptions   :  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Save_Motion_Vector(int blocktype) 
{ 
	int b8, b4; 
	// fill all 4 MV in one MB  by jhzheng [21:01 2004/02/15] 
	if (blocktype==1) 
	{//16x16 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				sInter_MV[b8][b4][0] = sInter_MV_ref[0][0][0]; 
				sInter_MV[b8][b4][1] = sInter_MV_ref[0][0][1]; 
				sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
				sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
			} 
	} 
	else if (blocktype==2) 
	{//16x8 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				if(b8<2) 
				{ 
					sInter_MV[b8][b4][0] = sInter_MV_ref[0][0][0]; 
					sInter_MV[b8][b4][1] = sInter_MV_ref[0][0][1]; 
					sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
					sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
				} 
				else 
				{ 
					sInter_MV[b8][b4][0] = sInter_MV_ref[2][0][0]; 
					sInter_MV[b8][b4][1] = sInter_MV_ref[2][0][1];  
					sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV_ref[2][0][0];  //zhangnan 
					sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV_ref[2][0][1]; 
				} 
			} 
	} 
	else if (blocktype==3) 
	{//8x16 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				if(b8&1) 
				{ 
					sInter_MV[b8][b4][0] = sInter_MV_ref[1][0][0]; 
					sInter_MV[b8][b4][1] = sInter_MV_ref[1][0][1]; 
					sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV_ref[1][0][0];  //zhangnan 
					sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV_ref[1][0][1]; 
				} 
				else 
				{ 
					sInter_MV[b8][b4][0] = sInter_MV_ref[0][0][0]; 
					sInter_MV[b8][b4][1] = sInter_MV_ref[0][0][1]; 
					sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
					sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
				} 
			} 
	} 
	 
	if(blocktype==4) 
	{ 
		for(b8 = 0; b8 < 4; b8++) 
			for(b4 = 0; b4 < 4; b4++) 
			{ 
				pgMbData->mvb[b8][b4][0] = pgMbData->mvb_ref[b8][b4][0]; 
				pgMbData->mvb[b8][b4][1] = pgMbData->mvb_ref[b8][b4][1]; 
				pgMbData->pred_mv[b8][b4][0] = pgMbData->pred_mv_ref[b8][b4][0]; 
				pgMbData->pred_mv[b8][b4][1] = pgMbData->pred_mv_ref[b8][b4][1]; 
			} 
	} 
	else 
	{ 
		for(b8 = 0; b8 < 4; b8++) 
			for(b4 = 0; b4 < 4; b4++) 
			{ 
				pgMbData->mvb[b8][b4][0] = sInter_MV[b8][b4][0]; 
				pgMbData->mvb[b8][b4][1] = sInter_MV[b8][b4][1]; 
				pgMbData->pred_mv[b8][b4][0] = sInter_Pred_MV[b8][b4][0]; 
				pgMbData->pred_mv[b8][b4][1] = sInter_Pred_MV[b8][b4][1]; 
			} 
	} 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : save motion vector for RDO 
+ parameters     :  
+ return		 :  
+ descriptions   :  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
void Save_Motion_Vector_RDO(int blocktype, int best_ref) 
{ 
	int b8, b4; 
	// fill all 4 MV in one MB  by jhzheng [21:01 2004/02/15] 
	if (blocktype==1) 
	{//16x16 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				blk_MV[blocktype][b8][b4][0] = sInter_MV_ref[0][0][0]; 
				blk_MV[blocktype][b8][b4][1] = sInter_MV_ref[0][0][1]; 
				blk_Pred_MV[blocktype][b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
				blk_Pred_MV[blocktype][b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
			} 
	} 
	else if (blocktype==2) 
	{//16x8 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				if(b8<2) 
				{ 
					blk_MV[blocktype][b8][b4][0] = sInter_MV_ref[0][0][0]; 
					blk_MV[blocktype][b8][b4][1] = sInter_MV_ref[0][0][1]; 
					blk_Pred_MV[blocktype][b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
					blk_Pred_MV[blocktype][b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
				} 
				else 
				{ 
					blk_MV[blocktype][b8][b4][0] = sInter_MV_ref[2][0][0]; 
					blk_MV[blocktype][b8][b4][1] = sInter_MV_ref[2][0][1];  
					blk_Pred_MV[blocktype][b8][b4][0] = sInter_Pred_MV_ref[2][0][0];  //zhangnan 
					blk_Pred_MV[blocktype][b8][b4][1] = sInter_Pred_MV_ref[2][0][1]; 
				} 
			} 
	} 
	else if (blocktype==3) 
	{//8x16 
		for(b8=0; b8<4; b8++) 
			for(b4=0; b4<4; b4++) 
			{ 
				if(b8&1) 
				{ 
					blk_MV[blocktype][b8][b4][0] = sInter_MV_ref[1][0][0]; 
					blk_MV[blocktype][b8][b4][1] = sInter_MV_ref[1][0][1]; 
					blk_Pred_MV[blocktype][b8][b4][0] = sInter_Pred_MV_ref[1][0][0];  //zhangnan 
					blk_Pred_MV[blocktype][b8][b4][1] = sInter_Pred_MV_ref[1][0][1]; 
				} 
				else 
				{ 
					blk_MV[blocktype][b8][b4][0] = sInter_MV_ref[0][0][0]; 
					blk_MV[blocktype][b8][b4][1] = sInter_MV_ref[0][0][1]; 
					blk_Pred_MV[blocktype][b8][b4][0] = sInter_Pred_MV_ref[0][0][0];  //zhangnan 
					blk_Pred_MV[blocktype][b8][b4][1] = sInter_Pred_MV_ref[0][0][1]; 
				} 
			} 
	} 
	 
	if(blocktype==4) 
	{ 
	    for(b8 = 0; b8 < 4; b8++) 
		{ 
			int best_subblk_type = pgMbData->best_mode_subblk[b8]; 
	 
			for(b4 = 0; b4 < 4; b4++) 
			{ 
				int best_ref2 = sInter_Ref[4][b8][b4]; 
				blk_MV[blocktype][b8][b4][0] = subblk_MV[best_subblk_type][best_ref2][b8][b4][0]; 
				blk_MV[blocktype][b8][b4][1] = subblk_MV[best_subblk_type][best_ref2][b8][b4][1]; 
				blk_Pred_MV[blocktype][b8][b4][0] = subblk_Pred_MV[best_subblk_type][best_ref2][b8][b4][0]; 
				blk_Pred_MV[blocktype][b8][b4][1] = subblk_Pred_MV[best_subblk_type][best_ref2][b8][b4][1]; 
			} 
		}		 
	} 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : save motion vector for each block 
+ parameters     :  
+ return		 :  
+ descriptions   :  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Save_Subblk_Motion_Vector_RDO(int subblktype, int b8, int ref) 
{ 
	int b4; 
 
	if (subblktype==1) 
	{//8x8 
		for(b4=0; b4<4; b4++) 
		{ 
			subblk_MV[subblktype][ref][b8][b4][0] = sInter_MV[b8][0][0]; 
			subblk_MV[subblktype][ref][b8][b4][1] = sInter_MV[b8][0][1]; 
			subblk_Pred_MV[subblktype][ref][b8][b4][0] = sInter_Pred_MV[b8][0][0]; 
			subblk_Pred_MV[subblktype][ref][b8][b4][1] = sInter_Pred_MV[b8][0][1]; 
		} 
	} 
	else if (subblktype==2) 
	{//8x4 
		subblk_MV[subblktype][ref][b8][0][0] = sInter_MV[b8][0][0];   subblk_MV[subblktype][ref][b8][0][1] = sInter_MV[b8][0][1]; 
		subblk_MV[subblktype][ref][b8][1][0] = sInter_MV[b8][0][0];   subblk_MV[subblktype][ref][b8][1][1] = sInter_MV[b8][0][1]; 
		subblk_MV[subblktype][ref][b8][2][0] = sInter_MV[b8][2][0];   subblk_MV[subblktype][ref][b8][2][1] = sInter_MV[b8][2][1]; 
		subblk_MV[subblktype][ref][b8][3][0] = sInter_MV[b8][2][0];   subblk_MV[subblktype][ref][b8][3][1] = sInter_MV[b8][2][1]; 
		subblk_Pred_MV[subblktype][ref][b8][0][0] = sInter_Pred_MV[b8][0][0];  
		subblk_Pred_MV[subblktype][ref][b8][0][1] = sInter_Pred_MV[b8][0][1];  
		subblk_Pred_MV[subblktype][ref][b8][1][0] = sInter_Pred_MV[b8][0][0];    
		subblk_Pred_MV[subblktype][ref][b8][1][1] = sInter_Pred_MV[b8][0][1]; 
		subblk_Pred_MV[subblktype][ref][b8][2][0] = sInter_Pred_MV[b8][2][0]; 
		subblk_Pred_MV[subblktype][ref][b8][2][1] = sInter_Pred_MV[b8][2][1]; 
		subblk_Pred_MV[subblktype][ref][b8][3][0] = sInter_Pred_MV[b8][2][0]; 
		subblk_Pred_MV[subblktype][ref][b8][3][1] = sInter_Pred_MV[b8][2][1]; 
		 
	} 
	else if (subblktype==3) 
	{//4x8 
		subblk_MV[subblktype][ref][b8][0][0] = sInter_MV[b8][0][0];   subblk_MV[subblktype][ref][b8][0][1] = sInter_MV[b8][0][1]; 
		subblk_MV[subblktype][ref][b8][2][0] = sInter_MV[b8][0][0];   subblk_MV[subblktype][ref][b8][2][1] = sInter_MV[b8][0][1]; 
		subblk_MV[subblktype][ref][b8][1][0] = sInter_MV[b8][1][0];   subblk_MV[subblktype][ref][b8][1][1] = sInter_MV[b8][1][1]; 
		subblk_MV[subblktype][ref][b8][3][0] = sInter_MV[b8][1][0];   subblk_MV[subblktype][ref][b8][3][1] = sInter_MV[b8][1][1]; 
		subblk_Pred_MV[subblktype][ref][b8][0][0] = sInter_Pred_MV[b8][0][0];   
		subblk_Pred_MV[subblktype][ref][b8][0][1] = sInter_Pred_MV[b8][0][1]; 
		subblk_Pred_MV[subblktype][ref][b8][2][0] = sInter_Pred_MV[b8][0][0];   
		subblk_Pred_MV[subblktype][ref][b8][2][1] = sInter_Pred_MV[b8][0][1]; 
		subblk_Pred_MV[subblktype][ref][b8][1][0] = sInter_Pred_MV[b8][1][0];    
		subblk_Pred_MV[subblktype][ref][b8][1][1] = sInter_Pred_MV[b8][1][1]; 
		subblk_Pred_MV[subblktype][ref][b8][3][0] = sInter_Pred_MV[b8][1][0];    
		subblk_Pred_MV[subblktype][ref][b8][3][1] = sInter_Pred_MV[b8][1][1]; 
	}else  
	{	 
		for(b4 = 0; b4 < 4; b4++) 
		{ 
			subblk_MV[subblktype][ref][b8][b4][0] = sInter_MV[b8][b4][0]; 
			subblk_MV[subblktype][ref][b8][b4][1] = sInter_MV[b8][b4][1]; 
			subblk_Pred_MV[subblktype][ref][b8][b4][0] = sInter_Pred_MV[b8][b4][0]; 
			subblk_Pred_MV[subblktype][ref][b8][b4][1] = sInter_Pred_MV[b8][b4][1]; 
		} 
	} 
}	 
 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : save motion vector for each block 
+ parameters     :  
+ return		 :  
+ descriptions   :  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
void Save_Subblk_Motion_Vector(int subblktype, int b8) 
{ 
	int b4; 
	if (subblktype==1) 
	{//8x8 
		for(b4=0; b4<4; b4++) 
		{ 
			sInter_MV[b8][b4][0] = sInter_MV[b8][0][0]; 
			sInter_MV[b8][b4][1] = sInter_MV[b8][0][1]; 
			sInter_Pred_MV[b8][b4][0] = sInter_Pred_MV[b8][0][0]; 
			sInter_Pred_MV[b8][b4][1] = sInter_Pred_MV[b8][0][1]; 
		} 
	} 
	else if (subblktype==2) 
	{//8x4 
		sInter_MV[b8][1][0] = sInter_MV[b8][0][0];   sInter_MV[b8][1][1] = sInter_MV[b8][0][1]; 
		sInter_MV[b8][3][0] = sInter_MV[b8][2][0];   sInter_MV[b8][3][1] = sInter_MV[b8][2][1]; 
		sInter_Pred_MV[b8][1][0] = sInter_Pred_MV[b8][0][0];    
		sInter_Pred_MV[b8][1][1] = sInter_Pred_MV[b8][0][1]; 
		sInter_Pred_MV[b8][3][0] = sInter_Pred_MV[b8][2][0]; 
		sInter_Pred_MV[b8][3][1] = sInter_Pred_MV[b8][2][1]; 
		 
	} 
	else if (subblktype==3) 
	{//4x8 
		sInter_MV[b8][2][0] = sInter_MV[b8][0][0];   sInter_MV[b8][2][1] = sInter_MV[b8][0][1]; 
		sInter_MV[b8][3][0] = sInter_MV[b8][1][0];   sInter_MV[b8][3][1] = sInter_MV[b8][1][1]; 
		sInter_Pred_MV[b8][2][0] = sInter_Pred_MV[b8][0][0];   
		sInter_Pred_MV[b8][2][1] = sInter_Pred_MV[b8][0][1]; 
		sInter_Pred_MV[b8][3][0] = sInter_Pred_MV[b8][1][0];    
		sInter_Pred_MV[b8][3][1] = sInter_Pred_MV[b8][1][1]; 
	} 
	 
	for(b4 = 0; b4 < 4; b4++) 
	{ 
		pgMbData->mvb_tmp[b8][b4][0] = sInter_MV[b8][b4][0]; 
		pgMbData->mvb_tmp[b8][b4][1] = sInter_MV[b8][b4][1]; 
		pgMbData->pred_mv_tmp[b8][b4][0] = sInter_Pred_MV[b8][b4][0]; 
		pgMbData->pred_mv_tmp[b8][b4][1] = sInter_Pred_MV[b8][b4][1]; 
	} 
} 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ function name  : restore motion vector for RDO 
+ parameters     :  
+ return		 :  
+ descriptions   :  
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
void Restore_Motion_Vector(int blocktype) 
{ 
	int b8, b4;  
 
	for(b8 = 0; b8 < 4; b8++) 
		for(b4 = 0; b4 < 4; b4++) 
		{ 
			pgMbData->mvb[b8][b4][0] = blk_MV[blocktype][b8][b4][0]; 
			pgMbData->mvb[b8][b4][1] = blk_MV[blocktype][b8][b4][1]; 
			pgMbData->pred_mv[b8][b4][0] = blk_Pred_MV[blocktype][b8][b4][0]; 
			pgMbData->pred_mv[b8][b4][1] = blk_Pred_MV[blocktype][b8][b4][1]; 
		} 
}