📄 rdopt.c
字号:
if (!copy)
{
/*==================================================*
*===== GET RATE OF CHROMA AND UPDATE COST =====*
*==================================================*/
rd->rate_chroma = writeMB_bits_for_DC_chroma (0);
rd->rate_chroma += writeMB_bits_for_AC_chroma (0);
//=== update and check rate-distortion cost ===
rd->rdcost += rdopt->lambda_mode * (double)rd->rate_chroma;
if (rd->rdcost >= rdopt->min_rdcost)
{
restore_coding_state ();
return 0;
}
}
//=== restore encoding environment ===
restore_coding_state ();
/*=================================================*
*===== =====*
*===== STORE PARAMETERS OF NEW BEST MODE =====*
*===== =====*
*=================================================*/
rdopt->min_rdcost = rd->rdcost;
rdopt->best_mode = mode;
rdopt->ref_or_i16mode = ref_or_i16mode;
rdopt->blocktype = blocktype;
rdopt->blocktype_back = blocktype_back;
//=== LUMINANCE OF RECONSTRUCTED MACROBLOCK ===
if (copy)
for (j=0; j<MB_BLOCK_SIZE; j++)
for (i=0; i<MB_BLOCK_SIZE; i++)
rdopt->rec_mb_Y[j][i] = FastPelY_14(mref[refidx], (img->pix_y+j)<<2, (img->pix_x+i)<<2);
else
for (j=0; j<MB_BLOCK_SIZE; j++)
for (i=0; i<MB_BLOCK_SIZE; i++)
rdopt->rec_mb_Y[j][i] = imgY[img->pix_y+j][img->pix_x+i];
//=== CHROMINANCE OF RECONSTRUCTED MACROBLOCK ===
if (copy)
for (j=0; j<(BLOCK_SIZE<<1); j++)
for (i=0; i<(BLOCK_SIZE<<1); i++)
{
rdopt->rec_mb_U[j][i] = mcef[refidx][0][img->pix_c_y+j][img->pix_c_x+i];
rdopt->rec_mb_V[j][i] = mcef[refidx][1][img->pix_c_y+j][img->pix_c_x+i];
}
else
for (j=0; j<(BLOCK_SIZE<<1); j++)
for (i=0; i<(BLOCK_SIZE<<1); i++)
{
rdopt->rec_mb_U[j][i] = imgUV[0][img->pix_c_y+j][img->pix_c_x+i];
rdopt->rec_mb_V[j][i] = imgUV[1][img->pix_c_y+j][img->pix_c_x+i];
}
//=== CBP, KAC, DCT-COEFFICIENTS ===
if (!copy)
{
rdopt->cbp = currMB->cbp;
rdopt->cbp_blk = currMB->cbp_blk;
rdopt->kac = img->kac;
memcpy (rdopt->cof, img->cof, 1728*sizeof(int));
memcpy (rdopt->cofu, img->cofu, 20*sizeof(int));
}
else
rdopt->cbp_blk = 0 ;
//=== INTRA PREDICTION MODES ===
if (intra4)
{
memcpy (rdopt->ipredmode, currMB->intra_pred_modes, 16*sizeof(int));
}
//=== MOTION VECTORS ===
if (inter)
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
rdopt-> mv[j][i][0] = tmp_mv [0][img->block_y+j][img->block_x+4+i];
rdopt-> mv[j][i][1] = tmp_mv [1][img->block_y+j][img->block_x+4+i];
}
else if (inter_for)
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
rdopt-> mv[j][i][0] = tmp_fwMV[0][img->block_y+j][img->block_x+4+i];
rdopt-> mv[j][i][1] = tmp_fwMV[1][img->block_y+j][img->block_x+4+i];
}
else if (inter_back)
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
rdopt->bw_mv[j][i][0] = tmp_bwMV[0][img->block_y+j][img->block_x+4+i];
rdopt->bw_mv[j][i][1] = tmp_bwMV[1][img->block_y+j][img->block_x+4+i];
}
else if (inter_bidir)
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
rdopt-> mv[j][i][0] = tmp_fwMV[0][img->block_y+j][img->block_x+4+i];
rdopt-> mv[j][i][1] = tmp_fwMV[1][img->block_y+j][img->block_x+4+i];
rdopt->bw_mv[j][i][0] = tmp_bwMV[0][img->block_y+j][img->block_x+4+i];
rdopt->bw_mv[j][i][1] = tmp_bwMV[1][img->block_y+j][img->block_x+4+i];
}
if (input->rdopt==2)
{
int k;
for (k=0; k<input->NoOfDecoders; k++)
{
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++)
{
/* Keep the decoded values of each MB for updating the ref frames*/
decY_best[k][j][i] = decY[k][j][i];
}
}
}
return 1; // new best mode
}
#define PFRAME 0
#define B_FORWARD 1
#define B_BACKWARD 2
/*!
************************************************************************
* \brief
* Rate-Distortion optimized mode decision
************************************************************************
*/
void
RD_Mode_Decision ()
{
int i, j, k, k0 = 0, dummy;
int mode, intra16mode, refframe, blocktype, blocktype_back;
int valid_mode [NO_MAX_MBMODES], valid_intra16mode[4];
int bframe, intra_macroblock, any_inter_mode = 0;
int tot_inter_sad, min_inter_sad;
int backward_me_done[9];
double forward_rdcost[9], backward_rdcost[9];
double min_rdcost;
int max_ref_frame, best_refframe[9];
RateDistortion rd;
int k1 = 1;
int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
/*==============================================*
*=== INIT PARAMETERS OF RD-OPT. STRUCTURE ===*
*==============================================*/
//--- set lagrange parameters ---
double qp = (double)img->qp;
rdopt->lambda_mode = 5.0 * exp (0.1 * qp) * (qp + 5.0) / (34.0 - qp);
if (img->type == B_IMG || img->types == SP_IMG)
rdopt->lambda_mode *= 4;
rdopt->lambda_motion = sqrt (rdopt->lambda_mode);
rdopt->lambda_intra = rdopt->lambda_mode;
if (input->rdopt == 2)
{
rdopt->lambda_mode=(1.0-input->LossRateA/100.0)*rdopt->lambda_mode;
rdopt->lambda_motion = sqrt (1.0-input->LossRateA/100.0) * rdopt->lambda_motion;
}
//--- cost values ---
rdopt->best_mode = -1;
rdopt->min_rdcost = 1e30;
for (i = 0; i < 9; i++)
{
forward_rdcost [i] = backward_rdcost [i] = -1.0;
backward_me_done[i] = 0;
for (j = 0; j < img->buf_cycle; j++)
{
forward_me_done[i][j] = 0;
}
}
/*========================*
*=== SET SOME FLAGS ===*
*========================*/
bframe = (img->type==B_IMG);
intra_macroblock = (img->mb_y==img->mb_y_upd && img->mb_y_upd!=img->mb_y_intra) || img->type==INTRA_IMG;
max_ref_frame = min (img->number, img->buf_cycle);
/*========================================*
*=== MARK POSSIBLE MACROBLOCK MODES ===*
*========================================*/
//--- reset arrays ---
memset (valid_mode, 0, sizeof(int)*NO_MAX_MBMODES);
memset (valid_intra16mode, 0, sizeof(int)*4);
//--- set intra modes ---
valid_mode [MBMODE_INTRA4x4 ] = 1;
valid_mode [MBMODE_INTRA16x16] = 1;
//--- set inter modes ---
if (!intra_macroblock || bframe)
{
for (i=MBMODE_INTER16x16; i <= MBMODE_INTER4x4; i++)
if (input->blc_size [i][0] > 0)
any_inter_mode = valid_mode [i] = 1;
if (bframe)
{
memcpy (valid_mode+MBMODE_BACKWARD16x16,
valid_mode+MBMODE_INTER16x16, NO_INTER_MBMODES*sizeof(int));
valid_mode[MBMODE_BIDIRECTIONAL] = valid_mode[MBMODE_DIRECT] = any_inter_mode;
}
else
{
valid_mode[MBMODE_COPY] = valid_mode[MBMODE_INTER16x16];
}
}
if (img->type==INTER_IMG && img->types== SP_IMG)
valid_mode[MBMODE_COPY] =0;
//===== LOOP OVER ALL MACROBLOCK MODES =====
for (mode = 0; mode < NO_MAX_MBMODES; mode++)
if (valid_mode[mode])
{
/*==================================================================*
*=== MOTION ESTIMATION, INTRA PREDICTION and COST CALCULATION ===*
*==================================================================*/
if (mode == MBMODE_INTRA4x4)
{
/*======================*
*=== INTRA 4x4 MODE ===*
*======================*/
currMB->intraOrInter = INTRA_MB_4x4;
img->imod = INTRA_MB_OLD;
Intra4x4_Mode_Decision (); // intra 4x4 prediction, dct, etc.
RDCost_Macroblock (&rd, mode, 0, 0, 0);
}
else if (mode == MBMODE_INTRA16x16)
{
/*========================*
*=== INTRA 16x16 MODE ===*
*========================*/
currMB->intraOrInter = INTRA_MB_16x16;
img->imod = INTRA_MB_NEW;
intrapred_luma_2 (); // make intra pred for all 4 new modes
find_sad2 (&k); // get best new intra mode
RDCost_Macroblock (&rd, mode, k, 0, 0);
}
else if (mode == MBMODE_COPY)
{
/*=======================*
*=== COPY MACROBLOCK ===*
*=======================*/
currMB->intraOrInter = INTER_MB;
img->imod = INTRA_MB_INTER;
RDCost_Macroblock (&rd, mode, 0, 0, 0);
}
else if (!bframe && (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4))
{
/*===================================*
*=== INTER MACROBLOCK in P-FRAME ===*
*===================================*/
currMB->intraOrInter = INTER_MB;
img->imod = INTRA_MB_INTER;
min_inter_sad = MAX_VALUE;
for (k=0; k<max_ref_frame; k++)
#ifdef _ADDITIONAL_REFERENCE_FRAME_
if (k < input->no_multpred ||
k == input->add_ref_frame)
#endif
{
tot_inter_sad = (int)floor(rdopt->lambda_motion * (1+2*floor(log(k+1)/log(2)+1e-10)));
tot_inter_sad += SingleUnifiedMotionSearch (k, mode,
refFrArr, tmp_mv, img->mv, PFRAME, img->all_mv,
rdopt->lambda_motion);
if (tot_inter_sad < min_inter_sad)
{
k0 = k;
min_inter_sad = tot_inter_sad;
}
}
for ( i=0; i < 4; i++)
for (j=0; j < 4; j++)
{
tmp_mv[0][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][0];
tmp_mv[1][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][1];
}
RDCost_Macroblock (&rd, mode, k0, mode, 0);
}
else if (bframe && (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4))
{
/*===============================================*
*=== FORWARD PREDICTED MACROBLOCK in B-FRAME ===*
*===============================================*/
if (forward_rdcost[mode] < 0.0)
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Forward;
min_inter_sad = MAX_VALUE;
for (k=0; k<max_ref_frame; k++)
#ifdef _ADDITIONAL_REFERENCE_FRAME_
if (k < input->no_multpred ||
k == input->add_ref_frame)
#endif
{
if (!forward_me_done[mode][k])
{
tot_for_sad[mode][k] = (int)floor(rdopt->lambda_motion * (1+2*floor(log(k+1)/log(2)+1e-10)));
tot_for_sad[mode][k] += SingleUnifiedMotionSearch (k, mode,
fw_refFrArr, tmp_fwMV, img->p_fwMV,
B_FORWARD, img->all_mv,
rdopt->lambda_motion);
forward_me_done[mode][k] = 1;
}
if (tot_for_sad[mode][k] < min_inter_sad)
{
k0 = k;
min_inter_sad = tot_for_sad[mode][k];
}
}
for ( i=0; i < 4; i++)
for (j=0; j < 4; j++)
{
tmp_fwMV[0][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][0];
tmp_fwMV[1][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][k0][mode][1];
}
RDCost_Macroblock (&rd, mode, k0, mode, 0);
forward_rdcost[mode] = rd.rdcost;
best_refframe [mode] = k0;
}
}
else if (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4)
{
/*================================================*
*=== BACKWARD PREDICTED MACROBLOCK in B-FRAME ===*
*================================================*/
if (backward_rdcost [mode-NO_INTER_MBMODES] < 0.0)
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Backward;
if (!backward_me_done[mode-NO_INTER_MBMODES])
{
SingleUnifiedMotionSearch (0, mode-NO_INTER_MBMODES,
bw_refFrArr, tmp_bwMV, img->p_bwMV, B_BACKWARD, img->all_bmv,
rdopt->lambda_motion);
backward_me_done[mode-NO_INTER_MBMODES]=1;
}
else
for (j = 0; j < 4; j++)
for (i = 0; i < 4; i++)
{
tmp_bwMV[0][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][mode-NO_INTER_MBMODES][0];
tmp_bwMV[1][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][mode-NO_INTER_MBMODES][1];
}
RDCost_Macroblock (&rd, mode, 0, 0, mode-NO_INTER_MBMODES);
backward_rdcost[mode-NO_INTER_MBMODES] = rd.rdcost;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -