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

📄 macroblock.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	  /* Set loop filter strength depending on mode decision */
	  SetLoopfilterStrength_P(); 
	  
	  /* Set reference frame information for motion vector prediction of future MBs */
	  SetRefFrameInfo_P();	
		
	  /*  Check if a MB is skipped (no coeffs. only 0-vectors and prediction from the most recent frame) */
	  if (img->mb_mode==M16x16_MB && currMB->intraOrInter == INTER_MB && (currMB->cbp == 0) 
	      && tmp_mv[0][img->block_y][img->block_x+4]==0 && tmp_mv[1][img->block_y][img->block_x+4]==0 
	      && (currMB->ref_frame == 0))
	    img->mb_mode=COPY_MB;	
	}

 	/* Set 16x16 intra mode and make "intra CBP" */
	if (img->imod==INTRA_MB_NEW)
    {
		img->mb_mode += intra_pred_mode_2 + 4*cr_cbp + 12*img->kac;
        currMB->cbp += 15*img->kac; /*GB*/
    }


    if (((img->type == INTER_IMG) && ((img->imod==INTRA_MB_NEW) || (img->imod==INTRA_MB_OLD)))
		|| (img->type == B_IMG && (img->imod==B_Backward || img->imod==B_Direct || img->imod==INTRA_MB_NEW || img->imod==INTRA_MB_OLD)))// gb b-frames too 
        currMB->ref_frame = 0;

#ifdef _RD_OPT_
    }
#endif
}

/************************************************************************
*
*  Name :       write_one_macroblock()
*
*  Description: Passes the chosen syntax elements to the NAL
*
************************************************************************/
void write_one_macroblock()
{
	int i;
	int mb_nr = img->current_mb_nr;
	SyntaxElement *currSE = img->MB_SyntaxElements;
	Macroblock *currMB = &img->mb_data[mb_nr];
	int *bitCount = currMB->bitcounter;
	Slice *currSlice = img->currentSlice;
	DataPartition *dataPart;
	int *partMap = assignSE2partition[input->partition_mode];

	/* Store imod for further use */
	currMB->mb_imode = img->imod;

	/* Store mb_mode for further use */
	currMB->mb_type = (currSE->value1 = img->mb_mode);

	/*  Bits for mode */
	if (input->symbol_mode == UVLC)
		currSE->mapping = n_linfo2;
	else
		currSE->writing = writeMB_typeInfo2Buffer_CABAC;
	currSE->type = SE_MBTYPE;

											
	/* choose the appropriate data partition */
	if (img->type != B_IMG)
	{
#if TRACE
		sprintf(currSE->tracestring, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,img->mb_mode);
#endif
		dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);

	}
	else
	{
#if TRACE
		sprintf(currSE->tracestring, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, img->mb_mode);
#endif
		dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
	}
	dataPart->writeSyntaxElement(	currSE, dataPart);
	bitCount[BITS_HEADER_MB]+=currSE->len;

	/* proceed to next SE */
	currSE++;
	currMB->currSEnr++;
	
	/*  Do nothing more if copy and inter mode  */
	if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB || img->type == B_IMG)
	{
		
		/*  Bits for intra prediction modes*/		
		if (img->imod == INTRA_MB_OLD)
		{
			for (i=0; i < MB_BLOCK_SIZE/2; i++)
			{
				currSE->value1 = currMB->intra_pred_modes[2*i];
				currSE->value2 = currMB->intra_pred_modes[2*i+1];
				if (input->symbol_mode == UVLC)
					currSE->mapping = intrapred_linfo;
				else
					currSE->writing = writeIntraPredMode2Buffer_CABAC;
				currSE->type = SE_INTRAPREDMODE;
											
				/* choose the appropriate data partition */
				if (img->type != B_IMG)
				{
#if TRACE
					sprintf(currSE->tracestring, "Intra mode     = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
					dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);

				}
				else
				{
#if TRACE
					sprintf(currSE->tracestring, "B_Intra mode = %3d\t",IPRED_ORDER[currSE->value1][currSE->value2]);
#endif
					dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);

				}
				dataPart->writeSyntaxElement(	currSE, dataPart);
				bitCount[BITS_COEFF_Y_MB]+=currSE->len;

				/* proceed to next SE */
				currSE++;
				currMB->currSEnr++;
			}
		}	
		/*  Bits for vector data*/
		if (img->type != B_IMG)
		{
			if (currMB->intraOrInter == INTER_MB) /* inter */
				writeMotionInfo2NAL_Pframe();
		}
		else
		{
			if(img->imod != B_Direct)
				writeMotionInfo2NAL_Bframe();
		}

		/* Bits for CBP and Coefficients */
		writeCBPandCoeffs2NAL();
	}
	bitCount[BITS_TOTAL_MB] =	bitCount[BITS_HEADER_MB] + bitCount[BITS_COEFF_Y_MB]	+ bitCount[BITS_INTER_MB] 
													+ bitCount[BITS_CBP_MB] + bitCount[BITS_COEFF_UV_MB];
	stat->bit_slice += bitCount[BITS_TOTAL_MB];
}

/************************************************************************
*
*  Name :       writeMotionInfo2NAL_Pframe()
*
*  Description: Passes for a given MB of a P picture the reference frame 
*								parameter and the motion vectors to the NAL 
*
************************************************************************/
#ifdef _RD_OPT_
int
#else
void
#endif
writeMotionInfo2NAL_Pframe()
{
	int i,j,k,l,m;
	int step_h,step_v;
	int curr_mvd;
	int mb_nr = img->current_mb_nr;
	Macroblock *currMB = &img->mb_data[mb_nr];
	SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
	int *bitCount = currMB->bitcounter;
	Slice *currSlice = img->currentSlice;
	DataPartition *dataPart;
	int *partMap = assignSE2partition[input->partition_mode];
#ifdef _RD_OPT_
	int no_bits = 0;
#endif
	
	/*	If multiple ref. frames, write reference frame for the MB */
#ifdef _ADDITIONAL_REFERENCE_FRAME_
	if (input->no_multpred > 1 || input->add_ref_frame > 0)
#else
	if (input->no_multpred > 1)
#endif
	{			

		currSE->value1 = currMB->ref_frame ;
		currSE->type = SE_REFFRAME;
		if (input->symbol_mode == UVLC)
			currSE->mapping = n_linfo2;
		else
			currSE->writing = writeRefFrame2Buffer_CABAC;
		dataPart = &(currSlice->partArr[partMap[currSE->type]]);
		dataPart->writeSyntaxElement(	currSE, dataPart);
		bitCount[BITS_INTER_MB]+=currSE->len;
#ifdef _RD_OPT_
		no_bits += currSE->len;
#endif
#if TRACE
		sprintf(currSE->tracestring, "Reference frame no %d", currMB->ref_frame);
#endif
				
		/* proceed to next SE */
		currSE++;
		currMB->currSEnr++;				
	}

	/* Write motion vectors */
	step_h=img->blc_size_h/BLOCK_SIZE;			/* horizontal stepsize */
	step_v=img->blc_size_v/BLOCK_SIZE;			/* vertical stepsize */
	
	for (j=0; j < BLOCK_SIZE; j += step_v)
	{
		for (i=0;i < BLOCK_SIZE; i += step_h)
		{
			for (k=0; k < 2; k++)
			{
				curr_mvd = tmp_mv[k][img->block_y+j][img->block_x+i+4]-img->mv[i][j][currMB->ref_frame][img->mb_mode][k];						

				img->subblock_x = i; // position used for context determination
				img->subblock_y = j; // position used for context determination
				currSE->value1 = curr_mvd;
				/* store (oversampled) mvd */
				for (l=0; l < step_v; l++) 
					for (m=0; m < step_h; m++)	
						currMB->mvd[0][j+l][i+m][k] =  curr_mvd;
				currSE->value2 = k; // identifies the component; only used for context determination
				currSE->type = SE_MVD;
				if (input->symbol_mode == UVLC)
					currSE->mapping = mvd_linfo2;
				else
					currSE->writing = writeMVD2Buffer_CABAC;
				dataPart = &(currSlice->partArr[partMap[currSE->type]]);
				dataPart->writeSyntaxElement(	currSE, dataPart);
				bitCount[BITS_INTER_MB]+=currSE->len;
#ifdef _RD_OPT_
				no_bits += currSE->len;
#endif
#if TRACE
				sprintf(currSE->tracestring, " MVD(%d) = %3d",k, curr_mvd);
#endif					
	
				/* proceed to next SE */
				currSE++;					
				currMB->currSEnr++;
						
			}
		}
	}		
#ifdef _RD_OPT_
	return no_bits;
#endif
}

/************************************************************************
*
*  Name :       writeCBPandCoeffs2NAL()
*
*  Description: Passes coded block pattern and coefficients (run/level)
*				to the NAL
*
************************************************************************/
void
writeCBPandCoeffs2NAL ()
{
  if (img->imod != INTRA_MB_NEW)
    {
      /* Bits for CBP */	  
      writeMB_bits_for_CBP  ();
      /* Bits for luma coefficients */
      writeMB_bits_for_luma (1);
    }
  else /* 16x16 based intra modes */
    {
      writeMB_bits_for_16x16_luma ();
    }
  /* Bits for chroma 2x2 DC transform coefficients */
  writeMB_bits_for_DC_chroma (1);
  /* Bits for chroma AC-coeffs. */		
  writeMB_bits_for_AC_chroma (1);
}	





int
writeMB_bits_for_CBP ()
{
  int           no_bits    = 0;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount  = currMB->bitcounter;
  DataPartition *dataPart;
  int           *partMap   = assignSE2partition[input->partition_mode];

  currSE->value1 = currMB->cbp;

#if TRACE
  sprintf(currSE->tracestring, "CBP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->cbp);
#endif

  if (img->imod == INTRA_MB_OLD) 
    {
      if (input->symbol_mode == UVLC)
	currSE->mapping = cbp_linfo_intra;
      currSE->type = SE_CBP_INTRA;
    }
  else
    {
      if (input->symbol_mode == UVLC)
	currSE->mapping = cbp_linfo_inter;
      currSE->type = SE_CBP_INTER;
    }

  if (input->symbol_mode == CABAC)
    currSE->writing = writeCBP2Buffer_CABAC;
											
  /* choose the appropriate data partition */
  if (img->type != B_IMG)
    dataPart = &(img->currentSlice->partArr[partMap[currSE->type]]);
  else
    dataPart = &(img->currentSlice->partArr[partMap[SE_BFRAME]]);

  dataPart->writeSyntaxElement(currSE, dataPart);
  bitCount[BITS_CBP_MB]+=currSE->len;
  no_bits              +=currSE->len;

  /* proceed to next SE */
  currSE++;	
  currMB->currSEnr++;
		
  return no_bits;
}





int
writeMB_bits_for_luma (int  filtering)
{
  int no_bits = 0;
  int cbp     = img->mb_data [img->current_mb_nr].cbp;
  int mb_y, mb_x, i, j, ii, jj, bits;

  for (mb_y=0; mb_y < 4; mb_y += 2)
    {
      for (mb_x=0; mb_x < 4; mb_x += 2)
	{
	  for (j=mb_y; j < mb_y+2; j++)
	    {
	      jj=j/2;
	      for (i=mb_x; i < mb_x+2; i++)
		{
		  ii=i/2;
		  if ((cbp & (1<<(ii+jj*2))) != 0) 	      /* check for any coefficients */
		    {
		      no_bits += (bits = writeMB_bits_for_4x4_luma (i, j, filtering));
		    }
		  else bits = 0;
#ifdef _RD_DEBUG_I4MODE_
		  rcdebug_set_luma_rate_4x4 (i, j, bits);
#endif
		}
	    }
	}
    }
  return no_bits;
}





int
writeMB_bits_for_4x4_luma (int i, int j, int  filtering)
{
  int           no_bits    = 0;
  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount  = currMB->bitcounter;
  Slice         *currSlice = img->currentSlice;
  DataPartition *dataPart;
  int           *partMap   = assignSE2partition[input->partition_mode];

  int kk,kbeg,kend;
  int level, run;
  int k;


  if (img->imod == INTRA_MB_OLD && img->qp < 24)	/* double scan */
    {
			      
      for(kk=0;kk<2;kk++)
	{
	  kbeg=kk*9;
	  kend=kbeg+8;
	  level=1; /* get inside loop */
				  
	  for(k=kbeg;k <= kend && level !=0; k++)
	    {
	      level = currSE->value1 = img->cof[i][j][k][0][DOUBLE_SCAN]; // level
	      run   = currSE->value2 = img->cof[i][j][k][1][DOUBLE_SCAN]; // run
				      
	      if (input->symbol_mode == UVLC)
		currSE->mapping = levrun_linfo_intra;	
	      else
		{
		  currSE->context = 0; // for choosing context model
		  currSE->writing = writeRunLevel2Buffer_CABAC;
		}
				      
	      if (k == kbeg)
		{ 
		  currSE->type  = SE_LUM_DC_INTRA; /* element is of type DC */
					  
		  /* choose the appropriate data partition */
		  if (img->type != B_IMG)
		    dataPart = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
		  else
		    dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
		}
	      else
		{
		  currSE->type  = SE_LUM_AC_INTRA;   /* element is of type AC */
					  
		  /* choose the appropriate data partition */
		  if (img->type != B_IMG)
		    dataPart = &(currSlice->partArr[partMap[SE_LUM_AC_INTRA]]);
		  else
		    dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
		}
	      dataPart->writeSyntaxElement (currSE, dataPart);
	      bitCount[BITS_COEFF_Y_MB]+=currSE->len;
	      no_bits                  +=currSE->len;
#if TRACE
	      sprintf(currSE->tracestring, "Luma dbl(%2d,%2d)  level=%3d Run=%2d",kk,k,level,run);
#endif							
	      /* proceed to next SE */
	      currSE++;	
	      currMB->currSEnr++;
				      
	      if (level!=0 && filtering)
		{
		  loopb[img->block_x+i+1][img->block_y+j+1]=max(loopb[img->block_x+i+1][img->block_y+j+1],2);
		  loopb[img->block_x+i	][img->block_y+j+1]=max(loopb[img->block_x+i  ][img->block_y+j+1],1);
		  loopb[img->block_x+i+1][img->block_y+j  ]=max(loopb[img->block_x+i+1][img->block_y+j	],1);
		  loopb[img->block_x+i+2][img->block_y+j+1]=max(loopb[img->block_x+i+2][img->block_y+j+1],1);
		  loopb[img->block_x+i+1][img->block_y+j+2]=max(loopb[img->block_x+i+1][img->block_y+j+2],1);
		}
	    }
	}
    }
  else     /* single scan */
    {
      level=1; /* get inside loop */
      for(k=0;k<=16 && level !=0; k++)
	{
	  level = currSE->value1 = img->cof[i][j][k][0][SINGLE_SCAN]; // level
	  run   = currSE->value2 = img->cof[i][j][k][1][SINGLE_SCAN]; // run
				  
	  if (input->symbol_mode == UVLC)
	    currSE->mapping = levrun_linfo_inter;		
	  else							
	    currSE->writing = writeRunLevel2Buffer_CABAC;
				  
	  if (k == 0)
	    { 
	      if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
		{
		  currSE->context = 2; // for choosing context model
		  currSE->type  = SE_LUM_DC_INTRA;
		}

⌨️ 快捷键说明

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