📄 mv-search.c
字号:
//--- delete arrays ---
free (spiral_search_x);
free (spiral_search_y);
free (mvbits);
free (refbits);
free (byte_abs);
free_mem3Dint (motion_cost, 8);
#ifdef _FAST_FULL_ME_
ClearFastFullIntegerSearch ();
#endif
}
/*!
***********************************************************************
* \brief
* Full pixel block motion search
***********************************************************************
*/
int // ==> minimum motion cost after search
FullPelBlockMotionSearch (pel_t** orig_pic, // <-- original pixel values for the AxB block
int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
int* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
int search_range_x, // <-- 1-d search range in pel units (horizontal)
int search_range_y, // <-- 1-d search range in pel units (vertical)
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
double lambda) // <-- lagrangian parameter for determining motion cost
{
int pos, cand_x, cand_y, y, x4, mcost;
pel_t *orig_line, *ref_line;
pel_t *(*get_ref_line)(int, pel_t*, int, int);
pel_t*ref_pic = (ref==-1 ? Refbuf11_P : Refbuf11 [ref]);
int best_pos = 0; // position with minimum motion cost
int max_pos = (2*search_range_x+1)*(2*search_range_y+1); // number of search positions
int lambda_factor = LAMBDA_FACTOR (lambda); // factor for determining lagragian motion cost
int mvshift = (input->mv_res ? 3 : 2); // motion vector shift for getting sub-pel units
int blocksize_y = input->blc_size[blocktype][1]; // vertical block size
int blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
int blocksize_x4 = blocksize_x >> 2; // horizontal block size in 4-pel units
int pred_x = (pic_pix_x << mvshift) + pred_mv_x; // predicted position x (in sub-pel units)
int pred_y = (pic_pix_y << mvshift) + pred_mv_y; // predicted position y (in sub-pel units)
int center_x = pic_pix_x + *mv_x; // center position x (in pel units)
int center_y = pic_pix_y + *mv_y; // center position y (in pel units)
int check_for_00 = (blocktype==1 && !input->rdopt && img->type!=B_IMG && ref==0);
//===== set function for getting reference picture lines =====
if ((center_x > search_range_x) && (center_x < img->width -1-search_range_x-blocksize_x) &&
(center_y > search_range_y) && (center_y < img->height-1-search_range_y-blocksize_y) )
{
get_ref_line = FastLineX;
}
else
{
get_ref_line = UMVLineX;
}
//===== loop over all search positions =====
for (pos=0; pos<max_pos; pos++)
{
//--- set candidate position (absolute position in pel units) ---
cand_x = center_x + spiral_search_x[pos];
cand_y = center_y + spiral_search_y[pos];
//--- initialize motion cost (cost for motion vector) and check ---
mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
if (check_for_00 && cand_x==pic_pix_x && cand_y==pic_pix_y)
{
mcost -= WEIGHTED_COST (lambda_factor, 16);
}
if (mcost >= min_mcost) continue;
//--- add residual cost to motion cost ---
for (y=0; y<blocksize_y; y++)
{
ref_line = get_ref_line (blocksize_x, ref_pic, cand_y+y, cand_x);
orig_line = orig_pic [y];
for (x4=0; x4<blocksize_x4; x4++)
{
mcost += byte_abs[ *orig_line++ - *ref_line++ ];
mcost += byte_abs[ *orig_line++ - *ref_line++ ];
mcost += byte_abs[ *orig_line++ - *ref_line++ ];
mcost += byte_abs[ *orig_line++ - *ref_line++ ];
}
if (mcost >= min_mcost)
{
break;
}
}
//--- check if motion cost is less than minimum cost ---
if (mcost < min_mcost)
{
best_pos = pos;
min_mcost = mcost;
}
}
//===== set best motion vector and return minimum motion cost =====
if (best_pos)
{
*mv_x += spiral_search_x[best_pos];
*mv_y += spiral_search_y[best_pos];
}
return min_mcost;
}
#ifdef _FAST_FULL_ME_
/*!
***********************************************************************
* \brief
* Fast Full pixel block motion search
***********************************************************************
*/
int // ==> minimum motion cost after search
FastFullPelBlockMotionSearch (pel_t** orig_pic, // <-- not used
int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // --> motion vector (x) - in pel units
int* mv_y, // --> motion vector (y) - in pel units
int search_range_x, // <-- 1-d search range in pel units (horizontal)
int search_range_y, // <-- 1-d search range in pel units (vertical)
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
double lambda) // <-- lagrangian parameter for determining motion cost
{
int pos, offset_x, offset_y, cand_x, cand_y, mcost;
int refindex = (ref!=-1 ? ref : img->buf_cycle); // reference frame index (array entry)
int max_pos = (2*search_range_x+1)*(2*search_range_y+1); // number of search positions
int lambda_factor = LAMBDA_FACTOR (lambda); // factor for determining lagragian motion cost
int mvshift = (input->mv_res ? 3 : 2); // motion vector shift for getting sub-pel units
int best_pos = 0; // position with minimum motion cost
int block_index = (pic_pix_y-img->pix_y)+((pic_pix_x-img->pix_x)>>2); // block index for indexing SAD array
int* block_sad = BlockSAD[refindex][blocktype][block_index]; // pointer to SAD array
//===== set up fast full integer search if needed / set search center =====
if (!search_setup_done[refindex])
{
SetupFastFullPelSearch (ref);
}
offset_x = search_center_x[refindex] - img->pix_x;
offset_y = search_center_y[refindex] - img->pix_y;
//===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====
if (!input->rdopt)
{
mcost = block_sad[pos_00[refindex]] + MV_COST (lambda_factor, mvshift, 0, 0, pred_mv_x, pred_mv_y);
if (img->type!=B_IMG && blocktype==1 && ref==0)
{
mcost -= WEIGHTED_COST (lambda_factor, 16);
}
if (mcost < min_mcost)
{
min_mcost = mcost;
best_pos = pos_00[refindex];
}
}
//===== loop over all search positions =====
for (pos=0; pos<max_pos; pos++, block_sad++)
{
//--- check residual cost ---
if (*block_sad < min_mcost)
{
//--- get motion vector cost ---
cand_x = offset_x + spiral_search_x[pos];
cand_y = offset_y + spiral_search_y[pos];
mcost = *block_sad;
mcost += MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_mv_x, pred_mv_y);
//--- check motion cost ---
if (mcost < min_mcost)
{
min_mcost = mcost;
best_pos = pos;
}
}
}
//===== set best motion vector and return minimum motion cost =====
*mv_x = offset_x + spiral_search_x[best_pos];
*mv_y = offset_y + spiral_search_y[best_pos];
return min_mcost;
}
//***********************************************************************
//==============fast integer motion estimation algorithm by tsinghua univ., Zhibo Chen, July 22, 2002================
//***********************************************************************
int // ==> minimum motion cost after search
FastFullPelBlockMotionSearch_chen (pel_t** orig_pic, // <-- not used
int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // --> motion vector (x) - in pel units
int* mv_y, // --> motion vector (y) - in pel units
int search_range_x, // <-- 1-d search range in pel units
int search_range_y, // <-- 1-d search range in pel units
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
double lambda) // <-- lagrangian parameter for determining motion cost
{
int pos, offset_x, offset_y, cand_x, cand_y, mcost,mcost0;
int refindex = (ref!=-1 ? ref : img->buf_cycle); // reference frame index (array entry)
int search_range_dynamic = max(search_range_x,search_range_y); //add for Dynamic search
int search_range = input->search_range; //add for Dynamic search
int max_pos = (2*search_range+1)*(2*search_range+1); // number of search positions
int lambda_factor = LAMBDA_FACTOR (lambda); // factor for determining lagragian motion cost
int mvshift = (input->mv_res ? 3 : 2); // motion vector shift for getting sub-pel units
int best_pos = 0; // position with minimum motion cost
int block_index = (pic_pix_y-img->pix_y)+((pic_pix_x-img->pix_x)>>2); // block index for indexing SAD array
int* block_sad = BlockSAD[refindex][blocktype][block_index]; // pointer to SAD array
char* search_pos;
int predict_mv_x,predict_mv_y;
int center_x,center_y;
pel_t orig_blocks[256], *orgptr=orig_blocks,*refptr;
pel_t* ref_pic = (ref>=0 ? Refbuf11[ref] : Refbuf11_P);
int y,x,iXMinNow, iYMinNow, i,iXMinNext,iYMinNext;
int iDistortion0,iDistortion1,iDistortion2,iSADLayer,m,pos_x,pos_y,iSAD,currmv_x,currmv_y;
int range_partly_outside;
int max_width = img->width - 17;
int max_height = img->height - 17;
int search_step_orgin,search_step,search_index;
int iMinPred_x, iMinPred_y, iSadMinPred, iUsePred, iMvPred_x, iMvPred_y;
predict_mv_x = ceil((float)pred_mv_x / (1 << mvshift));//
predict_mv_y = ceil((float)pred_mv_y / (1 << mvshift));//
////////////////////////////////////////
center_x = predict_mv_x + img->pix_x;
center_y = predict_mv_y + img->pix_y;
offset_x = center_x - img->pix_x;
offset_y = center_y - img->pix_y;
if(offset_x!= 0 || offset_y!=0)
iUsePred = 1;
else
iUsePred = 0;
if (center_x >= search_range && center_x <= max_width - search_range &&
center_y >= search_range && center_y <= max_height - search_range )
{
range_partly_outside = 0; PelYline_11 = FastLine16Y_11;
}
else
{
range_partly_outside = 1;
}
for(y=0;y<2*search_range+1;y++)
for(x=0;x<2*search_range+1;x++)
{
SearchState[y][x]=0;
SearchStateMaD[y][x]=0;
}
for (y = img->pix_y; y < img->pix_y+16; y++)
for (x = img->pix_x; x < img->pix_x+16; x++)
{
*orgptr++ = imgY_org [y][x];
}
if(search_model == 0)
search_step_orgin = 5;
else if(search_model == 1)
search_step_orgin = 3;
else
search_step_orgin = 1;
orgptr = orig_blocks;
mcost0 = CalMad(range_partly_outside,orgptr,ref_pic,16,16,center_x,center_y);
SearchStateMaD[search_range][search_range] = mcost0; //(0,0)should be where predictor point
mcost0 += MV_COST (lambda_factor, mvshift, offset_x, offset_y, pred_mv_x, pred_mv_y);
SearchState[search_range][search_range] = mcost0; //(0,0)should be where predictor point
if (mcost0 < min_mcost)
{
min_mcost = mcost0;
iXMinNow = center_x;
iYMinNow = center_y;
currmv_x = offset_x;
currmv_y = offset_y;
}
search_step = search_step_orgin;
iDistortion0 = iDistortion1 = iDistortion2 = 65536;
while(search_step>0)
{
search_index = 1;
for(i=0;i<2*search_range_dynamic/search_step;i++)
{
iSADLayer = 65536;
for (m = 0; m < 8; m++)
{
orgptr = orig_blocks;
pos_x = iXMinNow + gpiHoriozntalPos[m]*search_step*search_index;
pos_y = iYMinNow + gpiVerticalPos[m]*search_step*search_index;
if(abs(pos_x - center_x) <32 && abs(pos_y - center_y)< 32)
{
if(SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range])
iSAD = SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range];
else
{
iSAD = CalMad(range_partly_outside,orgptr,ref_pic,16,16,pos_x,pos_y);
SearchStateMaD[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
iSAD += MV_COST (lambda_factor, mvshift, pos_x-img->pix_x, pos_y-img->pix_y, pred_mv_x, pred_mv_y);//Mv_cost;
SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
}
if (iSAD < min_mcost)
{
currmv_x = pos_x - img->pix_x;
currmv_y = pos_y - img->pix_y;
min_mcost = iSAD;
}
if (iSAD < iSADLayer)
{
iSADLayer = iSAD;
iXMinNext = pos_x;
iYMinNext = pos_y;
}
}
}
iDistortion2 = iDistortion1;
iDistortion1 = iDistortion0;
iDistortion0 = iSADLayer;
if (iDistortion1 <= iDistortion0 && iDistortion2 <= iDistortion0)
{
break;
}
search_index += 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -