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

📄 rdopt.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************
 *
 * Modul       :  rdopt.c
 * Author      :  Heiko Schwarz <hschwarz@hhi.de>
 * Date        :  12. April 2001
 *
 * Description :  Rate-Distortion optimized mode decision
 * 	  
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include "rdopt.h"


#ifdef _RD_OPT_

#ifdef USE_9_INTRA_MODES
extern const byte PRED_IPRED[10][10][9];
#else // !USE_9_INTRA_MODES
extern const byte PRED_IPRED[7][7][6];
#endif

extern       int  QP2QUANT  [32];

/*=== static parameters ===*/
RDOpt  *rdopt     = NULL;


int    *forward_me_done[9];
int    *tot_for_sad[9];





/************************************************************************
 *
 *  Name :       clear_rdopt()
 *
 *  Description: delete structure for RD-optimized mode decision
 *
 ************************************************************************/
void
clear_rdopt ()
{
  int i;

  /* rd-optimization structure */
  if (rdopt != NULL)
    {
      free (rdopt);
      rdopt = NULL;

      for (i=0; i<9; i++)
	{
	  free (forward_me_done[i]);
	  free (tot_for_sad    [i]);
	}
    }

  /* structure for saving the coding state */
  clear_coding_state ();
}





/************************************************************************
 *
 *  Name :       init_rdopt()
 *
 *  Description: create structure for RD-optimized mode decision
 *
 ************************************************************************/
void
init_rdopt ()
{
  int i;

  if (!input->rdopt)
    return;  

  clear_rdopt ();

  /* rd-optimization structure */
  if ((rdopt = (RDOpt*) calloc (1, sizeof(RDOpt))) == NULL)
    {
      fprintf (stderr, "Memory allocation for RDOpt datastruct failed\n");
      exit(1);
    }

  for (i=0; i<9; i++)
    {
      if ((forward_me_done[i] = (int*)malloc (img->buf_cycle*sizeof(int))) == NULL) no_mem_exit (1);
      if ((tot_for_sad    [i] = (int*)malloc (img->buf_cycle*sizeof(int))) == NULL) no_mem_exit (1);
    }


  /* structure for saving the coding state */
  init_coding_state ();
}



/************************************************************************
 *
 *  Name :       RDCost_Intra4x4_Block()
 *
 *  Description: set Rate-Distortion cost of 4x4 Intra modes
 *
 ************************************************************************/
void
RDCost_Intra4x4_Block (int             block_x,
		       int             block_y,
		       int             ipmode)
{
  int             dummy, left_ipmode, upper_ipmode, curr_ipmode, x, y;
  int             i            = block_x >> 2;
  int             j            = block_y >> 2;
  int             pic_block_x  = (img->pix_x+block_x) / BLOCK_SIZE;
  int             pic_block_y  = (img->pix_y+block_y) / BLOCK_SIZE;
  int             even_block   = ((i & 1) == 1);
  Slice          *currSlice    =  img->currentSlice;
  Macroblock     *currMB       = &img->mb_data[img->current_mb_nr];
  SyntaxElement  *currSE       = &img->MB_SyntaxElements[currMB->currSEnr];
  int            *partMap      = assignSE2partition[input->partition_mode];
  DataPartition  *dataPart;


  /*===== perform DCT, Q, IQ, IDCT =====*/
  dct_luma (block_x, block_y, &dummy);

  /*===== get distortion (SSD) of 4x4 block =====*/
  for   (y=0; y < BLOCK_SIZE; y++)
    for (x=0; x < BLOCK_SIZE; x++)
      {
		dummy = imgY_org[img->pix_y+block_y+y][img->pix_x+block_x+x] - img->m7[x][y];
		rdopt->distortion_4x4[j][i][ipmode] += img->quad[abs(dummy)];
      }
  rdopt->rdcost_4x4[j][i][ipmode] = (double)rdopt->distortion_4x4[j][i][ipmode];
  if (rdopt->rdcost_4x4[j][i][ipmode] >= rdopt->min_rdcost_4x4[j][i])
    return;

  /*===== store the coding state =====*/
  store_coding_state ();

  /*===== get (estimate) rate for intra prediction mode =====*/
  /*--- set or estimate the values of syntax element ---*/
  if (even_block)
    /* EVEN BLOCK: the values the of syntax element can be set correctly */
    {
      /* value of last block */
      upper_ipmode   =  img->ipredmode [pic_block_x  ][pic_block_y  ];
      left_ipmode    =  img->ipredmode [pic_block_x-1][pic_block_y+1];
      curr_ipmode    =  img->ipredmode [pic_block_x  ][pic_block_y+1];
      currSE->value1 =  PRED_IPRED [upper_ipmode+1][left_ipmode+1][curr_ipmode];
      /* value of this block */
      upper_ipmode   =  img->ipredmode [pic_block_x+1][pic_block_y  ];
      currSE->value2 =  PRED_IPRED [upper_ipmode+1][curr_ipmode+1][ipmode];
    }
  else
    /* ODD BLOCK:  the second value of the syntax element cannot be set, since
     *             it will be known only after the next step. For estimating
     *             the rate the corresponding prediction mode is set to zero
     *             (minimum rate). */
    {
      upper_ipmode   =  img->ipredmode [pic_block_x+1][pic_block_y  ];
      left_ipmode    =  img->ipredmode [pic_block_x  ][pic_block_y+1];
      currSE->value1 =  PRED_IPRED [upper_ipmode+1][left_ipmode+1][ipmode];
      currSE->value2 =  0; /* value with maximum probability */
    }
  /*--- set function pointers for syntax element ---*/
  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)     dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
  else                        dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
  /*--- get length of syntax element ---*/
  dataPart->writeSyntaxElement (currSE, dataPart);
  rdopt->rate_imode_4x4[j][i][ipmode] = currSE->len;
  rdopt->rdcost_4x4[j][i][ipmode] += rdopt->lambda_intra*(double)rdopt->rate_imode_4x4[j][i][ipmode];
  if (rdopt->rdcost_4x4[j][i][ipmode] >= rdopt->min_rdcost_4x4[j][i])
    {
      restore_coding_state ();
      return;
    }
  currSE++;
  currMB->currSEnr++;

  /*===== get rate for luminance coefficients =====*/
  rdopt->rate_luma_4x4[j][i][ipmode] = writeMB_bits_for_4x4_luma (i, j, 0);
  rdopt->rdcost_4x4[j][i][ipmode] += rdopt->lambda_intra*(double)rdopt->rate_luma_4x4[j][i][ipmode];

  /*===== restore the saved coding state =====*/
  restore_coding_state ();

  /*===== update best mode =====*/
  if (rdopt->rdcost_4x4[j][i][ipmode] < rdopt->min_rdcost_4x4[j][i])
    {
      rdopt->best_mode_4x4 [j][i] = ipmode;
      rdopt->min_rdcost_4x4[j][i] = rdopt->rdcost_4x4[j][i][ipmode];
    }
}





/************************************************************************
 *
 *  Name :       RD_Intra4x4_Mode_Decision()
 *
 *  Description: Get best 4x4 Intra mode by rate-dist-based decision
 *
 ************************************************************************/
int
RD_Intra4x4_Mode_Decision (int              block_x,
			   int              block_y)
{
  int  ipmode, i, j;
  int  index_y     = block_y >> 2;
  int  index_x     = block_x >> 2;
  int  pic_pix_y   = img->pix_y + block_y;
  int  pic_pix_x   = img->pix_x + block_x;
  int  pic_block_y = pic_pix_y / BLOCK_SIZE;
  int  pic_block_x = pic_pix_x / BLOCK_SIZE;

  typedef int (*WRITE_SE)(SyntaxElement*, struct datapartition*);
  WRITE_SE     *writeSE=0;
  int           symbol_mode;



  /*=== set symbol mode to UVLC (CABAC does not work correctly -> wrong coding order) ===*
   *=== and store the original symbol mode and function pointers                      ===*/
  symbol_mode = input->symbol_mode;
  if (input->symbol_mode != UVLC)
    {
      input->symbol_mode = UVLC;
      if ((writeSE = (WRITE_SE*) calloc (img->currentSlice->max_part_nr, sizeof (WRITE_SE))) == NULL)
		{
			fprintf (stderr, "Memory allocation in RDGet_4x4IntraMode failed!\n");
			exit (1);
		}
      for (i=0; i<img->currentSlice->max_part_nr; i++)
		{
			writeSE[i] = img->currentSlice->partArr[i].writeSyntaxElement;
			img->currentSlice->partArr[i].writeSyntaxElement = writeSyntaxElement_UVLC;
		}
    }


  /*=== LOOP OVER ALL 4x4 INTRA PREDICTION MODES ===*/
  rdopt->best_mode_4x4 [index_y][index_x] = -1;
  rdopt->min_rdcost_4x4[index_y][index_x] =  1e30;
  for (ipmode=0; ipmode < NO_INTRA_PMODE; ipmode++)
    {
      rdopt->rdcost_4x4    [index_y][index_x][ipmode] = -1;
      rdopt->distortion_4x4[index_y][index_x][ipmode] =  0;
      rdopt->rate_imode_4x4[index_y][index_x][ipmode] =  0;
      rdopt->rate_luma_4x4 [index_y][index_x][ipmode] =  0;
      
      /* Horizontal pred from Y neighbour pix , vertical use X pix, diagonal needs both */
      if (ipmode==DC_PRED || ipmode==HOR_PRED || img->ipredmode[pic_block_x+1][pic_block_y] >= 0)
		/* DC or vert pred or hor edge*/
		{
			if (ipmode==DC_PRED || ipmode==VERT_PRED || img->ipredmode[pic_block_x][pic_block_y+1] >= 0)
			/* DC or hor pred or vert edge*/
			{
				/* find diff */
				for   (j=0; j < BLOCK_SIZE; j++)
				  for (i=0; i < BLOCK_SIZE; i++)
					img->m7[i][j] = imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mprr[ipmode][j][i];
				/* copy intra prediction block */
				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];
				/* get lagrangian cost */
				RDCost_Intra4x4_Block (block_x, block_y, ipmode);
			}
		}
    }

  /*=== restore the original symbol mode and function pointers ===*/
  if (symbol_mode != UVLC)
    {
      input->symbol_mode = symbol_mode;
      for (i=0; i<img->currentSlice->max_part_nr; i++)
		{
			img->currentSlice->partArr[i].writeSyntaxElement = writeSE[i];
		}
	  free (writeSE);
    }

  return rdopt->best_mode_4x4[index_y][index_x];
}





/************************************************************************
 *
 *  Name :       Intra4x4_Mode_Decision ()
 *
 *  Description: Rate-Distortion opt. mode decision for 4x4 intra blocks
 *
 ************************************************************************/
void
Intra4x4_Mode_Decision ()
{
  int i,j;
  int block_x, block_y;
  int best_ipmode;
  int coeff_cost; // not used
  int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
  int last_ipred=0;		        /* keeps last chosen intra prediction mode for 4x4 intra pred */
  int nonzero;                          /* keep track of nonzero coefficients */
  int cbp_mask;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  /* start making 4x4 intra prediction */
  currMB->cbp=0;
  img->mb_data[img->current_mb_nr].intraOrInter = INTRA_MB_4x4;
		
  for(block_y = 0 ; block_y < MB_BLOCK_SIZE ; block_y += BLOCK_MULTIPLE)
    {
      pic_pix_y=img->pix_y+block_y;
      pic_block_y=pic_pix_y/BLOCK_SIZE;

      for(block_x = 0 ; block_x < MB_BLOCK_SIZE  ; block_x += BLOCK_MULTIPLE)
		{
			cbp_mask=(1<<(2*(block_y/8)+block_x/8));
			pic_pix_x=img->pix_x+block_x;
			pic_block_x=pic_pix_x/BLOCK_SIZE;

			/*
			intrapred_luma() makes and returns 4x4 blocks with all 5 intra prediction modes.
			Notice that some modes are not possible at frame edges.
			*/
			intrapred_luma (pic_pix_x,pic_pix_y);

			/*=== rate-constrained mode decision ===*/
			best_ipmode = RD_Intra4x4_Mode_Decision (block_x, block_y);

			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 */

⌨️ 快捷键说明

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