📄 mode_decision.c
字号:
}
else
{
enc_mb->lambda_md = img->lambda_md[img->type][img->qp];
enc_mb->lambda_me = img->lambda_me[img->type][img->qp];
enc_mb->lambda_mf = img->lambda_mf[img->type][img->qp];
}
#endif
// Initialize bipredME decisions
for (mode=0; mode<MAXMODE; mode++)
{
img->bi_pred_me[mode]=0;
}
#ifdef ADAPTIVE_QUANTIZATION
CalculateLambdaForMatrix(enc_mb);
#endif
if (!img->MbaffFrameFlag)
{
for (l = LIST_0; l < BI_PRED; l++)
{
for(k = 0; k < listXsize[l]; k++)
{
listX[l][k]->chroma_vector_adjustment= 0;
if(img->structure == TOP_FIELD && img->structure != listX[l][k]->structure)
listX[l][k]->chroma_vector_adjustment = -2;
if(img->structure == BOTTOM_FIELD && img->structure != listX[l][k]->structure)
listX[l][k]->chroma_vector_adjustment = 2;
}
}
}
else
{
if (enc_mb->curr_mb_field)
{
for (l = enc_mb->list_offset[LIST_0]; l <= enc_mb->list_offset[LIST_1]; l++)
{
for(k = 0; k < listXsize[l]; k++)
{
listX[l][k]->chroma_vector_adjustment= 0;
if(img->current_mb_nr % 2 == 0 && listX[l][k]->structure == BOTTOM_FIELD)
listX[l][k]->chroma_vector_adjustment = -2;
if(img->current_mb_nr % 2 == 1 && listX[l][k]->structure == TOP_FIELD)
listX[l][k]->chroma_vector_adjustment = 2;
}
}
}
else
{
for (l = enc_mb->list_offset[LIST_0]; l <= enc_mb->list_offset[LIST_1]; l++)
{
for(k = 0; k < listXsize[l]; k++)
listX[l][k]->chroma_vector_adjustment= 0;
}
}
}
}
/*!
*************************************************************************************
* \brief
* computation of prediction list (including biprediction) cost
*************************************************************************************
*/
void list_prediction_cost(int list, int block, int mode, RD_PARAMS enc_mb, int bmcost[5], char best_ref[2])
{
short ref;
int mcost;
int cur_list = list < BI_PRED ? enc_mb.list_offset[list] : enc_mb.list_offset[LIST_0];
//--- get cost and reference frame for forward prediction ---
if (list < BI_PRED)
{
for (ref=0; ref < listXsize[cur_list]; ref++)
{
if (!img->checkref || list || ref==0 || CheckReliabilityOfRef (block, list, ref, mode))
{
// limit the number of reference frames to 1 when switching SP frames are used
if((!input->sp2_frame_indicator && !input->sp_output_indicator)||
((input->sp2_frame_indicator || input->sp_output_indicator) && (img->type!=P_SLICE && img->type!=SP_SLICE))||
((input->sp2_frame_indicator || input->sp_output_indicator) && ((img->type==P_SLICE || img->type==SP_SLICE) &&(ref==0))))
{
mcost = (input->rdopt
? REF_COST (enc_mb.lambda_mf, ref, cur_list)
: (int) (2 * enc_mb.lambda_me * min(ref, 1)));
mcost += motion_cost[mode][list][ref][block];
if (mcost < bmcost[list])
{
bmcost[list] = mcost;
best_ref[list] = (char)ref;
}
}
}
}
}
else if (list == BI_PRED)
{
bmcost[list] = (input->rdopt
? (REF_COST (enc_mb.lambda_mf, (short)best_ref[LIST_0], cur_list)
+ REF_COST (enc_mb.lambda_mf, (short)best_ref[LIST_1], cur_list + LIST_1))
: (int) (2 * (enc_mb.lambda_me * (min((short)best_ref[LIST_0], 1) + min((short)best_ref[LIST_1], 1)))));
bmcost[list] += BIDPartitionCost (mode, block, (short)best_ref[LIST_0], (short)best_ref[LIST_1], enc_mb.lambda_mf);
}
else
{
bmcost[list] = (input->rdopt
? (REF_COST (enc_mb.lambda_mf, 0, cur_list)
+ REF_COST (enc_mb.lambda_mf, 0, cur_list + LIST_1))
: (int) (4 * enc_mb.lambda_me));
bmcost[list] += BPredPartitionCost(mode, block, 0, 0, enc_mb.lambda_mf, !(list&1));
}
}
int compute_ref_cost(RD_PARAMS enc_mb, int ref, int list)
{
return WEIGHTED_COST(enc_mb.lambda_mf,((listXsize[enc_mb.list_offset[list]] <= 1)? 0:refbits[ref]));
}
/*!
*************************************************************************************
* \brief
* Determination of prediction list based on simple distortion computation
*************************************************************************************
*/
void determine_prediction_list(int mode, int bmcost[5], char best_ref[2], short *best_pdir, int *cost, short *bi_pred_me)
{
if ((!input->BiPredMotionEstimation) || (mode != 1))
{
//--- get prediction direction ----
if (bmcost[LIST_0] <= bmcost[LIST_1]
&& bmcost[LIST_0] <= bmcost[BI_PRED])
{
*best_pdir = 0;
// if(*cost!=INT_MAX)
*cost += bmcost[LIST_0];
//best_ref[LIST_1] = 0;
}
else if (bmcost[LIST_1] <= bmcost[LIST_0]
&& bmcost[LIST_1] <= bmcost[BI_PRED])
{
*best_pdir = 1;
// if(*cost!=INT_MAX)
*cost += bmcost[LIST_1];
//best_ref[LIST_0] = 0;
}
else
{
*best_pdir = 2;
// if((bmcost[BI_PRED]==INT_MAX) | (*cost==INT_MAX))
// *cost=INT_MAX;
// else
*cost += bmcost[BI_PRED];
//best_ref[LIST_1] = 0;
}
}
else
{
img->bi_pred_me[mode]=0;
*bi_pred_me = 0;
//--- get prediction direction ----
if (bmcost[LIST_0] <= bmcost[LIST_1]
&& bmcost[LIST_0] <= bmcost[BI_PRED]
&& bmcost[LIST_0] <= bmcost[BI_PRED_L0]
&& bmcost[LIST_0] <= bmcost[BI_PRED_L1])
{
*best_pdir = 0;
*cost += bmcost[LIST_0];
//best_ref[LIST_1] = 0;
}
else if (bmcost[LIST_1] <= bmcost[LIST_0]
&& bmcost[LIST_1] <= bmcost[BI_PRED]
&& bmcost[LIST_1] <= bmcost[BI_PRED_L0]
&& bmcost[LIST_1] <= bmcost[BI_PRED_L1])
{
*best_pdir = 1;
*cost += bmcost[LIST_1];
//best_ref[LIST_0] = 0;
}
else if (bmcost[BI_PRED] <= bmcost[LIST_0]
&& bmcost[BI_PRED] <= bmcost[LIST_1]
&& bmcost[BI_PRED] <= bmcost[BI_PRED_L0]
&& bmcost[BI_PRED] <= bmcost[BI_PRED_L1])
{
*best_pdir = 2;
*cost += bmcost[BI_PRED];
//best_ref[LIST_1] = 0;
}
else if (bmcost[BI_PRED_L0] <= bmcost[LIST_0]
&& bmcost[BI_PRED_L0] <= bmcost[LIST_1]
&& bmcost[BI_PRED_L0] <= bmcost[BI_PRED]
&& bmcost[BI_PRED_L0] <= bmcost[BI_PRED_L1])
{
*best_pdir = 2;
*cost += bmcost[BI_PRED_L0];
*bi_pred_me = 1;
img->bi_pred_me[mode]=1;
best_ref[LIST_1] = 0;
best_ref[LIST_0] = 0;
}
else
{
*best_pdir = 2;
*cost += bmcost[BI_PRED_L1];
*bi_pred_me = 2;
best_ref[LIST_1] = 0;
best_ref[LIST_0] = 0;
img->bi_pred_me[mode]=2;
}
}
}
/*!
*************************************************************************************
* \brief
* RD decision process
*************************************************************************************
*/
void compute_mode_RD_cost(int mode,
Macroblock *currMB,
RD_PARAMS enc_mb,
double *min_rdcost,
double *min_rate,
int i16mode,
short bslice,
short *inter_skip)
{
//--- transform size ---
currMB->luma_transform_size_8x8_flag = input->Transform8x8Mode==2
? (mode >= 1 && mode <= 3)
|| (mode == 0 && bslice && active_sps->direct_8x8_inference_flag)
|| ((mode == P8x8) && (enc_mb.valid[4]))
: 0;
//store_coding_state (cs_cm); // RD
SetModesAndRefframeForBlocks (mode);
// Encode with coefficients
img->NoResidueDirect = 0;
if (currMB->c_ipred_mode == DC_PRED_8 || (IS_INTRA(currMB) ))
{
while(1)
{
#ifdef MV_COMPETITION
if ((mode == 0) && (img->type==P_SLICE) && (input->mv_competition > 0))
skip_mode = TRUE;
else
skip_mode = FALSE;
#endif
if (RDCost_for_macroblocks (enc_mb.lambda_md, mode, min_rdcost, min_rate, i16mode))
{
//Rate control
if (input->RCEnable)
{
if(mode == P8x8)
rc_store_diff(img->opix_x,img->opix_y,
currMB->luma_transform_size_8x8_flag == 1 ? tr8x8.mpr8x8 : tr4x4.mpr8x8);
else
rc_store_diff(img->opix_x, img->opix_y, pred);
}
store_macroblock_parameters (mode);
if(input->rdopt==2 && mode == 0 && input->EarlySkipEnable)
{
// check transform quantized coeff.
if(currMB->cbp == 0)
*inter_skip = 1;
}
}
// Go through transform modes.
// Note that if currMB->cbp is 0 one could choose to skip 8x8 mode
// although this could be due to deadzoning decisions.
//if (input->Transform8x8Mode==1 && currMB->cbp!=0)
if (input->Transform8x8Mode==1)
{
//=========== try mb_types 1,2,3 with 8x8 transform ===========
if ((mode >= 1 && mode <= 3) && currMB->luma_transform_size_8x8_flag == 0)
{
//try with 8x8 transform size
currMB->luma_transform_size_8x8_flag = 1;
continue;
}
//=========== try DIRECT-MODE with 8x8 transform ===========
else if (mode == 0 && bslice && active_sps->direct_8x8_inference_flag && currMB->luma_transform_size_8x8_flag == 0)
{
//try with 8x8 transform size
currMB->luma_transform_size_8x8_flag = 1;
continue;
}
//=========== try mb_type P8x8 for mode 4 with 4x4/8x8 transform ===========
else if ((mode == P8x8) && (enc_mb.valid[4]) && (currMB->luma_transform_size_8x8_flag == 0))
{
currMB->luma_transform_size_8x8_flag = 1; //check 8x8 partition for transform size 8x8
continue;
}
else
{
currMB->luma_transform_size_8x8_flag = 0;
break;
}
}
else
break;
}
// Encode with no coefficients. Currently only for direct. This could be extended to all other modes as in example.
//if (mode < P8x8 && (*inter_skip == 0) && enc_mb.valid[mode] && currMB->cbp && (currMB->cbp&15) != 15 && !input->nobskip)
if ( bslice && mode == 0 && (*inter_skip == 0) && enc_mb.valid[mode]
&& currMB->cbp && (currMB->cbp&15) != 15 && !input->nobskip)
{
img->NoResidueDirect = 1;
if (RDCost_for_macroblocks (enc_mb.lambda_md, mode, min_rdcost, min_rate, i16mode))
{
//Rate control
if (input->RCEnable)
rc_store_diff(img->opix_x,img->opix_y,pred);
store_macroblock_parameters (mode);
}
}
}
};
/*!
*************************************************************************************
* \brief
* Mode Decision for an 8x8 sub-macroblock
*************************************************************************************
*/
void submacroblock_mode_decision(RD_PARAMS enc_mb,
RD_8x8DATA *dataTr,
Macroblock *currMB,
int ***cofACtr,
int *have_direct,
short bslice,
int block,
int *cost_direct,
int *cost,
int *cost8x8_direct,
int transform8x8)
{
int j0, i0, j1, i1;
int i,j, k;
int min_cost8x8, index;
double min_rdcost, rdcost = 0.0;
short best_pdir = 0;
char best_ref[2] = {0, -1};
int mode;
int64 curr_cbp_blk;
int direct4x4_tmp, direct8x8_tmp;
int bmcost[5] = {INT_MAX};
int cnt_nonz = 0;
short pdir;
int dummy;
short bi_pred_me;
int best_cnt_nonz = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -