📄 rdopt.c
字号:
for (j=0; j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
{
img->mpr[i+block_x][j+block_y]=img->mprr[best_ipmode][j][i];
img->m7[i][j] =imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mprr[best_ipmode][j][i];
}
nonzero = dct_luma(block_x,block_y,&coeff_cost);
if (nonzero)
{
currMB->cbp |= cbp_mask;// set coded block pattern if there are nonzero coeffs
}
}
}
}
/*!
************************************************************************
* \brief
* Rate-Distortion cost of a macroblock
************************************************************************
* \note
* the following parameters have to be set before using this function: \n
* ------------------------------------------------------------------- \n
* for INTRA4x4 : img->imod,
* img->cof,
* currMB->cbp,
* currMB->intra_pred_modes,
* currMB->intraOrInter
* \n
* for INTRA16x16: img->imod,
* img->mprr_2
* currMB->intraOrInter
* \n
* for INTER : img->imod,
* img->mv, (predictors)
* tmp_mv, (motion vectors)
* currMB->intraOrInter
* \n
* for FORWARD : img->imod,
* img->p_fwMV,
* tmp_fwMV,
* currMB->intraOrInter
* \n
* for BACKWARD : img->imod,
* img->p_bwMV,
* tmp_bwMV,
* currMB->intraOrInter
* \n
* for BIDIRECT : img->imod,
* img->p_fwMV,
* img->p_bwMV,
* tmp_fwMV,
* tmp_bwMV,
* currMB->intraOrInter
* \n
* for DIRECT : img->imod,
* dfMV,
* dbMV,
* currMB->intraOrInter
* \n
* for COPY : currMB->intraOrInter
*
************************************************************************
*/
int
RDCost_Macroblock (RateDistortion *rd,
int mode,
int ref_or_i16mode,
int blocktype,
int blocktype_back)
{
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;
int i, j, refidx=0, cr_cbp, mb_mode;
int bframe = (img->type == B_IMG);
int copy = (mode == MBMODE_COPY);
int intra4 = (mode == MBMODE_INTRA4x4);
int intra16 = (mode == MBMODE_INTRA16x16);
int inter = (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4 && !bframe);
int inter_for = (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4 && bframe);
int inter_back = (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4);
int inter_bidir = (mode == MBMODE_BIDIRECTIONAL);
int inter_direct = (mode == MBMODE_DIRECT);
int inter_bframe = (inter_for || inter_back || inter_bidir || inter_direct);
//=== init rd-values ===
rd->rdcost = 0.0;
rd->distortion = 0;
rd->distortion_UV = 0;
rd->rate_mode = 0;
rd->rate_motion = 0;
rd->rate_cbp = 0;
rd->rate_luma = 0;
rd->rate_chroma = 0;
/*======================================================*
*===== =====*
*===== DCT, QUANT, DEQUANT, IDCT OF LUMINANCE =====*
*===== =====*
*======================================================*/
/*
* note: - for intra4x4, dct have to be done already
* - for copy_mb, no dct coefficients are needed
*/
if (intra16)
{
//===== INTRA 16x16 MACROBLOCK =====
dct_luma2 (ref_or_i16mode);
currMB->cbp = 0;
}
else if (inter)
{
//===== INTER MACROBLOCK =====
img->multframe_no = ref_or_i16mode+1;
LumaResidualCoding_P ();
}
else if (inter_bframe)
{
//===== INTER MACROBLOCK in B-FRAME =====
img->fw_multframe_no = ref_or_i16mode+1;
LumaResidualCoding_B ();
}
// We need the reconstructed prediction residue for the simulated decoders.
if (input->rdopt==2 && !bframe)
compute_residue(mode);
/*==============================================================*
*===== PREDICTION, DCT, QUANT, DEQUANT OF CHROMINANCE =====*
*==============================================================*/
if (!copy)
{
if (bframe) ChromaCoding_B (&cr_cbp);
else ChromaCoding_P (&cr_cbp);
}
/*=========================================================*
*===== =====*
*===== GET DISTORTION OF LUMINANCE AND INIT COST =====*
*===== =====*
*=========================================================*/
if (input->rdopt==2)
{
int k;
for (k=0; k < input->NoOfDecoders ;k++)
{
decode_one_macroblock(k, mode, ref_or_i16mode);
for (j=img->pix_y; j<img->pix_y+MB_BLOCK_SIZE; j++)
for (i=img->pix_x; i<img->pix_x+MB_BLOCK_SIZE; i++)
{
rd->distortion += img->quad[abs (imgY_org[j][i] - decY[k][j][i])];
}
}
rd->distortion /= input->NoOfDecoders;
refidx = 1; /* reference frame index */
}
else
{
if (copy)
{
refidx = 1; // reference frame index
for (j=img->pix_y; j<img->pix_y+MB_BLOCK_SIZE; j++)
for (i=img->pix_x; i<img->pix_x+MB_BLOCK_SIZE; i++)
rd->distortion += img->quad [abs (imgY_org[j][i] - FastPelY_14(mref[refidx], j<<2, i<<2))];
}
else
{
for (j=img->pix_y; j<img->pix_y+MB_BLOCK_SIZE; j++)
for (i=img->pix_x; i<img->pix_x+MB_BLOCK_SIZE; i++)
rd->distortion += img->quad [abs (imgY_org[j][i] - imgY[j][i])];
}
}
//=== init and check rate-distortion cost ===
rd->rdcost = (double)rd->distortion;
if (rd->rdcost >= rdopt->min_rdcost)
return 0;
/*=============================================================*
*===== =====*
*===== GET DISTORTION OF CHROMINANCE AND UPDATE COST =====*
*===== =====*
*=============================================================*/
if (copy)
{
for (j=img->pix_c_y; j<img->pix_c_y+MB_BLOCK_SIZE/2; j++)
for (i=img->pix_c_x; i<img->pix_c_x+MB_BLOCK_SIZE/2; i++)
{
rd->distortion_UV += img->quad[abs (imgUV_org[0][j][i] - mcef[refidx][0][j][i])];
rd->distortion_UV += img->quad[abs (imgUV_org[1][j][i] - mcef[refidx][1][j][i])];
}
}
else
{
for (j=img->pix_c_y; j<img->pix_c_y+MB_BLOCK_SIZE/2; j++)
for (i=img->pix_c_x; i<img->pix_c_x+MB_BLOCK_SIZE/2; i++)
{
rd->distortion_UV += img->quad[abs (imgUV_org[0][j][i] - imgUV[0][j][i])];
rd->distortion_UV += img->quad[abs (imgUV_org[1][j][i] - imgUV[1][j][i])];
}
}
//=== init and check rate-distortion cost ===
rd->rdcost += (double)rd->distortion_UV;
if (rd->rdcost >= rdopt->min_rdcost)
return 0;
/*================================================*
*===== =====*
*===== GET CODING RATES AND UPDATE COST =====*
*===== =====*
*================================================*/
//=== store encoding environment ===
store_coding_state ();
/*===================================================*
*===== GET RATE OF MB-MODE AND UPDATE COST =====*
*===================================================*/
//--- set mode constants ---
if (copy || inter_direct) mb_mode = 0;
else if (inter) mb_mode = blocktype;
else if (intra4) mb_mode = (img->type<<3);
else if (intra16) mb_mode = (img->type<<3) + (cr_cbp<<2) + 12*img->kac + 1 + ref_or_i16mode;
else if (inter_bidir) mb_mode = 3;
else if (inter_for) mb_mode = (blocktype ==1 ? blocktype : (blocktype <<1));
else /* inter_back */ mb_mode = (blocktype_back==1 ? blocktype_back+1 : (blocktype_back<<1)+1);
currSE->value1 = mb_mode;
//--- set symbol type and function pointers ---
if (input->symbol_mode == UVLC) currSE->mapping = n_linfo2;
else currSE->writing = writeMB_typeInfo2Buffer_CABAC;
currSE->type = SE_MBTYPE;
//--- choose data partition ---
if (bframe) dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
else dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
//--- encode and set rate ---
dataPart->writeSyntaxElement (currSE, dataPart);
rd->rate_mode = currSE->len;
currSE++;
currMB->currSEnr++;
//=== encode intra prediction modes ===
if (intra4)
for (i=0; i < (MB_BLOCK_SIZE>>1); i++)
{
currSE->value1 = currMB->intra_pred_modes[ i<<1 ];
currSE->value2 = currMB->intra_pred_modes[(i<<1)+1];
//--- set symbol type and function pointers ---
if (input->symbol_mode == UVLC) currSE->mapping = intrapred_linfo;
else currSE->writing = writeIntraPredMode2Buffer_CABAC;
currSE->type = SE_INTRAPREDMODE;
//--- choose data partition ---
if (bframe) dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
else dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
//--- encode and update rate ---
dataPart->writeSyntaxElement (currSE, dataPart);
rd->rate_mode += currSE->len;
currSE++;
currMB->currSEnr++;
}
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_mode;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
/*=======================================================*
*===== GET RATE OF MOTION INFO AND UPDATE COST =====*
*=======================================================*/
if (inter)
{
//=== set some parameters ===
currMB->ref_frame = ref_or_i16mode;
currMB->mb_type = mb_mode;
img->mb_mode = mb_mode;
img->blc_size_h = input->blc_size[blocktype][0];
img->blc_size_v = input->blc_size[blocktype][1];
//=== get rate ===
rd->rate_motion = writeMotionInfo2NAL_Pframe ();
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_motion;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
}
else if (inter_bframe && !inter_direct)
{
//=== set some parameters ===
currMB->ref_frame = ref_or_i16mode;
currMB->mb_type = mb_mode;
img->mb_mode = mb_mode;
img->fw_blc_size_h = input->blc_size[blocktype ][0];
img->fw_blc_size_v = input->blc_size[blocktype ][1];
img->bw_blc_size_h = input->blc_size[blocktype_back][0];
img->bw_blc_size_v = input->blc_size[blocktype_back][1];
//=== get rate ===
rd->rate_motion = writeMotionInfo2NAL_Bframe ();
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_motion;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
}
//===== GET RATE FOR CBP, LUMA and CHROMA =====
if (intra16)
{
/*========================================================*
*===== GET RATE OF LUMA (16x16) AND UPDATE COST =====*
*========================================================*/
rd->rate_luma = writeMB_bits_for_16x16_luma ();
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_luma;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
}
else if (!copy)
{
/*===============================================*
*===== GET RATE OF CBP AND UPDATE COST =====*
*===============================================*/
rd->rate_cbp = writeMB_bits_for_CBP ();
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_cbp;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
/*=========================================================*
*===== GET RATE OF LUMA (16x(4x4)) AND UPDATE COST =====*
*=========================================================*/
rd->rate_luma = writeMB_bits_for_luma (0);
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_luma;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -