📄 mode_decision.c
字号:
*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;
SetModesAndRefframeForBlocks (mode);
// Encode with coefficients
img->NoResidueDirect = 0;
if (currMB->c_ipred_mode == DC_PRED_8 || (IS_INTRA(currMB) ))
{
while(1)
{
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;
int maxindex = (transform8x8) ? 2 : 5;
int pix_x, pix_y;
int block_x, block_y;
int fadjust[16][16], fadjustCr[2][16][16];
int (*fadjustTransform)[16][16] = transform8x8? img->fadjust8x8 : img->fadjust4x4;
int (*fadjustTransformCr)[2][16][16] = transform8x8? img->fadjust8x8Cr : img->fadjust4x4Cr;
int lumaAdjustIndex = transform8x8? 2 : 3;
int chromaAdjustIndex = transform8x8? 0 : 2;
//--- set coordinates ---
j0 = ((block/2)<<3); j1 = (j0>>2);
i0 = ((block%2)<<3); i1 = (i0>>2);
#ifdef BEST_NZ_COEFF
for(j = 0; j <= 1; j++)
{
for(i = 0; i <= 1; i++)
best_nz_coeff[i][j] = img->nz_coeff[img->current_mb_nr][i1 + i][j1 + j] = 0;
}
#endif
if (transform8x8)
currMB->luma_transform_size_8x8_flag = 1; //switch to transform size 8x8
//--- store coding state before coding ---
store_coding_state (cs_cm);
//===== LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION =====
for (min_cost8x8=INT_MAX, min_rdcost=1e30, index=(bslice?0:1); index<maxindex; index++)
{
mode = b8_mode_table[index];
*cost = 0;
if (enc_mb.valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
{
curr_cbp_blk = 0;
if (mode==0)
{
//--- Direct Mode ---
if (!input->rdopt )
{
direct4x4_tmp=0; direct8x8_tmp=0;
direct4x4_tmp = Get_Direct_Cost8x8 ( block, &direct8x8_tmp);
if ((direct4x4_tmp==INT_MAX)||(*cost_direct==INT_MAX))
{
*cost_direct = INT_MAX;
if (transform8x8)
*cost8x8_direct = INT_MAX;
}
else
{
*cost_direct += direct4x4_tmp;
if (transform8x8)
*cost8x8_direct += direct8x8_tmp;
}
*have_direct ++;
if (transform8x8)
{
switch(input->Transform8x8Mode)
{
case 1: // Mixture of 8x8 & 4x4 transform
if((direct8x8_tmp < direct4x4_tmp) || !(enc_mb.valid[5] && enc_mb.valid[6] && enc_mb.valid[7]))
*cost = direct8x8_tmp;
else
*cost = direct4x4_tmp;
break;
case 2: // 8x8 Transform only
*cost = direct8x8_tmp;
break;
default: // 4x4 Transform only
*cost = direct4x4_tmp;
break;
}
if (input->Transform8x8Mode==2)
*cost = INT_MAX;
}
else
{
*cost = direct4x4_tmp;
}
}
block_x = img->block_x+(block&1)*2;
block_y = img->block_y+(block&2);
best_ref[LIST_0] = direct_ref_idx[LIST_0][block_y][block_x];
best_ref[LIST_1] = direct_ref_idx[LIST_1][block_y][block_x];
best_pdir = direct_pdir[block_y][block_x];
} // if (mode==0)
else
{
//======= motion estimation for all reference frames ========
//-----------------------------------------------------------
PartitionMotionSearch (mode, block, enc_mb.lambda_mf);
//--- get cost and reference frame for LIST 0 prediction ---
bmcost[LIST_0] = INT_MAX;
list_prediction_cost(LIST_0, block, mode, enc_mb, bmcost, best_ref);
//store LIST 0 reference index for every block
block_x = img->block_x+(block&1)*2;
block_y = img->block_y+(block&2);
for (j = block_y; j< block_y + 2; j++)
{
for (i = block_x; i < block_x + 2; i++)
{
enc_picture->ref_idx [LIST_0][j][i] = best_ref[LIST_0];
enc_picture->ref_pic_id[LIST_0][j][i] =
enc_picture->ref_pic_num[enc_mb.list_offset[LIST_0]][(short)best_ref[LIST_0]];
}
}
if (bslice)
{
//--- get cost and reference frame for LIST 1 prediction ---
bmcost[LIST_1] = INT_MAX;
list_prediction_cost(LIST_1, block, mode, enc_mb, bmcost, best_ref);
// Compute bipredictive cost between best list 0 and best list 1 references
list_prediction_cost(BI_PRED, block, mode, enc_mb, bmcost, best_ref);
//--- get prediction direction ----
determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bi_pred_me);
//store backward reference index for every block
for (j = block_y; j< block_y + 2; j++)
{
for (i = block_x; i < block_x + 2; i++)
{
enc_picture->ref_idx[LIST_0][j][i] = best_ref[LIST_0];
enc_picture->ref_idx[LIST_1][j][i] = best_ref[LIST_1];
}
}
} // if (bslice)
else
{
best_pdir = 0;
*cost = bmcost[LIST_0];
}
} // if (mode!=0)
if (input->rdopt)
{
//--- get and check rate-distortion cost ---
rdcost = RDCost_for_8x8blocks (&cnt_nonz, &curr_cbp_blk, enc_mb.lambda_md,
block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]);
}
else
{
if (*cost!=INT_MAX)
*cost += (REF_COST (enc_mb.lambda_mf, B8Mode2Value (mode, best_pdir),
enc_mb.list_offset[(best_pdir<1?LIST_0:LIST_1)]) - 1);
}
//--- set variables if best mode has changed ---
if ( ( input->rdopt && rdcost < min_rdcost)
|| (!input->rdopt && *cost < min_cost8x8))
{
min_cost8x8 = *cost;
min_rdcost = rdcost;
dataTr->part8x8mode [block] = mode;
dataTr->part8x8pdir [block] = best_pdir;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -