📄 mv-search.c
字号:
search_center_y[refindex] += pix_y;
offset_x = search_center_x[refindex];
offset_y = search_center_y[refindex];
//===== copy original block for fast access =====
for (y = pix_y; y < pix_y+16; y++)
for (x = img->pix_x; x < img->pix_x+16; x++)
*orgptr++ = imgY_orig [y][x];
//===== check if whole search range is inside image =====
if (offset_x >= search_range && offset_x <= max_width - search_range &&
offset_y >= search_range && offset_y <= max_height - search_range )
{
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 = 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
* setting the motion vector predictor
***********************************************************************
*/
void
SetMotionVectorPredictor (int pmv[2],
int **refFrArr,
int ***tmp_mv,
int ref_frame,
int mb_x,
int mb_y,
int blockshape_x,
int blockshape_y)
{
int pic_block_x = img->block_x + (mb_x>>2);
int pic_block_y = img->block_y + (mb_y>>2);
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width ].slice_nr);
int mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1 ].slice_nr);
int mb_available_upleft = (img->mb_x == 0 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr);
int mb_available_upright = (img->mb_x >= mb_width-1 ||
img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr);
int block_available_up, block_available_left, block_available_upright, block_available_upleft;
int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
pic_block_y = img->field_block_y + (mb_y>>2);
mb_available_up = (img->field_mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width ].slice_nr);
mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1 ].slice_nr);
mb_available_upleft = (img->mb_x == 0 ||
img->field_mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr);
mb_available_upright = (img->mb_x >= mb_width-1 ||
img->field_mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr);
}
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
{
if(img->field_mode && !img->top_field)
mb_available_upright=0; // set mb_available_upright to 0 for bottom MBs in a MB pair
else if(!img->field_mode && img->mb_y%2)
mb_available_upright=0; // set mb_available_upright to 0 for bottom MBs in a MB pair
}
/* D B C */
/* A X */
/* 1 A, B, D are set to 0 if unavailable */
/* 2 If C is not available it is replaced by D */
block_available_up = mb_available_up || (mb_y > 0);
block_available_left = mb_available_left || (mb_x > 0);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_available_upright = 0;
else block_available_upright = 1;
}
else
{
if (mb_x+blockshape_x != 8) block_available_upright = 1;
else block_available_upright = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_available_upright = 1;
else block_available_upright = 0;
}
}
else if (mb_x+blockshape_x != MB_BLOCK_SIZE)
{
block_available_upright = block_available_up;
}
else
{
block_available_upright = mb_available_upright;
}
if (mb_x > 0)
{
block_available_upleft = (mb_y > 0 ? 1 : block_available_up);
}
else if (mb_y > 0)
{
block_available_upleft = block_available_left;
}
else
{
block_available_upleft = mb_available_upleft;
}
// if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
// block_available_upright = 0; // temp fix for MB level field/frame coding
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( block_available_upright && refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] == ref_frame)
//if(rFrameUR == ref_frame) // not correct
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;
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;
}
#undef MEDIAN
}
/*!
************************************************************************
* \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 = 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, 2*(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -