📄 rdopt.c
字号:
/*
*****************************************************************************
* 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 + -