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

📄 macroblock.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
						{
							best_intra_sad=current_intra_sad;
							best_ipmode=ipmode;

							for (j=0; j < BLOCK_SIZE; j++)
								for (i=0; i < BLOCK_SIZE; i++)
									img->mpr[i+block_x][j+block_y]=img->mprr[ipmode][j][i];       /* store the currently best intra prediction block*/
						}
					}
				}
			}
			tot_intra_sad += best_intra_sad;

			img->ipredmode[pic_block_x+1][pic_block_y+1]=best_ipmode;

			if ((pic_block_x & 1) == 1) /* just even blocks, two and two predmodes are sent together */
			{
				currMB->intra_pred_modes[block_x/4+block_y]=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];
				currMB->intra_pred_modes[block_x/4-1+block_y]=last_ipred;
			}
			last_ipred=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];

			/*  Make difference from prediction to be transformed*/
			for (j=0; j < BLOCK_SIZE; j++)
			{
				for (i=0; i < BLOCK_SIZE; i++)
				{
					img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y];
				}
			}

			nonzero = dct_luma(block_x,block_y,&coeff_cost);

			if (nonzero)
			{
					currMB->cbp |= cbp_mask;/* set coded block pattern if there are nonzero coeffs */
			}
		}
	}

	/* 16x16 intra prediction */
	intrapred_luma_2(img);                                /* make intra pred for the new 4 modes */
	tot_intra_sad2 = find_sad2(intra_pred_mode_2);   /* find best SAD for new modes */
		
	if (tot_intra_sad2<tot_intra_sad)
	{
		currMB->cbp = 0;												/* cbp for 16x16 LUMA is signaled by the MB-mode */
		tot_intra_sad = tot_intra_sad2; /* update best intra sad if necessary */
		img->imod = INTRA_MB_NEW;       /* one of the new modes is used */
		img->mb_data[img->current_mb_nr].intraOrInter = INTRA_MB_16x16;
		dct_luma2(*intra_pred_mode_2);
		for (i=0;i<4;i++)
			for (j=0;j<4;j++)
				img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
	}
	return tot_intra_sad;
}

/************************************************************************
*
*  Name :       LumaResidualCoding_P()
*
*  Description: Performs DCT, R-D constrained quantization, run/level 
*								pre-coding and IDCT for the MC-compensated MB residue  
*								of P-frame; current cbp (for LUMA only) is affected 
*
************************************************************************/
void LumaResidualCoding_P()
{

	int i,j;
	int block_x, block_y;
	int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
	int ii4,i2,jj4,j2;
	int sum_cnt_nonz;
	int mb_x, mb_y;
	int cbp_mask;
	int coeff_cost;
	int nonzero;
	Macroblock *currMB = &img->mb_data[img->current_mb_nr];


	currMB->cbp=0;
	sum_cnt_nonz=0;
	for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
	{
		for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
		{
			cbp_mask=(1<<(mb_x/8+mb_y/4));
			coeff_cost=0;
			for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
			{
				pic_pix_y=img->pix_y+block_y;
				pic_block_y=pic_pix_y/BLOCK_SIZE;

				for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
				{
					pic_pix_x=img->pix_x+block_x;
					pic_block_x=pic_pix_x/BLOCK_SIZE;

					img->ipredmode[pic_block_x+1][pic_block_y+1]=0;
		
					if(input->mv_res)
					
					{
						ii4=(img->pix_x+block_x)*8+tmp_mv[0][pic_block_y][pic_block_x+4];
						jj4=(img->pix_y+block_y)*8+tmp_mv[1][pic_block_y][pic_block_x+4];
						for (j=0;j<4;j++)
						{
							j2=j*8;
							for (i=0;i<4;i++)
							{
								i2=i*8;
#ifdef UMV
								img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref[img->multframe_no], jj4+j2, ii4+i2);
#else
								img->mpr[i+block_x][j+block_y]=FastPelY_18 (mref[img->multframe_no], jj4+j2, ii4+i2);
#endif
								//img->mpr[i+block_x][j+block_y]=get_eigthpix_pel(ii4+i2,jj4+j2,img->multframe_no);
							}
						}
						
					}
					else
					{
						ii4=(img->pix_x+block_x)*4+tmp_mv[0][pic_block_y][pic_block_x+4];
						jj4=(img->pix_y+block_y)*4+tmp_mv[1][pic_block_y][pic_block_x+4];
						for (j=0;j<4;j++)
						{
#ifndef UMV
							j2=j*4;
#endif
#ifdef UMV
							j2 = max (0, min(img->mvert,jj4+j*4));
#endif
							for (i=0;i<4;i++)
							{
#ifndef UMV
								i2=i*4;
								img->mpr[i+block_x][j+block_y]=mref[img->multframe_no][jj4+j2][ii4+i2];
#endif
#ifdef UMV
								i2 = max(0, min(img->mhor, ii4+i*4));
								img->mpr[i+block_x][j+block_y]=FastPelY_14 (mref[img->multframe_no], j2, i2);

#endif
							}
						}
					}
											
					for (j=0; j < BLOCK_SIZE; j++)
					{
						for (i=0; i < BLOCK_SIZE; i++)
						{
							img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y];
						}
					}
					nonzero=dct_luma(block_x,block_y,&coeff_cost);
					if (nonzero)
					{
						currMB->cbp |= cbp_mask;
					}

				}
			}

			/*
			The purpose of the action below is to prevent that single or 'expensive' coefficients are coded.
			With 4x4 transform there is larger chance that a single coefficient in a 8x8 or 16x16 block may be nonzero.
			A single small (level=1) coefficient in a 8x8 block will cost: 3 or more bits for the coefficient,
			4 bits for EOBs for the 4x4 blocks,possibly also more bits for CBP.  Hence the total 'cost' of that single
			coefficient will typically be 10-12 bits which in a RD consideration is too much to justify the distortion improvement.
			The action below is to watch such 'single' coefficients and set the reconstructed block equal to the prediction according
			to a given criterium.  The action is taken only for inter luma blocks.

			Notice that this is a pure encoder issue and hence does not have any implication on the standard.
			coeff_cost is a parameter set in dct_luma() and accumulated for each 8x8 block.  If level=1 for a coefficient,
			coeff_cost is increased by a number depending on RUN for that coefficient.The numbers are (see also dct_luma()): 3,2,2,1,1,1,0,0,...
			when RUN equals 0,1,2,3,4,5,6, etc.
			If level >1 coeff_cost is increased by 9 (or any number above 3). The threshold is set to 3. This means for example:
			1: If there is one coefficient with (RUN,level)=(0,1) in a 8x8 block this coefficient is discarded.
			2: If there are two coefficients with (RUN,level)=(1,1) and (4,1) the coefficients are also discarded
			sum_cnt_nonz is the accumulation of coeff_cost over a whole macro block.  If sum_cnt_nonz is 5 or less for the whole MB,
			all nonzero coefficients are discarded for the MB and the reconstructed block is set equal to the prediction.
			*/

			if (coeff_cost > 3)
			{
				sum_cnt_nonz += coeff_cost;
			}
			else /*discard */
			{
				currMB->cbp &= (63-cbp_mask);
				for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i++)
				{
					for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j++)
					{
						imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
					}
				}
			}
		}
	}
	
	if (sum_cnt_nonz <= 5 )
	{
		currMB->cbp &= 48; /* mask bit 4 and 5 */
		for (i=0; i < MB_BLOCK_SIZE; i++)
		{
			for (j=0; j < MB_BLOCK_SIZE; j++)
			{
				imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
			}
		}
	}
}

/************************************************************************
*
*  Name :       ChromaCoding_P()
*
*  Description: Performs DCT, quantization, run/level pre-coding and IDCT 
*               for the chrominance of a I- of P-frame macroblock; 
*								current cbp and cr_cbp are affected 
*
************************************************************************/
void ChromaCoding_P(int *cr_cbp)
{
	int i, j;
	int uv, ii,jj,ii0,jj0,ii1,jj1,if1,jf1,if0,jf0,f1,f2,f3,f4;	
	int pic_block_y, pic_block_x;
	Macroblock *currMB = &img->mb_data[img->current_mb_nr];

	if(input->mv_res)
	{
	  f1=16;
	  f2=15;
	}
	else
	{
	  f1=8;
	  f2=7;
	}

	f3=f1*f1;
	f4=f3/2;

	*cr_cbp=0;
	for (uv=0; uv < 2; uv++) 
	{      
		if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW) 
		{
			intrapred_chroma(img->pix_c_x,img->pix_c_y,uv); 
		}        
		else
		{
			for (j=0; j < MB_BLOCK_SIZE/2; j++)
			{
				pic_block_y=(img->pix_c_y+j)/2;
				for (i=0; i < MB_BLOCK_SIZE/2; i++)
				{
						pic_block_x=(img->pix_c_x+i)/2;
						ii=(img->pix_c_x+i)*f1+tmp_mv[0][pic_block_y][pic_block_x+4];
						jj=(img->pix_c_y+j)*f1+tmp_mv[1][pic_block_y][pic_block_x+4];
#ifndef UMV
						ii0=ii/f1;
						jj0=jj/f1;
						ii1=(ii+f2)/f1;
						jj1=(jj+f2)/f1;
#endif
#ifdef UMV
						ii0 = max (0, min (img->width_cr-1,ii/f1));
						jj0 = max (0, min (img->height_cr-1,jj/f1));
						ii1 = max (0, min (img->width_cr-1,(ii+f2)/f1));
						jj1 = max (0, min (img->height_cr-1,(jj+f2)/f1));
#endif

						if1=(ii & f2);
						jf1=(jj & f2);
						if0=f1-if1;
						jf0=f1-jf1;
						img->mpr[i][j]=(if0*jf0*mcef[img->multframe_no][uv][jj0][ii0]+
										if1*jf0*mcef[img->multframe_no][uv][jj0][ii1]+
										if0*jf1*mcef[img->multframe_no][uv][jj1][ii0]+
										if1*jf1*mcef[img->multframe_no][uv][jj1][ii1]+f4)/f3;

						img->m7[i][j]=imgUV_org[uv][img->pix_c_y+j][img->pix_c_x+i]-img->mpr[i][j];
				}
			}
		}
		*cr_cbp=dct_chroma(uv,*cr_cbp);
	}
	currMB->cbp += *cr_cbp*16;	
}

/************************************************************************
*
*  Name :       SetRefFrameInfo_P()
*
*  Description: Set reference frame information in global arrays 
*								depending on mode decision. Used for motion vector prediction.
*
************************************************************************/
void SetRefFrameInfo_P()
{
	int i,j;

	if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW) 
	{
		/* Set the reference frame information for motion vector prediction as unavailable */
		for (j = 0;j < BLOCK_MULTIPLE;j++)
		{
			for (i = 0;i < BLOCK_MULTIPLE;i++)
			{
				refFrArr[img->block_y+j][img->block_x+i] = -1;
			}
		}	
	}        
	else
	{
		/* Set the reference frame information for motion vector prediction  */
		for (j = 0;j < BLOCK_MULTIPLE;j++)
		{
			for (i = 0;i < BLOCK_MULTIPLE;i++)
			{
				refFrArr[img->block_y+j][img->block_x+i] = 	img->mb_data[img->current_mb_nr].ref_frame;
			}
		}		
	}
}


/************************************************************************
*
*  Name :       SetLoopfilterStrength_P()
*
*  Description: Set the filter strength for a macroblock of a I- or P-frame
*
************************************************************************/
void SetLoopfilterStrength_P()
{
	int i,j;
	int ii,jj;
	int i3,j3,mvDiffX,mvDiffY;

	if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW) 
	{
		for (i=0;i<BLOCK_MULTIPLE;i++)
		{
			ii=img->block_x+i;
			i3=ii/2;
			for (j=0;j<BLOCK_MULTIPLE;j++)
			{
				jj=img->block_y+j;
				j3=jj/2;
				loopb[ii+1][jj+1]=3;
				loopb[ii  ][jj+1]=max(loopb[ii  ][jj+1],2);
				loopb[ii+1][jj  ]=max(loopb[ii+1][jj  ],2);
				loopb[ii+2][jj+1]=max(loopb[ii+2][jj+1],2);
				loopb[ii+1][jj+2]=max(loopb[ii+1][jj+2],2);
				
				loopc[i3+1][j3+1]=2;
				loopc[i3  ][j3+1]=max(loopc[i3  ][j3+1],1);
				loopc[i3+1][j3  ]=max(loopc[i3+1][j3  ],1);
				loopc[i3+2][j3+1]=max(loopc[i3+2][j3+1],1);
				loopc[i3+1][j3+2]=max(loopc[i3+1][j3+2],1);
			}
		}
	}
	else
	{
		for (i=0;i<4;i++)
		{
			ii=img->block_x+i;
			i3=ii/2;
			for (j=0;j<4;j++)
			{
				jj=img->block_y+j;
				j3=jj/2;
				
				mvDiffX = tmp_mv[0][jj][ii+4] - tmp_mv[0][jj][ii-1+4];
				mvDiffY = tmp_mv[1][jj][ii+4] - tmp_mv[1][jj][ii-1+4];
				
				if((mvDiffX*mvDiffX >= 16 || mvDiffY*mvDiffY >= 16) && ii > 0)
				{ 
					loopb[ii  ][jj+1]=max(loopb[ii  ][jj+1],1);
					loopb[ii+1][jj+1]=max(loopb[ii+1][jj+1],1); 
					loopc[i3  ][j3+1]=max(loopc[i3  ][j3+1],1);
					loopc[i3+1][j3+1]=max(loopc[i3+1][j3+1],1);
				}
				
				if(jj > 0) /*GH: bug fix to avoid tmp_mv[][-1][ii+4]*/
				{
				  mvDiffX = tmp_mv[0][jj][ii+4] - tmp_mv[0][jj-1][ii+4];
				  mvDiffY = tmp_mv[1][jj][ii+4] - tmp_mv[1][jj-1][ii+4];
				
				  if(mvDiffX*mvDiffX >= 16 || mvDiffY*mvDiffY >= 16)
				  {
					loopb[ii+1][jj  ]=max(loopb[ii+1][jj  ],1);
					loopb[ii+1][jj+1]=max(loopb[ii+1][jj+1],1);
					loopc[i3+1][j3  ]=max(loopc[i3+1][j3  ],1);
					loopc[i3+1][j3+1]=max(loopc[i3+1][j3+1],1);
				  }
				}
			}
		}		
	}
}

/************************************************************************
*
*  Name :       encode_one_macroblock()
*
*  Description: Encode one macroblock depending on chosen picture type
*
************************************************************************/
void encode_one_macroblock()
{
  int cr_cbp;							/* chroma coded block pattern */
  int tot_intra_sad;
  int intra_pred_mode_2;	/* best 16x16 intra mode */

#ifdef _RD_OPT_
  if ((img->type!=B_IMG && input->rdopt) || (input->rdopt>0))
    {
      RD_Mode_Decision ();
    }
  else
    {
#endif
      Macroblock *currMB = &img->mb_data[img->current_mb_nr];

      /* Intra Prediction */
      tot_intra_sad = MakeIntraPrediction(&intra_pred_mode_2);

    if (img->type != B_IMG)					/* I- or P-frame */
	{
		if ((img->mb_y == img->mb_y_upd && img->mb_y_upd != img->mb_y_intra) || img->type == INTRA_IMG)
	    {
	      img->mb_mode=8*img->type+img->imod;  /* Intra mode: set if intra image or if intra GOB for error robustness */
	    }
		else						
	    {			
	      currMB->ref_frame = motion_search(tot_intra_sad);	/* Motion vector search for P-frames */ 
	    }
	}
    else													/* B-frame */
	currMB->ref_frame = motion_search_Bframe(tot_intra_sad); /* Motion vector search for B-frames */ 

    if (img->type == B_IMG)					/* B-frame */
	{
	  /* Residual coding of Luminance (only for B-modes) */
	  LumaResidualCoding_B(img);	
	  
	  /* Coding of Chrominance */
	  ChromaCoding_B(&cr_cbp);

	  /* Set loop filter strength depending on mode decision */
	  SetLoopfilterStrength_B(); 

	  /* Set reference frame information for motion vector prediction of future MBs */
	  SetRefFrameInfo_B();					
	}
      else									/* I- or P-frame */
	{
	  if (currMB->intraOrInter == INTER_MB)				
	    LumaResidualCoding_P();			/* Residual coding of Luminance (only for inter modes) */
	  /* Coding of Luma in intra mode is done implicitly in MakeIntraPredicition */
	  
	  /* Coding of Chrominance */
	  ChromaCoding_P(&cr_cbp);
	

⌨️ 快捷键说明

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