📄 mv-search.c
字号:
min_mcost, lambda_factor[F_PEL]);
}
else
{
//--- set search center ---
mv[0] = pred_mv[0] / 4;
mv[1] = pred_mv[1] / 4;
if (!input->rdopt)
{
//--- adjust search center so that the (0,0)-vector is inside ---
mv[0] = iClip3 (-search_range, search_range, mv[0]);
mv[1] = iClip3 (-search_range, search_range, mv[1]);
}
mv[0] = iClip3(-2047 + search_range, 2047 - search_range, mv[0]);
mv[1] = iClip3(LEVELMVLIMIT[img->LevelIndex][0] + search_range, LEVELMVLIMIT[img->LevelIndex][1] - search_range, mv[1]);
//--- perform motion search ---
min_mcost = FullPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv[0], pred_mv[1], &mv[0], &mv[1], search_range,
min_mcost, lambda_factor[F_PEL]);
}
//===== convert search center to quarter-pel units =====
if (input->EPZSSubPelGrid == 0 || input->SearchMode != EPZS)
{
mv[0] <<= 2;
mv[1] <<= 2;
}
//==============================
//===== SUB-PEL SEARCH =====
//==============================
ChromaMEEnable = (input->ChromaMEEnable == ME_YUV_FP_SP ) ? 1 : 0; // set it externally
if (!input->DisableSubpelME)
{
if (input->SearchMode != EPZS || (ref == 0 || img->structure != FRAME || (ref > 0 && min_mcost < 3.5 * prevSad[pic_pix_x >> 2])))
{
if ( !start_me_refinement_hp )
{
min_mcost = max_value;
}
if (input->SearchMode == UM_HEX)
{
if(blocktype >3)
{
min_mcost = UMHEXSubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv[0], pred_mv[1], &mv[0], &mv[1], 9, 9, min_mcost, lambda_factor[Q_PEL]);
}
else
{
min_mcost = SubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv[0], pred_mv[1], &mv[0], &mv[1], 9, 9, min_mcost, lambda_factor);
}
}
else if (input->SearchMode == UM_HEX_SIMPLE)
{
if(blocktype > 1)
{
min_mcost = smpUMHEXSubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y,
blocktype, pred_mv[0], pred_mv[1], &mv[0], &mv[1], 9, 9, min_mcost, lambda_factor[Q_PEL]);
}
else
{
min_mcost = smpUMHEXFullSubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y,
blocktype, pred_mv[0], pred_mv[1], &mv[0], &mv[1], 9, 9, min_mcost, lambda_factor[Q_PEL]);
}
}
else if (input->SearchMode == EPZS && input->EPZSSubPelME)
{
min_mcost = EPZSSubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv, mv, 9, 9, min_mcost, lambda_factor);
}
else
{
min_mcost = SubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv[0], pred_mv[1], &mv[0], &mv[1], 9, 9, min_mcost, lambda_factor);
}
}
}
if (!input->rdopt)
{
// Get the skip mode cost
if (blocktype == 1 && (img->type == P_SLICE||img->type == SP_SLICE))
{
int cost;
FindSkipModeMotionVector ();
cost = GetSkipCostMB ();
cost -= ((lambda_factor[Q_PEL] + 4096) >> 13);
if (cost < min_mcost)
{
min_mcost = cost;
mv[0] = img->all_mv [0][0][0][0][0][0];
mv[1] = img->all_mv [0][0][0][0][0][1];
}
}
}
//===============================================
//===== SET MV'S AND RETURN MOTION COST =====
//===============================================
for (j=block_y; j < block_y + (bsy>>2); j++)
{
for (i=block_x; i < block_x + (bsx>>2); i++)
{
all_mv[j][i][list][ref][blocktype][0] = mv[0];
all_mv[j][i][list][ref][blocktype][1] = mv[1];
}
}
if (img->type==B_SLICE && input->BiPredMotionEstimation != 0 && (blocktype == 1) && (ref==0))
{
short ******bipred_mv = list ? img->bipred_mv1 : img->bipred_mv2;
int min_mcostbi = max_value;
short bimv[2] = {0, 0}, tempmv[2] = {0, 0};
short *pred_mv1 = NULL;
short *pred_mv2 = NULL;
short iterlist=list;
short pred_mv_bi[2];
if (input->SearchMode == UM_HEX)
{
bipred_flag = 1;
UMHEXSetMotionVectorPredictor(pred_mv_bi, enc_picture->ref_idx[list ^ 1], enc_picture->mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), block_x, block_y, bsx, bsy, &search_range);
}
else
SetMotionVectorPredictor (pred_mv_bi, enc_picture->ref_idx[list ^ 1], enc_picture->mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), block_x, block_y, bsx, bsy);
if ((input->SearchMode != EPZS) || (input->EPZSSubPelGrid == 0))
{
mv[0]=(mv[0] + 2)>>2;
mv[1]=(mv[1] + 2)>>2;
}
//Bi-predictive motion Refinements
for (i=0;i<=input->BiPredMERefinements;i++)
{
if (i%2)
{
pred_mv2=pred_mv;
pred_mv1=pred_mv_bi;
tempmv[0]=bimv[0];
tempmv[1]=bimv[1];
bimv[0]=mv[0];
bimv[1]=mv[1];
iterlist= list ^ 1;
}
else
{
pred_mv1=pred_mv;
pred_mv2=pred_mv_bi;
if (i!=0)
{
tempmv[0]=bimv[0];
tempmv[1]=bimv[1];
bimv[0]=mv[0];
bimv[1]=mv[1];
}
else
{
tempmv[0]=mv[0];
tempmv[1]=mv[1];
if ((input->SearchMode != EPZS) || (input->EPZSSubPelGrid == 0))
{
bimv[0] = (pred_mv2[0] + 2)>>2;
bimv[1] = (pred_mv2[1] + 2)>>2;
}
else
{
bimv[0] = pred_mv2[0];
bimv[1] = pred_mv2[1];
}
}
iterlist=list;
}
mv[0]=bimv[0];
mv[1]=bimv[1];
if (input->SearchMode == EPZS)
{
min_mcostbi = EPZSBiPredBlockMotionSearch (orig_pic, ref, iterlist,
list_offset, enc_picture->ref_idx, enc_picture->mv,
pic_pix_x, pic_pix_y, blocktype,
pred_mv1, pred_mv2, bimv, tempmv,
(input->BiPredMESearchRange<<(input->EPZSSubPelGrid * 2))>>i, min_mcostbi, lambda_factor[F_PEL]);
}
else if(input->SearchMode == UM_HEX)
{
min_mcostbi = UMHEXBipredIntegerPelBlockMotionSearch (orig_pic, ref, iterlist,
pic_pix_x, pic_pix_y, blocktype,
pred_mv1[0], pred_mv1[1], pred_mv2[0], pred_mv2[1],
&bimv[0], &bimv[1], &tempmv[0], &tempmv[1],
input->BiPredMESearchRange>>i, min_mcostbi, lambda_factor[F_PEL]);
}
else if(input->SearchMode == UM_HEX_SIMPLE)
{
min_mcostbi = smpUMHEXBipredIntegerPelBlockMotionSearch (orig_pic, ref, iterlist,
pic_pix_x, pic_pix_y, blocktype,
pred_mv[0], pred_mv[1], pred_mv[0], pred_mv[1],
&bimv[0], &bimv[1], &tempmv[0], &tempmv[1],
input->BiPredMESearchRange>>i, min_mcostbi, lambda_factor[F_PEL]);
}
else
{
min_mcostbi = FullPelBlockMotionBiPred (orig_pic, ref, iterlist,
pic_pix_x, pic_pix_y, blocktype,
pred_mv1[0], pred_mv1[1], pred_mv2[0], pred_mv2[1],
&bimv[0], &bimv[1], &tempmv[0], &tempmv[1],
input->BiPredMESearchRange>>i, min_mcostbi, lambda_factor[F_PEL]);
}
if ((mv[0] == bimv[0]) && (mv[1] == bimv[1]))
{
//mv[0]=tempmv[0];
//mv[1]=tempmv[1];
//break;
}
mv[0]=tempmv[0];
mv[1]=tempmv[1];
}
if ((input->SearchMode != EPZS) || (input->EPZSSubPelGrid == 0))
{
mv[0]=tempmv[0] << 2;
mv[1]=tempmv[1] << 2;
bimv[0] = bimv[0] << 2;
bimv[1] = bimv[1] << 2;
}
if (input->BiPredMESubPel && !input->DisableSubpelME)
{
if ( !start_me_refinement_hp )
{
min_mcostbi = max_value;
}
if (input->SearchMode == EPZS && input->EPZSSubPelMEBiPred)
{
min_mcostbi = EPZSSubPelBlockSearchBiPred (orig_pic, ref, iterlist, pic_pix_x, pic_pix_y, blocktype,
pred_mv2, pred_mv1, bimv, mv, 9, 9, min_mcostbi, lambda_factor);
}
else
{
min_mcostbi = SubPelBlockSearchBiPred (orig_pic, ref, iterlist, pic_pix_x, pic_pix_y, blocktype,
pred_mv2[0], pred_mv2[1], &bimv[0], &bimv[1], &mv[0], &mv[1], 9, 9,
min_mcostbi, lambda_factor);
}
}
if (input->BiPredMESubPel==2 && !input->DisableSubpelME)
{
if ( !start_me_refinement_hp || !start_me_refinement_qp)
{
min_mcostbi = max_value;
}
if (input->SearchMode == EPZS && input->EPZSSubPelMEBiPred)
{
min_mcostbi = EPZSSubPelBlockSearchBiPred (orig_pic, ref, iterlist ^ 1, pic_pix_x, pic_pix_y, blocktype,
pred_mv1, pred_mv2, mv, bimv, 9, 9, min_mcostbi, lambda_factor);
}
else
{
min_mcostbi = SubPelBlockSearchBiPred (orig_pic, ref, iterlist ^ 1, pic_pix_x, pic_pix_y, blocktype,
pred_mv1[0], pred_mv1[1], &mv[0], &mv[1], &bimv[0], &bimv[1], 9, 9,
min_mcostbi, lambda_factor);
}
}
for (j=block_y; j < block_y + (bsy>>2); j++)
{
for (i=block_x ; i < block_x + (bsx>>2); i++)
{
bipred_mv[j][i][iterlist ][0][blocktype][0] = mv[0];
bipred_mv[j][i][iterlist ][0][blocktype][1] = mv[1];
bipred_mv[j][i][iterlist ^ 1][0][blocktype][0] = bimv[0];
bipred_mv[j][i][iterlist ^ 1][0][blocktype][1] = bimv[1];
}
}
}
#if GET_METIME
ftime(&tstruct2); // end time ms
me_tmp_time=(tstruct2.time*1000+tstruct2.millitm) - (tstruct1.time*1000+tstruct1.millitm);
me_tot_time += me_tmp_time;
me_time += me_tmp_time;
#endif
return min_mcost;
}
/*!
***********************************************************************
* \brief
* Motion Cost for Bidirectional modes
***********************************************************************
*/
int BIDPartitionCost (int blocktype,
int block8x8,
short ref_l0,
short ref_l1,
int lambda_factor)
{
static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
int curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; // ABT pred.error buffer
int bsx = imin(input->blc_size[blocktype][0],8);
int bsy = imin(input->blc_size[blocktype][1],8);
int pic_pix_x, pic_pix_y, block_x, block_y;
int v, h, mcost, i, j, k;
int mvd_bits = 0;
int parttype = (blocktype<4?blocktype:4);
int step_h0 = (input->part_size[ parttype][0]);
int step_v0 = (input->part_size[ parttype][1]);
int step_h = (input->part_size[blocktype][0]);
int step_v = (input->part_size[blocktype][1]);
int bxx, byy; // indexing curr_blk
int bx = bx0[parttype][block8x8];
int by = by0[parttype][block8x8];
short ******all_mv = img->all_mv;
short ****** p_mv = img->pred_mv;
//----- cost for motion vector bits -----
for (v=by; v<by + step_v0; v+=step_v)
{
for (h=bx; h<bx + step_h0; h+=step_h)
{
mvd_bits += mvbits[ all_mv [v][h][LIST_0][ref_l0][blocktype][0] - p_mv[v][h][LIST_0][ref_l0][blocktype][0] ];
mvd_bits += mvbits[ all_mv [v][h][LIST_0][ref_l0][blocktype][1] - p_mv[v][h][LIST_0][ref_l0][blocktype][1] ];
mvd_bits += mvbits[ all_mv [v][h][LIST_1][ref_l1][blocktype][0] - p_mv[v][h][LIST_1][ref_l1][blocktype][0] ];
mvd_bits += mvbits[ all_mv [v][h][LIST_1][ref_l1][blocktype][1] - p_mv[v][h][LIST_1][ref_l1][blocktype][1] ];
}
}
mcost = WEIGHTED_COST (lambda_factor, mvd_bits);
//----- cost of residual signal -----
for (byy=0, v=by; v<by + step_v0; byy+=4, v++)
{
pic_pix_y = img->opix_y + (block_y = (v<<2));
for (bxx=0, h=bx; h<bx + step_h0; bxx+=4, h++)
{
pic_pix_x = img->opix_x + (block_x = (h<<2));
LumaPrediction4x4 (block_x, block_y, 2, blocktype, blocktype, ref_l0, ref_l1);
for (k=j=0; j<4; j++)
{
for ( i=0; i<4; i++)
diff64[k++] = curr_blk[byy+j][bxx+i] =
imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
}
if ((!input->Transform8x8Mode) || (blocktype>4))
mcost += distortion4x4 (diff64);
}
}
if (input->Transform8x8Mode && (blocktype<=4)) // tchen 4-29-04
{
for (byy=0; byy < input->blc_size[parttype][1]; byy+=bsy)
for (bxx=0; bxx<input->blc_size[parttype][0]; bxx+=bsx)
{
for (k=0, j=byy;j<byy + 8;j++, k += 8)
memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -