mode_decision.c
来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 1,390 行 · 第 1/4 页
C
1,390 行
img->nz_coeff[currMB->mb_nr][i1 + i][j1 + j] = best_nz_coeff[i][j];
}
#endif
if (!transform8x8)
{
if (min_cost8x8 != INT_MAX)
dataTr->mb_p8x8_cost += min_cost8x8;
else
dataTr->mb_p8x8_cost = INT_MAX;
}
//----- set cbp and count of nonzero coefficients ---
if (best_cnt_nonz)
{
cbp8x8 |= (1 << block);
cnt_nonz_8x8 += best_cnt_nonz;
}
if (!transform8x8)
{
if (block < 3)
{
//===== re-set reconstructed block =====
j0 = 8*(block >> 1);
i0 = 8*(block & 0x01);
for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
{
memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x], dataTr->rec_mbY8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel));
}
if (params->rdopt == 3)
{
errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY_best8x8[transform8x8], j0, BLOCK_SIZE_8x8);
}
if(img->type==SP_SLICE &&(!si_frame_indicator))
{
for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
{
memcpy(&lrec[img->pix_y + j][img->pix_x], dataTr->lrec[j],2*BLOCK_SIZE*sizeof(imgpel)); // reset the coefficients for SP slice
}
}
if(img->P444_joined)
{
for (k=0; k<2; k++)
{
for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++)
{
memcpy(&enc_picture->imgUV[k][img->pix_y + j][img->pix_x], dataTr->rec_mb8x8_cr[k][j], BLOCK_SIZE_8x8 * sizeof(imgpel));
}
}
}
} // if (block<3)
}
else
{
//======= save motion data for 8x8 partition for transform size 8x8 ========
StoreNewMotionVectorsBlock8x8(0, block, dataTr->part8x8mode[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8pdir[block], dataTr->part8x8bipred[block], bslice);
}
//===== set motion vectors and reference frames (prediction) =====
SetRefAndMotionVectors (&enc_picture->motion, currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8bipred[block]);
//===== set the coding state after current block =====
//if (transform8x8 == 0 || block < 3)
if (stored_state_8x8 == TRUE)
reset_coding_state (currSlice, currMB, cs_b8);
else
{
update_adaptive_rounding_8x8(dataTr, fadjust);
}
}
}
/*!
*************************************************************************************
* \brief
* Low Complexity Mode Decision for an 8x8 sub-macroblock
*************************************************************************************
*/
void submacroblock_mode_decision_low(Slice *currSlice,
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 is_cavlc)
{
int64 curr_cbp_blk;
double min_rdcost, rdcost = 0.0;
int j0, i0, j1, i1;
int i,j, k;
int min_cost8x8, index;
int mode;
int direct4x4_tmp, direct8x8_tmp;
int bmcost[5] = {INT_MAX};
int cnt_nonz = 0;
int dummy;
int best_cnt_nonz = 0;
int maxindex = (transform8x8) ? 2 : 5;
int block_x, block_y;
int lambda_mf[3];
int ****fadjust = transform8x8? img->ARCofAdj8x8 : img->ARCofAdj4x4;
short pdir, bipred_me = 0;
char best_pdir = 0;
char best_ref[2] = {0, -1};
imgpel **mb_pred = img->mb_pred[0];
Boolean valid_8x8 = FALSE;
Boolean stored_state_8x8 = FALSE;
#ifdef BEST_NZ_COEFF
int best_nz_coeff[2][2];
#endif
//--- set coordinates ---
j0 = ((block>>1)<<3);
j1 = (j0>>2);
i0 = ((block&0x01)<<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[currMB->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 (currSlice, currMB, cs_cm);
//===== LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION =====
for (min_cost8x8 = INT_MAX, min_rdcost = 1e20, index = (bslice?0:1); index < maxindex; index++)
{
mode = b8_mode_table[index];
*cost = 0;
if (enc_mb->valid[mode] && (!(transform8x8 == 1 && mode > 4)) && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
{
if (transform8x8)
{
currMB->valid_8x8 = TRUE;
}
valid_8x8 = TRUE;
curr_cbp_blk = 0;
if (mode==0)
{
//--- Direct Mode ---
direct4x4_tmp = 0;
direct8x8_tmp = 0;
direct4x4_tmp = GetDirectCost8x8 ( currMB, 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(params->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 (params->Transform8x8Mode==2)
*cost = INT_MAX;
}
else
{
*cost = direct4x4_tmp;
}
block_x = img->block_x + (block & 0x01)*2;
block_y = img->block_y + (block & 0x02);
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
{
int64 ref_pic_num;
char b_ref;
//======= motion estimation for all reference frames ========
//-----------------------------------------------------------
memcpy(lambda_mf, enc_mb->lambda_mf, 3 * sizeof(int));
if (params->CtxAdptLagrangeMult == 1)
{
lambda_mf[F_PEL] = (int)(lambda_mf[F_PEL] * lambda_mf_factor);
lambda_mf[H_PEL] = (int)(lambda_mf[H_PEL] * lambda_mf_factor);
lambda_mf[Q_PEL] = (int)(lambda_mf[Q_PEL] * lambda_mf_factor);
}
PartitionMotionSearch (currMB, mode, block, lambda_mf);
//--- get cost and reference frame for LIST 0 prediction ---
bmcost[LIST_0] = INT_MAX;
list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref);
//store LIST 0 reference index for every block
block_x = img->block_x + (block & 0x01)*2;
block_y = img->block_y + (block & 0x02);
b_ref = best_ref[LIST_0];
ref_pic_num = enc_picture->ref_pic_num[enc_mb->list_offset[LIST_0]][(short) b_ref];
for (j = block_y; j< block_y + 2; j++)
{
memset(&enc_picture->motion.ref_idx [LIST_0][j][block_x], b_ref, 2 * sizeof(char));
}
for (j = block_y; j< block_y + 2; j++)
{
for (i = block_x; i < block_x + 2; i++)
{
enc_picture->motion.ref_pic_id[LIST_0][j][i] = ref_pic_num;
}
}
if (bslice)
{
//--- get cost and reference frame for LIST 1 prediction ---
bmcost[LIST_1] = INT_MAX;
bmcost[BI_PRED] = INT_MAX;
list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref);
// Compute bipredictive cost between best list 0 and best list 1 references
list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref);
// currently Bi prediction ME is only supported for modes 1, 2, 3 and only for ref 0 and only for ref 0
if (is_bipred_enabled(mode))
{
list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0);
list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0);
}
else
{
bmcost[BI_PRED_L0] = INT_MAX;
bmcost[BI_PRED_L1] = INT_MAX;
}
//--- get prediction direction ----
determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bipred_me);
//store backward reference index for every block
for (k = LIST_0; k <= LIST_1; k++)
{
for (j = block_y; j< block_y + 2; j++)
{
memset(&enc_picture->motion.ref_idx[k][j][block_x], best_ref[k], 2 * sizeof(char));
}
}
} // if (bslice)
else
{
best_pdir = 0;
*cost = bmcost[LIST_0];
}
} // if (mode!=0)
if (*cost!=INT_MAX)
*cost += (REF_COST (enc_mb->lambda_mf[Q_PEL], B8Mode2Value (mode, best_pdir),
enc_mb->list_offset[(best_pdir < 1 ? LIST_0 : LIST_1)]) - 1);
//--- set variables if best mode has changed ---
if (*cost < min_cost8x8)
{
min_cost8x8 = *cost;
min_rdcost = rdcost;
dataTr->part8x8mode [block] = mode;
dataTr->part8x8pdir [block] = best_pdir;
dataTr->part8x8l0ref [block] = best_ref[LIST_0];
dataTr->part8x8l1ref [block] = best_ref[LIST_1];
dataTr->part8x8bipred[block] = bipred_me;
currMB->b8mode[block] = mode;
#ifdef BEST_NZ_COEFF
if (cnt_nonz)
{
best_nz_coeff[0][0]= img->nz_coeff[currMB->mb_nr][i1 ][j1 ];
best_nz_coeff[0][1]= img->nz_coeff[currMB->mb_nr][i1 ][j1 + 1];
best_nz_coeff[1][0]= img->nz_coeff[currMB->mb_nr][i1 + 1][j1 ];
best_nz_coeff[1][1]= img->nz_coeff[currMB->mb_nr][i1 + 1][j1 + 1];
}
else
{
best_nz_coeff[0][0]= 0;
best_nz_coeff[0][1]= 0;
best_nz_coeff[1][0]= 0;
best_nz_coeff[1][1]= 0;
}
#endif
//--- store number of nonzero coefficients ---
best_cnt_nonz = cnt_nonz;
//--- store best 8x8 coding state ---
if (block < 3)
{
store_coding_state (currSlice, currMB, cs_b8);
stored_state_8x8 = TRUE;
}
} // if (rdcost <= min_rdcost)
//--- re-set coding state as it was before coding with current mode was performed ---
reset_coding_state (currSlice, currMB, cs_cm);
} // if ((enc_mb->valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag)))
} // for (min_rdcost=1e30, index=(bslice?0:1); index<6; index++)
if (valid_8x8 == TRUE)
{
#ifdef BEST_NZ_COEFF
for(i = 0; i <= 1; i++)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?