📄 mv-search.c
字号:
else if (mb_y > 0)
{
block_available_upleft = block_available_left;
}
else
{
block_available_upleft = mb_available_upleft;
}
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? refFrArr[pic_block_y] [pic_block_x-1] : -1;
rFrameU = block_available_up ? refFrArr[pic_block_y-1][pic_block_x] : -1;
rFrameUR = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] :
block_available_upleft ? refFrArr[pic_block_y-1][pic_block_x-1] : -1;
/* Prediction if only one of the neighbors uses the reference frame
* we are checking
*/
if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_L;
else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_U;
else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
mvPredType = MVPRED_UR;
// Directional predictions
else if(blockshape_x == 8 && blockshape_y == 16)
{
if(mb_x == 0)
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
else
{
if(rFrameUR == ref_frame)
mvPredType = MVPRED_UR;
}
}
else if(blockshape_x == 16 && blockshape_y == 8)
{
if(mb_y == 0)
{
if(rFrameU == ref_frame)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
}
#define MEDIAN(a,b,c) (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)
for (hv=0; hv < 2; hv++)
{
mv_a = block_available_left ? tmp_mv[hv][pic_block_y ][4+pic_block_x-1] : 0;
mv_b = block_available_up ? tmp_mv[hv][pic_block_y-1][4+pic_block_x] : 0;
mv_d = block_available_upleft ? tmp_mv[hv][pic_block_y-1][4+pic_block_x-1] : 0;
mv_c = block_available_upright ? tmp_mv[hv][pic_block_y-1][4+pic_block_x+blockshape_x/4] : mv_d;
//czb add this for defineing search model at 2002/7/17
temp = (block_available_left<<2) + (block_available_up<<1) + block_available_upleft;
if(temp == 0)
search_model_mv[hv] = 0;
else if(temp == 1 || temp == 2 || temp == 4)
search_model_mv[hv] = 1;
else if(temp == 3 || temp == 5 || temp == 6)
{
search_model_mv[hv] = 2;
}
else if(temp == 7)
{
if(mv_a == mv_b && mv_a == mv_c)
search_model_mv[hv] = 3;
else
search_model_mv[hv] = 2;
}
/////////////////////////////
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_available_upleft || block_available_up || block_available_upright))
pred_vec = mv_a;
else
pred_vec = MEDIAN (mv_a, mv_b, mv_c);
break;
case MVPRED_L:
pred_vec = mv_a;
break;
case MVPRED_U:
pred_vec = mv_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
break;
default:
break;
}
pmv[hv] = pred_vec;
}
search_model = max(search_model_mv[0],search_model_mv[1]);
#undef MEDIAN
}
/*!
***********************************************************************
* \brief
* Setup the fast search for an macroblock
***********************************************************************
*/
void
SetupFastFullPelSearch (int ref) // <-- reference frame parameter (0... or -1 (backward))
{
int pmv[2];
pel_t orig_blocks[256], *orgptr=orig_blocks, *refptr;
int offset_x, offset_y, x, y, range_partly_outside, ref_x, ref_y, pos, abs_x, abs_y, bindex, blky;
int LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
int mvshift = (input->mv_res ? 3 : 2);
int refframe = (ref>=0 ? ref : 0);
int refindex = (ref>=0 ? ref : img->buf_cycle);
pel_t* ref_pic = (ref>=0 ? Refbuf11[ref] : Refbuf11_P);
int** ref_array = (img->type!=B_IMG ? refFrArr : ref>=0 ? fw_refFrArr : bw_refFrArr);
int*** mv_array = (img->type!=B_IMG ? tmp_mv : ref>=0 ? tmp_fwMV : tmp_bwMV);
int** block_sad = BlockSAD[refindex][7];
int max_width = img->width - 17;
int max_height = img->height - 17;
int search_range = max_search_range[refindex];
int max_pos = (2*search_range_x+1) * (2*search_range_y+1);
//===== get search center: predictor of 16x16 block =====
SetMotionVectorPredictor (pmv, ref_array, mv_array, refframe, 0, 0, 16, 16);
search_center_x[refindex] = pmv[0] / (1 << mvshift);
search_center_y[refindex] = pmv[1] / (1 << mvshift);
if (!input->rdopt)
{
//--- correct center so that (0,0) vector is inside ---
search_center_x[refindex] = max(-search_range_x, min(search_range_x, search_center_x[refindex]));
search_center_y[refindex] = max(-search_range_y, min(search_range_y, search_center_y[refindex]));
}
search_center_x[refindex] += img->pix_x;
search_center_y[refindex] += img->pix_y;
offset_x = search_center_x[refindex];
offset_y = search_center_y[refindex];
//===== copy original block for fast access =====
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];
//===== check if whole search range is inside image =====
if (offset_x >= search_range_x && offset_x <= max_width - search_range_x &&
offset_y >= search_range_y && offset_y <= max_height - search_range_y )
{
range_partly_outside = 0; PelYline_11 = FastLine16Y_11;
}
else
{
range_partly_outside = 1;
}
//===== determine position of (0,0)-vector =====
if (!input->rdopt)
{
ref_x = img->pix_x - offset_x;
ref_y = img->pix_y - offset_y;
for (pos = 0; pos < max_pos; pos++)
{
if (ref_x == spiral_search_x[pos] &&
ref_y == spiral_search_y[pos])
{
pos_00[refindex] = pos;
break;
}
}
}
//===== loop over search range (spiral search): get blockwise SAD =====
for (pos = 0; pos < max_pos; pos++)
{
abs_y = offset_y + spiral_search_y[pos];
abs_x = offset_x + spiral_search_x[pos];
if (range_partly_outside)
{
if (abs_y >= 0 && abs_y <= max_height &&
abs_x >= 0 && abs_x <= max_width )
{
PelYline_11 = FastLine16Y_11;
}
else
{
PelYline_11 = UMVLine16Y_11;
}
}
orgptr = orig_blocks;
bindex = 0;
for (blky = 0; blky < 4; blky++)
{
LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
for (y = 0; y < 4; y++)
{
refptr = PelYline_11 (ref_pic, abs_y++, abs_x);
LineSadBlk0 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk0 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk0 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk0 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk1 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk1 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk1 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk1 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk2 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk2 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk2 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk2 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk3 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk3 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk3 += byte_abs [*refptr++ - *orgptr++];
LineSadBlk3 += byte_abs [*refptr++ - *orgptr++];
}
block_sad[bindex++][pos] = LineSadBlk0;
block_sad[bindex++][pos] = LineSadBlk1;
block_sad[bindex++][pos] = LineSadBlk2;
block_sad[bindex++][pos] = LineSadBlk3;
}
}
//===== combine SAD's for larger block types =====
SetupLargerBlocks (refindex, max_pos);
//===== set flag marking that search setup have been done =====
search_setup_done[refindex] = 1;
}
#endif // _FAST_FULL_ME_
/*!
************************************************************************
* \brief
* Initialize the motion search
************************************************************************
*/
void
Init_Motion_Search_Module ()
{
int bits, i, imin, imax, k, l;
int search_range = input->search_range;
int number_of_reference_frames = img->buf_cycle;
int max_search_points = (2*search_range+1)*(2*search_range+1);
int max_ref_bits = 1 + 2 * (int)floor(log(max(16,number_of_reference_frames+1)) / log(2) + 1e-10);
int max_ref = (1<<((max_ref_bits>>1)+1))-1;
int number_of_subpel_positions = (input->mv_res?8:4) * (2*search_range+3);
int max_mv_bits = 3 + 2 * (int)ceil (log(number_of_subpel_positions+1) / log(2) + 1e-10);
max_mvd = (1<<( max_mv_bits >>1) )-1;
//===== CREATE ARRAYS =====
//-----------------------------
if ((spiral_search_x = (int*)calloc(max_search_points, sizeof(int))) == NULL)
no_mem_exit("Init_Motion_Search_Module: spiral_search_x");
if ((spiral_search_y = (int*)calloc(max_search_points, sizeof(int))) == NULL)
no_mem_exit("Init_Motion_Search_Module: spiral_search_y");
if ((mvbits = (int*)calloc(2*max_mvd+1, sizeof(int))) == NULL)
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_mem3Dint (&motion_cost, 8, img->buf_cycle+1, 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -