📄 mv-search.c
字号:
no_mem_exit("Init_Motion_Search_Module: mvbits");
if ((refbits = (int*)calloc(max_ref, sizeof(int))) == NULL)
no_mem_exit("Init_Motion_Search_Module: refbits");
if ((byte_abs = (int*)calloc(512, sizeof(int))) == NULL)
no_mem_exit("Init_Motion_Search_Module: byte_abs");
get_mem4Dint (&motion_cost, 8, 2*(img->buf_cycle+1),2, 4);
//--- set array offsets ---
mvbits += max_mvd;
byte_abs += 256;
//===== INIT ARRAYS =====
//---------------------------
//--- init array: motion vector bits ---
mvbits[0] = 1;
for (bits=3; bits<=max_mv_bits; bits+=2)
{
imax = 1 << (bits >> 1);
imin = imax >> 1;
for (i = imin; i < imax; i++) mvbits[-i] = mvbits[i] = bits;
}
//--- init array: reference frame bits ---
refbits[0] = 1;
for (bits=3; bits<=max_ref_bits; bits+=2)
{
imax = (1 << ((bits >> 1) + 1)) - 1;
imin = imax >> 1;
for (i = imin; i < imax; i++) refbits[i] = bits;
}
//--- init array: absolute value ---
byte_abs[0] = 0;
for (i=1; i<256; i++) byte_abs[i] = byte_abs[-i] = i;
//--- init array: search pattern ---
spiral_search_x[0] = spiral_search_y[0] = 0;
for (k=1, l=1; l<=max(1,search_range); l++)
{
for (i=-l+1; i< l; i++)
{
spiral_search_x[k] = i; spiral_search_y[k++] = -l;
spiral_search_x[k] = i; spiral_search_y[k++] = l;
}
for (i=-l; i<=l; i++)
{
spiral_search_x[k] = -l; spiral_search_y[k++] = i;
spiral_search_x[k] = l; spiral_search_y[k++] = i;
}
}
#ifdef _FAST_FULL_ME_
InitializeFastFullIntegerSearch ();
#endif
}
/*!
************************************************************************
* \brief
* Free memory used by motion search
************************************************************************
*/
void
Clear_Motion_Search_Module ()
{
//--- correct array offset ---
mvbits -= max_mvd;
byte_abs -= 256;
//--- delete arrays ---
free (spiral_search_x);
free (spiral_search_y);
free (mvbits);
free (refbits);
free (byte_abs);
free_mem4Dint (motion_cost, 2, 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, // <-- 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, 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<0 ? listX[LIST_1][0]->imgY_11 : listX[LIST_0][ref]->imgY_11;
int best_pos = 0; // position with minimum motion cost
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 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 << 2) + pred_mv_x; // predicted position x (in sub-pel units)
int pred_y = (pic_pix_y << 2) + 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_SLICE && ref==0);
//===== set function for getting reference picture lines =====
if ((center_x > search_range) && (center_x < img->width -1-search_range-blocksize_x) &&
(center_y > search_range) && (center_y < img->height-1-search_range-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, 2, 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 list,
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, // <-- 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;
// int refindex = (ref!=-1 ? ref : img->buf_cycle); // reference frame index (array entry)
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 best_pos = 0; // position with minimum motion cost
int block_index; // block index for indexing SAD array
int* block_sad; // pointer to SAD array
int pix_y;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
pix_y = img->field_pix_y;
block_index = (pic_pix_y-pix_y)+((pic_pix_x-img->pix_x)>>2);
block_sad = BlockSAD[list][ref][blocktype][block_index];
}
else
{
block_index = (pic_pix_y-img->pix_y)+((pic_pix_x-img->pix_x)>>2); // block index for indexing SAD array
block_sad = BlockSAD[list][ref][blocktype][block_index]; // pointer to SAD array
pix_y = img->pix_y;
}
//===== set up fast full integer search if needed / set search center =====
if (!search_setup_done[list][ref])
{
SetupFastFullPelSearch (ref, list);
}
offset_x = search_center_x[list][ref] - img->pix_x;
offset_y = search_center_y[list][ref] - pix_y;
//===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====
if (!input->rdopt)
{
mcost = block_sad[pos_00[list][ref]] + MV_COST (lambda_factor, 2, 0, 0, pred_mv_x, pred_mv_y);
if (mcost < min_mcost)
{
min_mcost = mcost;
best_pos = pos_00[list][ref];
}
}
//===== 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, 2, 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;
}
#endif
/*!
***********************************************************************
* \brief
* Calculate SA(T)D
***********************************************************************
*/
int
SATD (int* diff, int use_hadamard)
{
int k, satd = 0, m[16], dd, *d=diff;
if (use_hadamard)
{
/*===== hadamard transform =====*/
m[ 0] = d[ 0] + d[12];
m[ 4] = d[ 4] + d[ 8];
m[ 8] = d[ 4] - d[ 8];
m[12] = d[ 0] - d[12];
m[ 1] = d[ 1] + d[13];
m[ 5] = d[ 5] + d[ 9];
m[ 9] = d[ 5] - d[ 9];
m[13] = d[ 1] - d[13];
m[ 2] = d[ 2] + d[14];
m[ 6] = d[ 6] + d[10];
m[10] = d[ 6] - d[10];
m[14] = d[ 2] - d[14];
m[ 3] = d[ 3] + d[15];
m[ 7] = d[ 7] + d[11];
m[11] = d[ 7] - d[11];
m[15] = d[ 3] - d[15];
d[ 0] = m[ 0] + m[ 4];
d[ 8] = m[ 0] - m[ 4];
d[ 4] = m[ 8] + m[12];
d[12] = m[12] - m[ 8];
d[ 1] = m[ 1] + m[ 5];
d[ 9] = m[ 1] - m[ 5];
d[ 5] = m[ 9] + m[13];
d[13] = m[13] - m[ 9];
d[ 2] = m[ 2] + m[ 6];
d[10] = m[ 2] - m[ 6];
d[ 6] = m[10] + m[14];
d[14] = m[14] - m[10];
d[ 3] = m[ 3] + m[ 7];
d[11] = m[ 3] - m[ 7];
d[ 7] = m[11] + m[15];
d[15] = m[15] - m[11];
m[ 0] = d[ 0] + d[ 3];
m[ 1] = d[ 1] + d[ 2];
m[ 2] = d[ 1] - d[ 2];
m[ 3] = d[ 0] - d[ 3];
m[ 4] = d[ 4] + d[ 7];
m[ 5] = d[ 5] + d[ 6];
m[ 6] = d[ 5] - d[ 6];
m[ 7] = d[ 4] - d[ 7];
m[ 8] = d[ 8] + d[11];
m[ 9] = d[ 9] + d[10];
m[10] = d[ 9] - d[10];
m[11] = d[ 8] - d[11];
m[12] = d[12] + d[15];
m[13] = d[13] + d[14];
m[14] = d[13] - d[14];
m[15] = d[12] - d[15];
d[ 0] = m[ 0] + m[ 1];
d[ 1] = m[ 0] - m[ 1];
d[ 2] = m[ 2] + m[ 3];
d[ 3] = m[ 3] - m[ 2];
d[ 4] = m[ 4] + m[ 5];
d[ 5] = m[ 4] - m[ 5];
d[ 6] = m[ 6] + m[ 7];
d[ 7] = m[ 7] - m[ 6];
d[ 8] = m[ 8] + m[ 9];
d[ 9] = m[ 8] - m[ 9];
d[10] = m[10] + m[11];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -