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

📄 rdopt.c

📁 avs-s最新代码,包括编码器和解码器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*                     
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under 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 for standardization procedure is available at 
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard 
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors:   Guoping Li,    Siwei Ma,    Jian Lou,    Qiang Wang , 
*   Jianwen Chen,Haiwu Zhao,  Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
* 
******************************************************************************
*/



/*
*************************************************************************************
* File name: 
* Function: 
*
*************************************************************************************
*/

#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <assert.h>
#include "rdopt_coding_state.h"
#include "memalloc.h"
#include "refbuf.h"
#include "block.h"
#include "vlc.h"
#include "macroblock.h"
#include "ratectl.h"
#include "global.h"

#ifdef FastME
#include "fast_me.h"
#endif

//Rate control
extern       int  QP2QUANT  [40];
int QP,QP2;
int DELTA_QP,DELTA_QP2;
int diffy[16][16];
static int pred[16][16];

extern       int  QP2QUANT  [40];

//==== MODULE PARAMETERS ====
int   best_mode;
int   rec_mbY[16][16], rec_mbU[8][8], rec_mbV[8][8], rec_mbY8x8[16][16];    // reconstruction values
int   mpr8x8[16][16];
int   ****cofAC=NULL, ****cofAC8x8=NULL;        // [8x8block][4x4block][level/run][scan_pos]
int   ***cofDC=NULL;                       // [yuv][level/run][scan_pos]
int   ***cofAC4x4=NULL, ****cofAC4x4intern=NULL; // [level/run][scan_pos]
int   ****chromacofAC4x4=NULL;
int   cbp, cbp8x8, cnt_nonz_8x8;
int   cbp_blk, cbp_blk8x8;
int   frefframe[2][2], brefframe[2][2], b8mode[4], b8pdir[4];
int   best8x8mode [4];                // [block]
int   best8x8pdir [MAXMODE][4];       // [mode][block]
int   best8x8ref  [MAXMODE][4];       // [mode][block]
int   b8_ipredmode[4], b8_intra_pred_modes[4];
CSptr cs_mb=NULL, cs_b8=NULL, cs_cm=NULL;
int   best_c_imode;
int   best_weight_flag ; // !!  shenyanfei 


int   best8x8bwref     [MAXMODE][4];       // [mode][block]
int   best8x8symref     [MAXMODE][4][2];       // [mode][block]

int   best_intra_pred_modes_tmp[4];
int   best_ipredmode_tmp[2][2];
int   best_mpr_tmp[16][16];
int   best_dct_mode;


#define IS_FW ((best8x8pdir[mode][k]==0 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0 || !bframe))
#define IS_BW ((best8x8pdir[mode][k]==1 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0))

/*
*************************************************************************
* Function:delete structure for RD-optimized mode decision
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void clear_rdopt ()
{
  free_mem_DCcoeff (cofDC);
  free_mem_ACcoeff (cofAC);
  free_mem_ACcoeff (cofAC8x8);
  free_mem_ACcoeff (cofAC4x4intern);
	free_mem4Dint(chromacofAC4x4, 2, 4 );

  // structure for saving the coding state
  delete_coding_state (cs_mb);
  delete_coding_state (cs_b8);
  delete_coding_state (cs_cm);

}

/*
*************************************************************************
* Function:create structure for RD-optimized mode decision
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void init_rdopt ()
{
  get_mem_DCcoeff (&cofDC);
  get_mem_ACcoeff (&cofAC);
  get_mem_ACcoeff (&cofAC8x8);
  get_mem_ACcoeff (&cofAC4x4intern);
  cofAC4x4 = cofAC4x4intern[0];
	get_mem4Dint(&(chromacofAC4x4),2,4,2,17);

  // structure for saving the coding state
  cs_mb  = create_coding_state ();
  cs_b8  = create_coding_state ();
  cs_cm  = create_coding_state ();

}

/*
*************************************************************************
* Function:Get RD cost for AVS intra block
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

double RDCost_for_AVSIntraBlocks(int *nonzero,
                                 int b8,
                                 int ipmode,
                                 double lambda,
                                 double  min_rdcost,
                                 int mostProbableMode)
{
  int x,y,rate,tmp_cbp,tmp_cbp_blk;
  int distortion;
  int block_x;
  int block_y;
  int pic_pix_x;
  int pic_pix_y;
  int pic_block_x;
  int pic_block_y;
  int even_block;
  short tmp_block_88_inv[8][8];
  Macroblock  *currMB;
  SyntaxElement *currSE;
	int incr_y=1,off_y=0;/*lgp*/

  block_x    =8*(b8%2);
  block_y    =8*(b8/2);
  pic_pix_x  =img->pix_x+block_x;
  pic_pix_y  =img->pix_y+block_y;
  pic_block_x=pic_pix_x/4;
  pic_block_y=pic_pix_y/4;
  even_block =0;
  currMB   =&img->mb_data[img->current_mb_nr];
  currSE   =&img->MB_SyntaxElements[currMB->currSEnr];
  //===== perform DCT, Q, IQ, IDCT, Reconstruction =====
  
  for(y=0;y<8;y++)
    for(x=0;x<8;x++)
      tmp_block_88_inv[y][x]=img->m7[x][y];        //the subblock to be processed is in the top left corner of img->m7[][].

  tmp_cbp=tmp_cbp_blk=0;
	
	transform_B8(tmp_block_88_inv);
	//Lou 1013  scanquant_B8(img->qp+QP_OFS-MIN_QP,4,b8,tmp_block_88_inv,0,&tmp_cbp,&tmp_cbp_blk); // '|4' indicate intra for quantization
	scanquant_B8   (img->qp-MIN_QP,4,b8,tmp_block_88_inv,0,&tmp_cbp,&tmp_cbp_blk); // '|4' indicate intra for quantization		

		//digipro_0
  //scanquant returns a SCR value!.....
  *nonzero=(tmp_cbp!=0);

  //===== get distortion (SSD) of 4x4 block =====
  distortion =0;

	/*lgp*/
  for (y=0; y<8; y++)
    for (x=0; x<8; x++)
      distortion += img->quad [imgY_org[pic_pix_y+incr_y*y+off_y][pic_pix_x+x] - imgY[pic_pix_y+incr_y*y+off_y][pic_pix_x+x]];

  //===== RATE for INTRA PREDICTION MODE  (SYMBOL MODE MUST BE SET TO UVLC) =====
  currSE->value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;

  //--- set position and type ---
  currSE->context = 4*b8;
  currSE->type    = SE_INTRAPREDMODE;

  //--- encode and update rate ---
  writeSyntaxElement_Intra4x4PredictionMode(currSE, currBitStream);
  
  rate = currSE->len;
  currSE++;
  currMB->currSEnr++;

  //===== RATE for LUMINANCE COEFFICIENTS =====
  
  x=currMB->cbp;
  currMB->cbp=tmp_cbp;//writeLumaCoeffAVS_B8 needs a correct Macroblock->cbp .
	rate+=writeLumaCoeffAVS_B8(b8,1);
  currMB->cbp=x;

  //calc RD and return it.
  return (double)distortion+lambda*(double)rate;
}

/*
*************************************************************************
* Function:Mode Decision for AVS intra blocks
     This might also be placed in rdopt.c behind Mode_Decision_for_4x4IntraBlocks().
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

int Mode_Decision_for_AVS_IntraBlocks(int b8,double lambda,int *min_cost)
{
  int ipmode,best_ipmode,i,j,x,y,cost,loc_cbp,loc_cbp_blk;
  int c_nz, nonzero, rec4x4[8][8], diff[16][16];
  double rdcost;
  int block_x;
  int block_y;
  int pic_pix_x;
  int pic_pix_y;
  int pic_block_x;
  int pic_block_y;
  short tmp_block_88[8][8];
  int upMode;
  int leftMode;
  int mostProbableMode;
  Macroblock *currMB;
  double min_rdcost ;
  int incr_y=1,off_y=0;/*lgp*/
  int MBRowSize = img->width / MB_BLOCK_SIZE;/*lgp*/
  int k;

  currMB=img->mb_data+img->current_mb_nr;

  block_x    =8*(b8&1);
  block_y    =8*(b8>>1);
  pic_pix_x  =img->pix_x+block_x;
  pic_pix_y  =img->pix_y+block_y;
  pic_block_x=pic_pix_x>>3;
  pic_block_y=pic_pix_y>>3;
  min_rdcost =1e30;
	
  
  *min_cost = (1<<20);
  
  upMode           = img->ipredmode[pic_block_x+1][pic_block_y  ];
  leftMode         = img->ipredmode[pic_block_x  ][pic_block_y+1];
  mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
    
  
  //===== INTRA PREDICTION FOR 4x4 BLOCK =====
  intrapred_luma_AVS(pic_pix_x,pic_pix_y);
  
  //===== LOOP OVER ALL INTRA PREDICTION MODES =====
  for (ipmode=0;ipmode<NO_INTRA_PMODE;ipmode++)
  {
    if(img->mprr[ipmode][0][0]>=0)        //changed this. the intrapred function marks the invalid modes. At least one is always valid (the DC).
    {
      if(!input->rdopt)
      {
        for (j=0;j<8;j++)
          for (i=0;i<8;i++)
            diff[j][i] = imgY_org[pic_pix_y+/*j*/incr_y*j+off_y/*lgp*/][pic_pix_x+i] - img->mprr[ipmode][j][i]; // bug fix: index of diff was flipped. mwi 020701

 //       cost  = (ipmode == mostProbableMode) ? 0 : (int)floor(4 * lambda );
          cost  = (ipmode == mostProbableMode) ? 0 : (int)floor(3 * lambda );   // jlzheng  7.20
          
        cost+=find_sad_8x8(input->hadamard,8,8,0,0,diff);
          
        if (cost < *min_cost)
        {
          best_ipmode = ipmode;
          *min_cost   = cost;
        }
      }
      else
      {
        // get prediction and prediction error
        for (j=0;j<8;j++)
          for (i=0;i<8;i++)
          {
            img->mpr[block_x+i][block_y+j]=img->mprr[ipmode][j][i];
            img->m7[i][j] = imgY_org[pic_pix_y+/*j*/incr_y*j+off_y/*lgp*/][pic_pix_x+i] - img->mpr[block_x+i][block_y+j] ;
          }
          
        //===== store the coding state =====
        store_coding_state (cs_cm);
          
        // get and check rate-distortion cost
        if ((rdcost = RDCost_for_AVSIntraBlocks(&c_nz,b8,ipmode,lambda,min_rdcost, mostProbableMode)) < min_rdcost)
        {
          //--- set coefficients ---
          for(j=0;j<2;j++)
            for(k=0;k<4;k++)
              for(i=0;i<65;i++)
                cofAC4x4[k][j][i]=img->cofAC[b8][k][j][i];
            
          //--- set reconstruction ---
          for(y=0; y<8; y++)
            for(x=0; x<8; x++)
              rec4x4[y][x]=imgY[pic_pix_y+/*y*/incr_y*y+off_y/*lgp*/][pic_pix_x+x];
                
          //--- flag if dct-coefficients must be coded ---
          nonzero = c_nz;
                
          //--- set best mode update minimum cost ---
          min_rdcost  = rdcost;
          *min_cost=(int)min_rdcost;
          best_ipmode = ipmode;
        }
        reset_coding_state (cs_cm);
      }
    }
  }
  
  //===== set intra mode prediction =====
  
  img->ipredmode[pic_block_x+1][pic_block_y+1] = best_ipmode;
  currMB->intra_pred_modes[b8] = mostProbableMode == best_ipmode ? -1 : best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
//  best_ipmode = mostProbableMode == best_ipmode ? best_ipmode : best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
/*  if(!pred_mode_flag)
  best_ipmode = best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
  else
   best_ipmode = mostProbableMode;*/
  
  
  /*lgp*/
  if (!input->rdopt)
  {
		
		// get prediction and prediction error
		for (j=0;j<8; j++)
			for (i=0;i<8; i++)
			{
				img->mpr[block_x+i][block_y+j] = img->mprr[best_ipmode][j][i];
				tmp_block_88[j][i] = imgY_org[pic_pix_y+/*j*/incr_y*j+off_y/*lgp*/][pic_pix_x+i] - img->mprr[best_ipmode][j][i];
			}

			loc_cbp=loc_cbp_blk=0;
			
			transform_B8(tmp_block_88);
				//Lou 1013			scanquant_B8(img->qp+QP_OFS-MIN_QP,4,b8,tmp_block_88,0,&loc_cbp,&loc_cbp_blk); // '|4' indicate intra for quantization
			scanquant_B8   (img->qp-MIN_QP,4,b8,tmp_block_88,0,&loc_cbp,&loc_cbp_blk); // '|4' indicate intra for quantization
				
			//digipro_1			
			//scanquant returns a SCR value!.....
			nonzero=(loc_cbp!=0);
			currMB->cbp|=loc_cbp;
			currMB->cbp_blk|=loc_cbp_blk;
	}
	else
	{/*lgp*/
    //===== restore coefficients =====
		for(j=0;j<2;j++)
      for(k=0;k<4;k++)
			  for(i=0;i<65;i++)
				  img->cofAC[b8][k][j][i] = cofAC4x4[k][j][i];

    //--- set reconstruction ---
		for(y=0; y<8; y++)
			for(x=0; x<8; x++)
			{
				imgY[pic_pix_y+incr_y*y+off_y][pic_pix_x+x] = rec4x4[y][x];
				img->mpr[block_x+i][block_y+j] = img->mprr[best_ipmode][j][i];
			}			
  }/*lgp*/

    
  return nonzero;
}


/*
*************************************************************************
* Function:Mode Decision for an 8x8 Intra block
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

⌨️ 快捷键说明

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