📄 mv-search.c
字号:
imgY_orig = imgY_org_bot;
}
}
//===== get search center: predictor of 16x16 block =====
SetMotionVectorPredictor (pmv, enc_picture->ref_idx, enc_picture->mv, ref, list, 0, 0, 16, 16);
search_center_x[list][ref] = pmv[0] / 4;
search_center_y[list][ref] = pmv[1] / 4;
if (!input->rdopt)
{
//--- correct center so that (0,0) vector is inside ---
search_center_x[list][ref] = max(-search_range, min(search_range, search_center_x[list][ref]));
search_center_y[list][ref] = max(-search_range, min(search_range, search_center_y[list][ref]));
}
search_center_x[list][ref] += img->pix_x;
search_center_y[list][ref] += pix_y;
offset_x = search_center_x[list][ref];
offset_y = search_center_y[list][ref];
//===== 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[list][ref] = 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 (list, ref, max_pos);
//===== set flag marking that search setup have been done =====
search_setup_done[list][ref] = 1;
}
#endif // _FAST_FULL_ME_
/*!
************************************************************************
* \brief
* Set motion vector predictor
************************************************************************
*/
void SetMotionVectorPredictor (int pmv[2],
int ***refPic,
int ****tmp_mv,
int ref_frame,
int list,
int block_x,
int block_y,
int blockshape_x,
int blockshape_y)
{
int mb_x = 4*block_x;
int mb_y = 4*block_y;
int mb_nr = img->current_mb_nr;
int mv_a, mv_b, mv_c, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
PixelPos block_a, block_b, block_c, block_d;
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, 0, &block_a);
getLuma4x4Neighbour(mb_nr, block_x, block_y, 0, -1, &block_b);
getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, -1, &block_d);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_c.available = 0;
else block_c.available &= 1;
}
else
{
if (mb_x+blockshape_x != 8) block_c.available &= 1;
else block_c.available = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_c.available &= 1;
else block_c.available = 0;
}
}
if (!block_c.available)
{
block_c=block_d;
}
mvPredType = MVPRED_MEDIAN;
if (!img->MbaffFrameFlag)
{
rFrameL = block_a.available ? refPic[list][block_a.pos_x][block_a.pos_y] : -1;
rFrameU = block_b.available ? refPic[list][block_b.pos_x][block_b.pos_y] : -1;
rFrameUR = block_c.available ? refPic[list][block_c.pos_x][block_c.pos_y] : -1;
}
else
{
if (img->mb_data[img->current_mb_nr].mb_field)
{
rFrameL = block_a.available ?
img->mb_data[block_a.mb_addr].mb_field ?
refPic[list][block_a.pos_x][block_a.pos_y]:
refPic[list][block_a.pos_x][block_a.pos_y] * 2:
-1;
rFrameU = block_b.available ?
img->mb_data[block_b.mb_addr].mb_field ?
refPic[list][block_b.pos_x][block_b.pos_y]:
refPic[list][block_b.pos_x][block_b.pos_y] * 2:
-1;
rFrameUR = block_c.available ?
img->mb_data[block_c.mb_addr].mb_field ?
refPic[list][block_c.pos_x][block_c.pos_y]:
refPic[list][block_c.pos_x][block_c.pos_y] * 2:
-1;
}
else
{
rFrameL = block_a.available ?
img->mb_data[block_a.mb_addr].mb_field ?
refPic[list][block_a.pos_x][block_a.pos_y] >>1:
refPic[list][block_a.pos_x][block_a.pos_y] :
-1;
rFrameU = block_b.available ?
img->mb_data[block_b.mb_addr].mb_field ?
refPic[list][block_b.pos_x][block_b.pos_y] >>1:
refPic[list][block_b.pos_x][block_b.pos_y] :
-1;
rFrameUR = block_c.available ?
img->mb_data[block_c.mb_addr].mb_field ?
refPic[list][block_c.pos_x][block_c.pos_y] >>1:
refPic[list][block_c.pos_x][block_c.pos_y] :
-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;
}
}
for (hv=0; hv < 2; hv++)
{
if (!img->MbaffFrameFlag || hv==0)
{
mv_a = block_a.available ? tmp_mv[list][block_a.pos_x][block_a.pos_y][hv] : 0;
mv_b = block_b.available ? tmp_mv[list][block_b.pos_x][block_b.pos_y][hv] : 0;
mv_c = block_c.available ? tmp_mv[list][block_c.pos_x][block_c.pos_y][hv] : 0;
}
else
{
if (img->mb_data[img->current_mb_nr].mb_field)
{
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
tmp_mv[list][block_a.pos_x][block_a.pos_y][hv]:
tmp_mv[list][block_a.pos_x][block_a.pos_y][hv] / 2:
0;
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
tmp_mv[list][block_b.pos_x][block_b.pos_y][hv]:
tmp_mv[list][block_b.pos_x][block_b.pos_y][hv] / 2:
0;
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
tmp_mv[list][block_c.pos_x][block_c.pos_y][hv]:
tmp_mv[list][block_c.pos_x][block_c.pos_y][hv] / 2:
0;
}
else
{
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
tmp_mv[list][block_a.pos_x][block_a.pos_y][hv] * 2:
tmp_mv[list][block_a.pos_x][block_a.pos_y][hv]:
0;
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
tmp_mv[list][block_b.pos_x][block_b.pos_y][hv] * 2:
tmp_mv[list][block_b.pos_x][block_b.pos_y][hv]:
0;
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
tmp_mv[list][block_c.pos_x][block_c.pos_y][hv] * 2:
tmp_mv[list][block_c.pos_x][block_c.pos_y][hv]:
0;
}
}
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_b.available || block_c.available))
pred_vec = mv_a;
else
pred_vec = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(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;
}
}
/*!
************************************************************************
* \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 = input->InterlaceCodingOption?2*img->buf_cycle: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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -