📄 epzs.c
字号:
predictor->point[*prednum].y = (mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][1] + 2048) >> 12;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
if (block_available_below)
{
predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][0] + 2048) >> 12;
predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][1] + 2048) >> 12;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
}
if (block_available_below)
{
predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][0] + 2048) >> 12;
predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][1] + 2048) >> 12;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
}
}
/*!
************************************************************************
* \brief
* EPZS Block Type Predictors
************************************************************************
*/
static void EPZSBlockTypePredictors (int block_x, int block_y, int blocktype, int ref, int list,
EPZSStructure * predictor, int *prednum)
{
short ***all_mv = img->all_mv[block_y][block_x][list];
if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
{
predictor->point[*prednum].x = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][0] + 512) >> 10;
predictor->point[*prednum].y = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][1] + 512) >> 10;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
predictor->point[*prednum].x = (mv_scale[list][ref][0] * all_mv[0][blocktype][0] + 512) >> 10;
predictor->point[*prednum].y = (mv_scale[list][ref][0] * all_mv[0][blocktype][1] + 512) >> 10;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
predictor->point[*prednum].x = (all_mv[ref][blk_parent[blocktype]][0] + 2) >> 2;
predictor->point[*prednum].y = (all_mv[ref][blk_parent[blocktype]][1] + 2) >> 2;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
if (blocktype != 1)
{
predictor->point[*prednum].x = (all_mv[ref][1][0] + 2) >> 2;
predictor->point[*prednum].y = (all_mv[ref][1][1] + 2) >> 2;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
if (blocktype != 4)
{
predictor->point[*prednum].x = (all_mv[ref][4][0] + 2) >> 2;
predictor->point[*prednum].y = (all_mv[ref][4][1] + 2) >> 2;
*prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
}
}
/*!
************************************************************************
* \brief
* EPZS Window Based Predictors
************************************************************************
*/
static void EPZSWindowPredictors (int mv_x, int mv_y, EPZSStructure *predictor, int *prednum, int extended)
{
int pos;
EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;
for (pos = 0; pos < windowPred->searchPoints; pos++)
{
predictor->point[(*prednum) ].x = mv_x + windowPred->point[pos].x;
predictor->point[(*prednum)++].y = mv_y + windowPred->point[pos].y;
}
}
/*!
************************************************************************
* \brief
* SAD computation
************************************************************************
*/
static int computeSad(pel_t** cur_pic,
int blocksize_y,
int blocksize_x,
int blockshape_x,
int mcost,
int min_mcost,
int cand_x,
int cand_y)
{
int y,x4;
pel_t *cur_line, *ref_line;
for (y=0; y<blocksize_y; y++)
{
ref_line = get_ref_line (blocksize_x, ref_pic, cand_y + y, cand_x, img_height, img_width);
cur_line = cur_pic [y];
for (x4 = 0; x4 < blockshape_x; x4++)
{
mcost += byte_abs[ *cur_line++ - *ref_line++ ];
mcost += byte_abs[ *cur_line++ - *ref_line++ ];
mcost += byte_abs[ *cur_line++ - *ref_line++ ];
mcost += byte_abs[ *cur_line++ - *ref_line++ ];
//mcost += abs( *cur_line++ - *ref_line++ );
//mcost += abs( *cur_line++ - *ref_line++ );
//mcost += abs( *cur_line++ - *ref_line++ );
//mcost += abs( *cur_line++ - *ref_line++ );
}
if (mcost >= min_mcost) break;
}
return mcost;
}
/*!
************************************************************************
* \brief
* BiPred SAD computation (no weights)
************************************************************************
*/
static int computeBiPredSad1(pel_t** cur_pic,
int blocksize_y,
int blocksize_x,
int blockshape_x,
int mcost,
int min_mcost,
int cand_x1, int cand_y1,
int cand_x2, int cand_y2)
{
pel_t *cur_line, *ref1_line, *ref2_line;
int bi_diff;
int y,x4;
for (y = 0; y < blocksize_y; y++)
{
ref2_line = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
ref1_line = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
cur_line = cur_pic [y];
for (x4 = 0; x4 < blockshape_x; x4++)
{
bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
mcost += byte_abs[bi_diff];
bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
mcost += byte_abs[bi_diff];
bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
mcost += byte_abs[bi_diff];
bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
mcost += byte_abs[bi_diff];
}
if (mcost >= min_mcost) break;
}
return mcost;
}
/*!
************************************************************************
* \brief
* BiPred SAD computation (with weights)
************************************************************************
*/
static int computeBiPredSad2(pel_t** cur_pic,
int blocksize_y,
int blocksize_x,
int blockshape_x,
int mcost,
int min_mcost,
int cand_x1, int cand_y1,
int cand_x2, int cand_y2)
{
pel_t *cur_line, *ref1_line, *ref2_line;
int bi_diff;
int denom = luma_log_weight_denom + 1;
int lround = 2 * wp_luma_round;
int y,x4;
int weightedpel, pixel1, pixel2;
for (y=0; y<blocksize_y; y++)
{
ref2_line = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
ref1_line = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
cur_line = cur_pic [y];
for (x4 = 0; x4 < blockshape_x; x4++)
{
pixel1 = weight1 * (*ref1_line++);
pixel2 = weight2 * (*ref2_line++);
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weight1 * (*ref1_line++);
pixel2 = weight2 * (*ref2_line++);
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weight1 * (*ref1_line++);
pixel2 = weight2 * (*ref2_line++);
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weight1 * (*ref1_line++);
pixel2 = weight2 * (*ref2_line++);
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
if (mcost >= min_mcost) break;
}
if (mcost >= min_mcost) break;
}
return mcost;
}
/*!
***********************************************************************
* \brief
* FAST Motion Estimation using EPZS
* AMT/HYC
***********************************************************************
*/
int // ==> minimum motion cost after search
EPZSPelBlockMotionSearch (pel_t ** cur_pic, // <-- original pixel values for the AxB block
short ref, // <-- reference picture
int list, // <-- reference list
int list_offset, // <-- offset for Mbaff
char ***refPic, // <-- reference array
short ****tmp_mv, // <-- mv array
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)
short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
short *mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
short *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)
int lambda_factor) // <-- lagrangian parameter for determining motion cost
{
StorablePicture *ref_picture = listX[list+list_offset][ref];
short blocksize_y = input->blc_size[blocktype][1]; // vertical block size
short blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
short blockshape_x = (blocksize_x >> 2); // horizontal block size in 4-pel units
short blockshape_y = (blocksize_y >> 2); // vertical block size in 4-pel units
short mb_x = pic_pix_x - img->opix_x;
short mb_y = pic_pix_y - img->opix_y;
short pic_pix_x2 = pic_pix_x >> 2;
short pic_pix_y2 = pic_pix_y >> 2;
short block_x = (mb_x >> 2);
short block_y = (mb_y >> 2);
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 cand_x = center_x;
int cand_y = center_y;
int tempmv_x = *mv_x, tempmv_y = *mv_y;
int tempmv_x2 = 0, tempmv_y2 = 0;
int stopCriterion = medthres[blocktype];
int mapCenter_x = search_range - *mv_x;
int mapCenter_y = search_range - *mv_y;
int second_mcost = INT_MAX;
short apply_weights = (active_pps->weighted_pred_flag > 0 || active_pps->weighted_bipred_idc == 1);
int *prevSad = EPZSDistortion[list + list_offset][blocktype - 1];
short *motion=NULL;
short invalid_refs = 0;
byte checkMedian = FALSE;
EPZSStructure *searchPatternF = searchPattern;
ref_pic = (apply_weights && input->UseWeightedReferenceME) ? ref_picture->imgY_11_w : ref_picture->imgY_11;
if (input->EPZSSpatialMem)
{
#if EPZSREF
motion = EPZSMotion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2];
#else
motion = EPZSMotion[list + list_offset][blocktype - 1][block_y][pic_pix_x2];
#endif
}
img_width = ref_picture->size_x;
img_height = ref_picture->size_y;
//===== set function for getting reference picture lines =====
get_ref_line = CHECK_RANGE ? FastLineX : UMVLineX;
// Clear EPZSMap
memset(EPZSMap[0],FALSE,(2*search_range+1)*(2*search_range+1));
// Check median candidate;
EPZSMap[search_range][search_range] = TRUE;
//--- initialize motion cost (cost for motion vector) and check ---
min_mcost = MV_COST (lambda_factor, 2, cand_x, cand_y, pred_x, pred_y);
//--- add residual cost to motion cost ---
min_mcost = computeSad(cur_pic, blocksize_y,blocksize_x,
blockshape_x,min_mcost, INT_MAX, cand_x,cand_y);
// Additional threshold for ref>0
if ((ref>0 && img->structure == FRAME)
&& (prevSad[pic_pix_x2] < medthres[blocktype])
&& (prevSad[pic_pix_x2] < min_mcost))
{
return min_mcost;
}
if ((center_x > search_range) && (center_x < img_width - search_range - blocksize_x) &&
(center_y > search_range) && (center_y < img_height - search_range - blocksize_y) )
get_ref_line = FastLineX;
else
get_ref_line = UMVLineX;
//! If medthres satisfied, then terminate, otherwise generate Predictors
//! Condition could be strengthened by consideration distortion of adjacent partitions.
if (min_mcost > stopCriterion)
{
int mb_available_right = (img->mb_x < (img_width >> 4) - 1);
int mb_available_below = (img->mb_y < (img_height >> 4) - 1);
int sadA, sadB, sadC;
int block_available_right;
int block_available_below;
int prednum = 5;
int patternStop = 0, pointNumber = 0, checkPts;
int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -