www.pudn.com > wm2.5.zip > rdopt.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2004, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder 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 is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include "global.h" #include "interpred.h" #include "intrapred.h" #include "macroblock.h" #include "block.h" #include "rdopt.h" #include "ratectl.h" // LX 0409 extern MacroblockHeader MbHeader; // LX 0409 /* ************************************************************************* * Function:Save RD cost state * Input: * Output: * Return: * Attention: ************************************************************************* */ void Save_RD_State() { pgRDStream->bits_to_go = pgcurrBitStream->bits_to_go; pgRDStream->byte_buf = pgcurrBitStream->byte_buf; pgRDStream->byte_pos = pgcurrBitStream->byte_pos; } /* ************************************************************************* * Function:Restore RD cost state * Input: * Output: * Return: * Attention: ************************************************************************* */ void Restore_RD_State() { pgcurrBitStream->bits_to_go = pgRDStream->bits_to_go; pgcurrBitStream->byte_buf = pgRDStream->byte_buf; pgcurrBitStream->byte_pos = pgRDStream->byte_pos; } /* ************************************************************************* * Function:Calculate RD cost for a macroblock * Input: * Output: * Return: * Attention: ************************************************************************* */ double RD_Cost_Macrobock() { double distortion; double rdcost; int rate; int i, j, uv; int pic_x = pgMbData->mb_x<<4; int pic_y = pgMbData->mb_y<<4; int pic_c_x = pic_x>>1; int pic_c_y = pic_y>>1; write_one_macroblock(); rate = (pgcurrBitStream->byte_pos - pgRDStream->byte_pos)*8 + (pgRDStream->bits_to_go-pgcurrBitStream->bits_to_go); distortion = 0; for(j=0; j<16; j++) for(i=0; i<16; i++) distortion += quadarr[pgMbData->org_luma[j][i]-imgY[pic_y+j][pic_x+i]]; for(uv=0; uv<2; uv++) for(j=0; j<8; j++) for(i=0; i<8; i++) distortion += quadarr[pgMbData->org_chroma[uv][j][i]-imgUV[uv][pic_c_y+j][pic_c_x+i]]; rdcost = distortion + pgMbData->lamda_mode * rate; return rdcost; } /* ************************************************************************* * Function:Calculate RD cost for Inter macroblock * Input: * Output: * Return: * Attention: ************************************************************************* */ int RD_Cost_Inter_Macrobock() { int blocktype; int b8, b4; int i, j, k; int pic_block_x, pic_block_y; int step_h0, step_v0; int img_x = (pgMbData->mb_x<<4); int img_y = (pgMbData->mb_y<<4); int img_c_x = img_x>>1; int img_c_y = img_y>>1; double rdcost, intra_rdcost; int min_cost = 1<<30;//WJP int coeff_cost; int best_mode=1;//WJP int dummy; int old_skip_counter; int best_abt_size, abt_size_flag=0; //cbzhu 12-15 #ifdef _ISOLATED_REGION_ int iregallow=1; int m,n; #endif for(blocktype=1; blocktype<=4; blocktype++) { //cbzhu 12-15 #ifdef _ISOLATED_REGION_ iregallow=1; if(input.IREGEnable) { if(pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { for(m=0;m<4;m++) { for(n=0;n<4;n++) { if(iIREGReliableFrmFlag==1 || iIREGState==2*input.IREGRate || input.num_reference_frames==1) if(typemap[0][blocktype-1][m][n]==0) { iregallow=0; break; } else if(typemap[0][blocktype-1][m][n]==0 && typemap[1][blocktype-1][m][n]==0) { iregallow=0; break; } } if(iregallow==0)break; } } if(iregallow==0) { rdcost=1<<30; continue; } } #endif //_ISOLATED_REGION_ Restore_Motion_Vector(blocktype); //restore reference index for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { refFrArr[pgImage->block_y+((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] = sInter_Ref[blocktype][b8][b4]; } //WJP 040824N if(input.ABT_RDO) abt_size_flag=!abt_size_flag; //qhg for abt else if (blocktype<4) { abt_size_flag=1; } //WJP 040824N pgMbData->best_mode = blocktype; // P8x8 used when blocktype == 4 pgMbHeader->mb_type = blocktype; if(pgMbHeader->mb_type == 4) //qwang 2004-3-22 { for(i=0; i<4; i++) pgMbHeader->subblk_type[i] = pgMbData->best_mode_subblk[i]; abt_size_flag=0; } //--- Set the numbers of MV --- pgMbHeader->mv_num = (pgMbData->best_mode == 3) ? 2 : pgMbData->best_mode; //--- Update left ref --- pgMbData->left_ref = 0; //--- Update Intra line buffer --- for (b8=0;b8<4;b8++) for (b4=0;b4<4;b4++) { pic_block_x=(img_x/4 + 2*(b8%2)+(b4%2)); pic_block_y=(img_y/4 + 2*(b8/2)+(b4/2)); ipredmode[pic_block_x+1][img_y/4+1] = (active_pps->constrained_intra_pred_flag ? -1 : 10);//MZ /* if(active_pps->constrained_intra_pred_flag) c_ipredmode[img_x/16+1][img_y/16+1] = -1;//zhangnan else c_ipredmode[img_x/16+1][img_y/16+1] = 0; //MZ 04-03 */ } //--- Get RefIndex info --- //zhangnan step_h0 = (csiInter_Block_Size[pgMbHeader->mb_type-1][0] >> 2); step_v0 = (csiInter_Block_Size[pgMbHeader->mb_type-1][1] >> 2); //??? zhangnan for (j=0; j<4; j+=step_v0) for (i=0; i<4; i+=step_h0) { k=j+(i/2); pgMbHeader->refIndex[k] = refFrArr[pgMbData->mb_y*4+j][pgMbData->mb_x*4+i]; } //--- Get MVD info --- for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { pgMbHeader->mvd[b8][b4][0] = pgMbData->mvb[b8][b4][0] - pgMbData->pred_mv[b8][b4][0]; pgMbHeader->mvd[b8][b4][1] = pgMbData->mvb[b8][b4][1] - pgMbData->pred_mv[b8][b4][1]; } for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { tmp_mv[0][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb[b8][b4][0]; tmp_mv[1][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb[b8][b4][1]; } //--- Reset cbp --- pgMbHeader->cbp = 0; // dongjie for(i=0;i<6;i++) pgMbHeader->cbp_4x4[i] = 0; // end Inter_ReLoad_Residual(); for (b8=0; b8<4; b8++) //zhangnan { coeff_cost = 0; coeff_cost_4x4[0]=coeff_cost_4x4[1]=coeff_cost_4x4[2]=coeff_cost_4x4[3] = 0; // dongjie //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { abt_size_flag=1; } //WJP END if(abt_size_flag==0||!input.ABT) //qhg for abt { for (b4=0; b4<4; b4++) { Transform_B4(b8, b4); // LX 0409 for( i = 0; i < BLOCK_SIZE; i++) for( j = 0; j < BLOCK_SIZE; j++) // block_x = 0 4 8 12 g_nbestDCTcoef[ b8*4 + i ][ b8*4 + j ]= MbHeader.pred_residual[b8][b4][j][i]; // LX 0409 Quant_B4(pgMbData->qp_mb, b8, b4, &coeff_cost); } // dongjie if(pgMbHeader->cbp_4x4[b8]==0) pgMbHeader->cbp &= (~(1< cbp |= (1< qp_mb, b8, &coeff_cost); } if(coeff_cost <= (b8<4 ? LUMACOEFFCOST:CHROMACOEFFCOST)) { pgMbHeader->cbp &= (63 - (1< pred_residual[b8][b4][j][i] = 0; } // dongjie else { for(b4=0;b4<4;b4++) { if(coeff_cost_4x4[b4] <= LUMACOEFFCOST4x4) { pgMbHeader->cbp_4x4[b8] &= (15 - (1< pred_residual[b8][b4][j][i] = 0; } } } // end if(abt_size_flag==0||!input.ABT) //qhg for abt { for (b4=0; b4<4; b4++) { Dequant_B4(pgMbData->qp_mb, b8, b4); Inv_Transform_B4(b8, b4); } } else { abt_dequant_B8(pgMbData->qp_mb,b8); abt_Itransform_B8(b8); } //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { abt_size_flag=0; } //WJP END } for(b8=4; b8<6; b8++) { coeff_cost = 0; for(b4=0; b4<4; b4++) Transform_B4(b8, b4); //TranformChromaDC(b8); for(b4=0; b4<4; b4++) Quant_B4(pgMbData->qp_mb, b8, b4, &coeff_cost); // dongjie if(pgMbHeader->cbp_4x4[b8]==0) pgMbHeader->cbp &= (~(1< cbp |= (1< cbp &= (63 - (1< pred_residual[b8][b4][j][i] = 0; } // dongjie else { for(b4=0;b4<4;b4++) { if(coeff_cost_4x4[b4] <= CHROMACOEFFCOST4x4) { pgMbHeader->cbp_4x4[b8] &= (15 - (1< pred_residual[b8][b4][j][i] = 0; } } } // end for(b4=0; b4<4; b4++) Dequant_B4(pgMbData->qp_mb, b8, b4); //InvTransformChromaDC(b8); for (b4=0; b4<4; b4++) Inv_Transform_B4(b8, b4); } for (b8=0; b8<6; b8++) { for (b4=0; b4<4; b4++) { //Inv_Transform_B4(b8, b4); Recon_B4(b8, b4, 1); if(b8<4) { for(j=0; j<4; j++) for(i=0; i<4; i++) { imgY[(pgMbData->mb_y<<4) + (b8/2)*8+(b4/2)*4+j][(pgMbData->mb_x<<4) + (b8%2)*8+(b4%2)*4+i] = imgY1[j][i]; } } else { for(j=0; j<4; j++) for(i=0; i<4; i++) { imgUV[b8-4][(pgMbData->mb_y<<3) + (b4/2)*4+j][(pgMbData->mb_x<<3) +(b4%2)*4+ i] = imgUV1[b8-4][j][i]; } } } } pgMbHeader->abt_block_size_flag=abt_size_flag; Save_RD_State(); old_skip_counter = pgImage->cod_counter; rdcost = RD_Cost_Macrobock(); pgImage->cod_counter = old_skip_counter; Restore_RD_State(); if(rdcost < min_cost) { best_mode = blocktype; min_cost = (int) rdcost; best_abt_size=abt_size_flag; } if(input.ABT && input.ABT_RDO)//WJP 040824N blocktype=blocktype-abt_size_flag; //qhg for abt } pgMbHeader->mb_type = I4MB; pgMbHeader->cbp = 0;//WJP 040824 // dongjie for(i=0;i<6;i++) pgMbHeader->cbp_4x4[i] = 0; // end Intra_Luma_Prediction(&dummy); Intra_Chroma_Prediction(&dummy); Save_RD_State(); intra_rdcost = (int)(4.0*floor(6.0 * pgMbData->lamda_mode + 0.4999)); old_skip_counter = pgImage->cod_counter; intra_rdcost += RD_Cost_Macrobock(); pgImage->cod_counter = old_skip_counter; Restore_RD_State(); Get_Skip_RD_Cost_MB(); //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] == 1 ) { if (iIntegerPixFlag == 0 || iSubPixFlag1 == 1) { pgMbData->skip_cost = 1 << 30; min_cost = 1 << 30; } } if(typemap[0][0][0][0]==0) { pgMbData->skip_cost = 1 << 30; } if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] == 2) { pgMbData->skip_cost = 1 << 30; min_cost = 1 << 30; } }//if (input->IREGEnable) #endif // _ISOLATED_REGION_ if(pgMbData->skip_cost skip_cost mb_type = 0; //--- Update Intra line buffer --- for (b8=0;b8<4;b8++) for (b4=0;b4<4;b4++) { pic_block_x=(img_x/4 + 2*(b8%2)+(b4%2)); pic_block_y=(img_y/4 + 2*(b8/2)+(b4/2)); ipredmode[pic_block_x+1][pic_block_y+1] = (active_pps->constrained_intra_pred_flag ? -1:10);//MZ /* if(active_pps->constrained_intra_pred_flag) c_ipredmode[img_x/16 +1][img_y/16+1] = -1;//zhangnan else c_ipredmode[img_x/16 +1][img_y/16+1] = 0; //MZ 04-03-05 */ } write_one_macroblock(); return 0; } else if(intra_rdcost>min_cost) { Restore_Motion_Vector(best_mode); pgMbData->best_mode = best_mode; pgMbHeader->abt_block_size_flag=best_abt_size; //qhg for abt //restore reference index for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { refFrArr[pgImage->block_y+((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)] = sInter_Ref[best_mode][b8][b4]; } return 1; } else//INTRA-coded { pgMbHeader->mb_type = I4MB; pgMbHeader->cbp = 0;//WJP 040824 // dongjie for(i=0;i<6;i++) pgMbHeader->cbp_4x4[i] = 0; // end Intra_Luma_Prediction(&dummy); Intra_Chroma_Prediction(&dummy); pgMbData->left_ref = -1; for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) { tmp_mv[0][pgMbData->mb_y*4+j][pgMbData->mb_x*4+i+4] = 0; tmp_mv[1][pgMbData->mb_y*4+j][pgMbData->mb_x*4+i+4] = 0; refFrArr [pgMbData->mb_y*4+j][pgMbData->mb_x*4+i ] = -1; } write_one_macroblock(); #ifdef _ISOLATED_REGION_ if(input.IREGEnable) { intrambcount++; } #endif return 0; } } /* ************************************************************************* * Function:Calculate SA(T)D * Input: * Output: * Return: * Attention: ************************************************************************* */ int SATD (int* diff) { int k, satd = 0, m[16], dd, *d=diff; /*===== hadamard transform =====*/ m[ 0] = d[ 0] + d[12]; m[ 4] = d[ 4] + d[ 8]; m[ 8] = d[ 4] - d[ 8]; m[12] = d[ 0] - d[12]; m[ 1] = d[ 1] + d[13]; m[ 5] = d[ 5] + d[ 9]; m[ 9] = d[ 5] - d[ 9]; m[13] = d[ 1] - d[13]; m[ 2] = d[ 2] + d[14]; m[ 6] = d[ 6] + d[10]; m[10] = d[ 6] - d[10]; m[14] = d[ 2] - d[14]; m[ 3] = d[ 3] + d[15]; m[ 7] = d[ 7] + d[11]; m[11] = d[ 7] - d[11]; m[15] = d[ 3] - d[15]; d[ 0] = m[ 0] + m[ 4]; d[ 8] = m[ 0] - m[ 4]; d[ 4] = m[ 8] + m[12]; d[12] = m[12] - m[ 8]; d[ 1] = m[ 1] + m[ 5]; d[ 9] = m[ 1] - m[ 5]; d[ 5] = m[ 9] + m[13]; d[13] = m[13] - m[ 9]; d[ 2] = m[ 2] + m[ 6]; d[10] = m[ 2] - m[ 6]; d[ 6] = m[10] + m[14]; d[14] = m[14] - m[10]; d[ 3] = m[ 3] + m[ 7]; d[11] = m[ 3] - m[ 7]; d[ 7] = m[11] + m[15]; d[15] = m[15] - m[11]; m[ 0] = d[ 0] + d[ 3]; m[ 1] = d[ 1] + d[ 2]; m[ 2] = d[ 1] - d[ 2]; m[ 3] = d[ 0] - d[ 3]; m[ 4] = d[ 4] + d[ 7]; m[ 5] = d[ 5] + d[ 6]; m[ 6] = d[ 5] - d[ 6]; m[ 7] = d[ 4] - d[ 7]; m[ 8] = d[ 8] + d[11]; m[ 9] = d[ 9] + d[10]; m[10] = d[ 9] - d[10]; m[11] = d[ 8] - d[11]; m[12] = d[12] + d[15]; m[13] = d[13] + d[14]; m[14] = d[13] - d[14]; m[15] = d[12] - d[15]; d[ 0] = m[ 0] + m[ 1]; d[ 1] = m[ 0] - m[ 1]; d[ 2] = m[ 2] + m[ 3]; d[ 3] = m[ 3] - m[ 2]; d[ 4] = m[ 4] + m[ 5]; d[ 5] = m[ 4] - m[ 5]; d[ 6] = m[ 6] + m[ 7]; d[ 7] = m[ 7] - m[ 6]; d[ 8] = m[ 8] + m[ 9]; d[ 9] = m[ 8] - m[ 9]; d[10] = m[10] + m[11]; d[11] = m[11] - m[10]; d[12] = m[12] + m[13]; d[13] = m[12] - m[13]; d[14] = m[14] + m[15]; d[15] = m[15] - m[14]; /*===== sum up =====*/ for (dd=diff[k=0]; k<16; dd=diff[++k]) { satd += (dd < 0 ? -dd : dd); } satd >>= 1; return satd; }