⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block.cpp

📁 h264编解码.用C++实现了图像的编解码功能。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(current_inter_sad < MinCost) 
	{
	    img->mb_mode=3;
	    img->imod=INTRA_MB_INTER; 
	   
		for(i=0;i<4;i++)
		{
			tmp_mv[pic_block_y+i][pic_block_x+2][0]=curr_mvx2[0];
			tmp_mv[pic_block_y+i][pic_block_x+2][1]=curr_mvy2[0];
			tmp_mv[pic_block_y+i][pic_block_x+3][0]=curr_mvx2[0];
			tmp_mv[pic_block_y+i][pic_block_x+3][1]=curr_mvy2[0];
			tmp_mv[pic_block_y+i][pic_block_x+4][0]=curr_mvx2[1];
			tmp_mv[pic_block_y+i][pic_block_x+4][1]=curr_mvy2[1];
			tmp_mv[pic_block_y+i][pic_block_x+5][0]=curr_mvx2[1];
			tmp_mv[pic_block_y+i][pic_block_x+5][1]=curr_mvy2[1];
			intra_mb_pos[pic_block_y+i][pic_block_x+2] = 0;
			intra_mb_pos[pic_block_y+i][pic_block_x+3] = 0;
			intra_mb_pos[pic_block_y+i][pic_block_x+4] = 0;
			intra_mb_pos[pic_block_y+i][pic_block_x+5] = 0;
		}
	    MinCost = current_inter_sad;
	} 
          	        
  return MinCost;
}

int motion_search(struct img_par *img,int tot_intra_sad)
{
  int i;
  int vec0_x,vec0_y,vec1_x,vec1_y,vec2_x,vec2_y;
  int pic_block_x,pic_block_y,pic_pix_y,pic_pix_x;
  int ip0,ip1,ip2,ip3,ip4,ip5;
  int best_inter_sad,current_inter_sad,skip_sad=65536,skip_offset;
  int tmp0,tmp1; 
  int lambda = QP2QUANT[img->qp-SHIFT_QP]; 
  int x,y,offset,type,pos,skipcomp;  
        byte* curr;
	byte* prev;
	Point* point=search;
	SAD_TABLE * sadTbl=sadTable;
	int maxX=img->width-12;
	int maxY=img->height-12;
	int sadTimes=25;
	int mvx0=0,mvy0=0,mvx1,mvy1; 
	int x_curr,y_curr;
	int width=img->width+IMG_PAD_SIZE;

#ifdef FAST_INTEGER	
	int prev_AE1[17];
	int prev_m1,prev_m2=0;
	static int prevm[4] = {2, 3, 0, 1};
	static int htp[4] = {-1, 0, 1, 0};
	static int vtp[4] = {0, 1, 0, -1};
	int j_min_now, i_min_now,i_min_next=0, j_min_next=0, Coffset,sad_layr,ioffset=0,l,m,j;
	int distortion_0, distortion_1, distortion_2;
#endif    
	
  pic_block_y=img->block_y;
  pic_pix_y=img->pix_y;
        
  pic_block_x=img->block_x;
  pic_pix_x=img->pix_x;

  x_curr=pic_pix_x;
  y_curr=pic_pix_y;
                    
  vec0_x=pic_block_x-1;		/*left block*/
  vec0_y=pic_block_y;
  vec1_x=pic_block_x;
  vec1_y=pic_block_y-1;		/*up block*/
  vec2_x=pic_block_x+4;
  vec2_y=pic_block_y-1;		/*upright block*/
                    
          if (pic_block_y == 0) /*current block has no up blocks, reset refference block*/
          {
            vec1_x=vec0_x;
            vec2_x=vec0_x;
            vec1_y=vec0_y;
            vec2_y=vec0_y;
          }                
          if (vec2_x > (img->width>>2)-1) /*current block has no upright block,reset refference block*/
          {
            vec2_x=pic_block_x-1;
          }
          
          
            ip0=tmp_mv[vec0_y][vec0_x+4][0];
            ip1=tmp_mv[vec1_y][vec1_x+4][0];
            ip2=tmp_mv[vec2_y][vec2_x+4][0];
			ip3=tmp_mv[vec0_y][vec0_x+4][1];
            ip4=tmp_mv[vec1_y][vec1_x+4][1];
            ip5=tmp_mv[vec2_y][vec2_x+4][1];
			if((!intra_mb_pos[vec0_y][vec0_x+4])&&(intra_mb_pos[vec1_y][vec1_x+4])&&(intra_mb_pos[vec2_y][vec2_x+4]))
			{
				img->mv[0] = ip0;
				img->mv[1] = ip3;
			}
			else if((intra_mb_pos[vec0_y][vec0_x+4])&&(!intra_mb_pos[vec1_y][vec1_x+4])&&(intra_mb_pos[vec2_y][vec2_x+4]))
			{
				img->mv[0] = ip1;
				img->mv[1] = ip4;
			}
			else if((intra_mb_pos[vec0_y][vec0_x+4])&&(intra_mb_pos[vec1_y][vec1_x+4])&&(!intra_mb_pos[vec2_y][vec2_x+4]))
			{
				img->mv[0] = ip2;
				img->mv[1] = ip5;
			}
			else
			{
				img->mv[0]=ip0+ip1+ip2-min(min(ip0,ip1),ip2)-max(max(ip0,ip1),ip2);
				img->mv[1]=ip3+ip4+ip5-min(min(ip3,ip4),ip5)-max(max(ip3,ip4),ip5);
			}
          ip0=img->mv[0];
          ip1=img->mv[1];

		  //by guoxq
		  if(pic_pix_y==0 || pic_pix_x==0)
		  {
			  skip_mv[0]=0;
			  skip_mv[1]=0;
		  }
		  else if(tmp_mv[vec0_y][vec0_x+4][0]==0 && tmp_mv[vec0_y][vec0_x+4][1]==0 && (!intra_mb_pos[vec0_y][vec0_x+4]))
		  {
			  skip_mv[0]=0;
			  skip_mv[1]=0;
		  }
		  else if(tmp_mv[vec1_y][vec1_x+4][0]==0 && tmp_mv[vec1_y][vec1_x+4][1]==0 && (!intra_mb_pos[vec1_y][vec1_x+4]))
		  {
			  skip_mv[0]=0;
			  skip_mv[1]=0;
		  }
		  else
		  {
			  skip_mv[0]=ip0;
			  skip_mv[1]=ip1;
		  }
    
	img->bSkipMode=0;
	offset=width*pic_pix_y+pic_pix_x;  
    curr=imgY_org + offset; 
    x=pic_pix_x+(skip_mv[0]>>2)+(((skip_mv[0]>>1)|skip_mv[0])&1);
    y=pic_pix_y+(skip_mv[1]>>2)+(((skip_mv[1]>>1)|skip_mv[1])&1);             
	if((x>=-4)&&(y>=-4)&&(x<=maxX)&&(y<=maxY))//16表示模式1,16x16块
	{
		skipcomp=(skip_mv[1]&3)*4+(skip_mv[0]&3);
		skip_offset=(pic_pix_y+(skip_mv[1]>>2))*width + pic_pix_x+(skip_mv[0]>>2);
		prev=ipol[skipcomp] + skip_offset;
		skip_sad=SAD_Macroblock(img,curr,prev,MAX_VALUE,0);
		skip_sad -= 8*lambda; 
		if (skip_sad <= 10*lambda)
		{
			img->bSkipMode=1;
			img->offset=skip_offset;
			img->comp  =skipcomp;
			best_inter_sad=skip_sad;
			curr_mvx=skip_mv[0];
			curr_mvy=skip_mv[1];
			img->mb_mode=1;
			img->imod=INTRA_MB_INTER;   
			for(i=0;i<4;i++)
			{
				tmp_mv[pic_block_y][pic_block_x+4+i][0]=curr_mvx;
				tmp_mv[pic_block_y][pic_block_x+4+i][1]=curr_mvy;
				tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=curr_mvx;
				tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=curr_mvy;
				tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=curr_mvx;
				tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=curr_mvy;
				tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=curr_mvx;
				tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=curr_mvy;
				intra_mb_pos[pic_block_y][pic_block_x+4+i] = 0;
				intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 0;
				intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 0;
				intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 0;
			}
			return best_inter_sad;
		}
	}    

	prev=ipol[0] + offset;  
    tmp0=-ip0;
    tmp1=-ip1;
    current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
    best_inter_sad = SAD_Macroblock(img,curr, prev, MAX_VALUE,current_inter_sad);
    best_inter_sad -= lambda * 16;

#ifndef FAST_INTEGER          
	pos=0;
	for (i = 1; i < sadTimes; i++)
	{
		sadTbl++;
		x=x_curr+sadTbl->dx;
		y=y_curr+sadTbl->dy;

		tmp0=((mvx0+sadTbl->dx)<<2)-ip0;
        tmp1=((mvy0+sadTbl->dy)<<2)-ip1;
        current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
//		current_inter_sad += SAD_Macroblock(img,prev+sadTbl->offset, curr, best_inter_sad,current_inter_sad);
		current_inter_sad = SAD_Macroblock(img,prev+sadTbl->offset, curr, best_inter_sad,current_inter_sad);
		if (current_inter_sad < best_inter_sad)
		{
			pos=i;
			best_inter_sad = current_inter_sad;
		}
	}
	mvx0 = sadTable[pos].dx;
	mvy0 = sadTable[pos].dy;
	offset+=sadTable[pos].offset;
	x_curr+=mvx0;
	y_curr+=mvy0;
	
#else
	i_min_now = min(maxX,max(-4, x_curr+(ip0>>2)));
	j_min_now = min(maxY,max(-4, y_curr+(ip1>>2)));

	/*full pixel motion estimation*/
  	distortion_0 = distortion_1 = distortion_2 = 65536;
  	prev_AE1[0] = best_inter_sad;
  	prev_m1 = -1;
  	for (l = 1; l <= 16; l++){
  		sad_layr = 65536;
  		for (m = 0; m < 4; m++){
  			i = i_min_now + htp[m];
  			j = j_min_now + vtp[m];
  			Coffset = i - x_curr + (j - y_curr)*width;
  			if(l>2&&prev_m1 == m)
  			{
  				current_inter_sad = prev_AE1[l-2];
  				if (current_inter_sad < sad_layr){
  					sad_layr = current_inter_sad;
  					i_min_next = i;
  					j_min_next = j;
  					prev_m2=prevm[m];
  					prev_AE1[l]=current_inter_sad;
  				}
  			}
  			else if (i >= -4 && i <= maxX && j >= -4 && j <= maxY){
  				tmp0=((i - x_curr)<<2)-ip0;
			        tmp1=((j - y_curr)<<2)-ip1;
			        current_inter_sad=(lambda*(img->mv_bituse[IABS(tmp0)]+img->mv_bituse[IABS(tmp1)]));
//			        current_inter_sad += SAD_Macroblock(img,curr, prev+Coffset, sad_layr,current_inter_sad);
			        current_inter_sad = SAD_Macroblock(img,curr, prev+Coffset, sad_layr,current_inter_sad);
  				if (current_inter_sad < best_inter_sad){
  					mvx0  = i - x_curr;
  					mvy0  = j - y_curr;
  					ioffset = Coffset;
  					best_inter_sad = current_inter_sad ;
  				}
  				if (current_inter_sad < sad_layr){
  					sad_layr = current_inter_sad;
  					i_min_next = i;
  					j_min_next = j;
  					prev_m2 = prevm[m];
	  				prev_AE1[l] = current_inter_sad;
  				}
  			}
  		}
  		prev_m1 = prev_m2;
  		i_min_now = i_min_next;
  		j_min_now = j_min_next;
  		distortion_2 = distortion_1;
  		distortion_1 = distortion_0;
  		distortion_0 = sad_layr;
  		if (distortion_1 <= distortion_0 && distortion_2 <= distortion_0){
  			break;  			
  		}
  	}
  	offset+=ioffset;
	x_curr+=mvx0;
	y_curr+=mvy0;

#endif	
   /*********************************
   *****                       *****
   *****  HALF-PEL REFINEMENT  *****
   *****                       *****
   *********************************/
	pos=0;
	for (i = 1; i < 9; i++)
	{
		point++;
		x=x_curr+point->x;
		y=y_curr+point->y;
#ifdef FAST_INTEGER
		if((x<-4)||(y<-4)||(x>maxX)||(y>maxY))
			continue;
#endif
		
		tmp0=(mvx0<<2)+point->x-ip0;
        tmp1=(mvy0<<2)+point->y-ip1;
        current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
		prev=ipol[point->comp] + offset + point->offset;
//		current_inter_sad+=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);		
		current_inter_sad=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);
		if (current_inter_sad < best_inter_sad)
		{
			best_inter_sad=current_inter_sad;
			pos=i;
		}
	}
	mvx1 = search[pos].x;
	mvy1 = search[pos].y;
	offset+=search[pos].offset;
	type  =search[pos].type;
	x_curr+=(mvx1>>1);
	y_curr+=(mvy1>>1);

	
   /************************************
   *****                          *****
   *****  QUARTER-PEL REFINEMENT  *****
   *****                          *****
   ************************************/
	point=qsearch[type];
	pos=0;
	for (i = 1; i < 9; i++)
	{
		point++;
		x=x_curr+point->x;
		y=y_curr+point->y;
#ifdef FAST_INTEGER
		if((x<-4)||(y<-4)||(x>maxX)||(y>maxY))
			continue;
#endif
			
		tmp0=(mvx0<<2)+mvx1+point->x-ip0;
        tmp1=(mvy0<<2)+mvy1+point->y-ip1;
        current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
		prev=ipol[point->comp] + offset + point->offset;
		current_inter_sad=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);
		if (current_inter_sad < best_inter_sad)
		{
			best_inter_sad=current_inter_sad;
			pos=i;
		}
	}
	offset+=qsearch[type][pos].offset;
	img->offset=offset;
	img->comp  =qsearch[type][pos].comp;
	curr_mvx=(mvx0<<2)+mvx1+qsearch[type][pos].x;
	curr_mvy=(mvy0<<2)+mvy1+qsearch[type][pos].y;
	
	if (skip_sad <= best_inter_sad)
	{
		img->bSkipMode=1;
		img->offset=skip_offset;
		img->comp  =skipcomp;
		best_inter_sad=skip_sad;
		curr_mvx=skip_mv[0];
		curr_mvy=skip_mv[1];
	}
	
	if (tot_intra_sad < best_inter_sad) 
	{
	    img->mb_mode=img->imod+8*img->type; 
		for(i=0;i<4;i++)
		{
			tmp_mv[pic_block_y][pic_block_x+4+i][0]=0;
			tmp_mv[pic_block_y][pic_block_x+4+i][1]=0;
			tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=0;
			tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=0;
			tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=0;
			tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=0;
			tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=0;
			tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=0;
			intra_mb_pos[pic_block_y][pic_block_x+4+i] = 1;
			intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 1;
			intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 1;
			intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 1;
		}
	    best_inter_sad = tot_intra_sad;
	} 
	else 
	{
		img->mb_mode=1;
	    img->imod=INTRA_MB_INTER;   
		for(i=0;i<4;i++)
		{
			tmp_mv[pic_block_y][pic_block_x+4+i][0]=curr_mvx;
			tmp_mv[pic_block_y][pic_block_x+4+i][1]=curr_mvy;
			tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=curr_mvx;
			tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=curr_mvy;
			tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=curr_mvx;
			tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=curr_mvy;
			tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=curr_mvx;
			tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=curr_mvy;
			intra_mb_pos[pic_block_y][pic_block_x+4+i] = 0;
			intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 0;
			intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 0;
			intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 0;
		}
	}
	return best_inter_sad;
          	        
}

int Intra_Sad(struct img_par *img,byte *ii, int *pp)
{
	int i,sad=0;
	int x0,x1,x2,x3;
	int y0,y1,y2,y3;
	int lx=img->width+IMG_PAD_SIZE;
	for(i=0;i<4;i++)
	{
		x0=ii[0];	y0=pp[0];
		x1=ii[1];	y1=pp[1];
		x2=ii[2];	y2=pp[2];
		x3=ii[3];	y3=pp[3];
		sad+=IABS(x0-y0)+IABS(x1-y1)+IABS(x2-y2)+IABS(x3-y3);
		ii+=lx;	pp+=4;
	}
	return sad;
}

int IntraMB_Sad(struct img_par *img,byte *ii, int *pp)
{
	int sad=0;
	int i,j;
	int mm,jj;
	int current_intra_sad_2;
	int lx=img->width+IMG_PAD_SIZE;
	int M1[16][16],M0[4][4][4][4],M3[4],M4[4][4];
	for (j=0;j<16;j++)
	{
		jj=j>>2;
        for (i=0;i<16;i+=4)
        {
          mm=i>>2;
          M1[i][j]  =ii[i]  -pp[i];		  M1[i+1][j]=ii[i+1]-pp[i+1];
		  M1[i+2][j]=ii[i+2]-pp[i+2];		  M1[i+3][j]=ii[i+3]-pp[i+3];
          M0[0][mm][j&0x03][jj]=  M1[i][j];
		  M0[1][mm][j&0x03][jj]=M1[i+1][j];
		  M0[2][mm][j&0x03][jj]=M1[i+2][j];
		  M0[3][mm][j&0x03][jj]=M1[i+3][j];
        }
		ii+=lx;	pp+=16;
	}

	current_intra_sad_2=0;	// no SAD start handicap here
	for (jj=0;jj<4;jj++)
	{
        for (mm=0;mm<4;mm++)
        {
			for (j=0;j<4;j++)
			{
				M3[0]=M0[0][mm][j][jj]+M0[3][mm][j][jj];
				M3[1]=M0[1][mm][j][jj]+M0[2][mm][j][jj];
				M3[2]=M0[1][mm][j][jj]-M0[2][mm][j][jj];
				M3[3]=M0[0][mm][j][jj]-M0[3][mm][j][jj];
				
				M0[0][mm][j][jj]=M3[0]+M3[1];
				M0[2][mm][j][jj]=M3[0]-M3[1];
				M0[1][mm][j][jj]=M3[2]+M3[3];
				M0[3][mm][j][jj]=M3[3]-M3[2];
			}
			
			for (i=0;i<4;i++)
			{
				M3[0]=M0[i][mm][0][jj]+M0[i][mm][3][jj];
				M3[1]=M0[i][mm][1][jj]+M0[i][mm][2][jj];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -