📄 me_epzs.c
字号:
? img->mb_data[block_b.mb_addr].mb_field
? (int) refPic[block_b.pos_y][block_b.pos_x] >> 1
: (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
refC = block_c.available
? img->mb_data[block_c.mb_addr].mb_field
? (int) refPic[block_c.pos_y][block_c.pos_x] >> 1
: (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
refD = block_d.available
? img->mb_data[block_d.mb_addr].mb_field
? (int) refPic[block_d.pos_y][block_d.pos_x] >> 1
: (int) refPic[block_d.pos_y][block_d.pos_x] : -1;
// Left Predictor
predictor->point[1].motion.mv_x = (block_a.available)
? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0]), sp_shift_mv) : fixed_mv;
predictor->point[1].motion.mv_y = (block_a.available)
? img->mb_data[block_a.mb_addr].mb_field
? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv - 1)
: rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv) : 0;
// Up predictor
predictor->point[2].motion.mv_x = (block_b.available)
? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0]), sp_shift_mv) : 0;
predictor->point[2].motion.mv_y = (block_b.available)
? img->mb_data[block_b.mb_addr].mb_field
? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv - 1)
: rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv) : fixed_mv;
// Up-Right predictor
predictor->point[3].motion.mv_x = (block_c.available)
? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0]), sp_shift_mv) : -fixed_mv;
predictor->point[3].motion.mv_y = (block_c.available)
? img->mb_data[block_c.mb_addr].mb_field
? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv - 1)
: rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv) : 0;
//Up-Left predictor
predictor->point[4].motion.mv_x = (block_d.available)
? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0]), sp_shift_mv) : 0;
predictor->point[4].motion.mv_y = (block_d.available)
? img->mb_data[block_d.mb_addr].mb_field
? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv - 1)
: rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv) : -fixed_mv;
}
}
return ((refA == -1) + (refB == -1) + (refC == -1 && refD == -1));
}
/*!
***********************************************************************
* \brief
* Spatial Predictors
* AMT/HYC
***********************************************************************
*/
static void EPZSSpatialMemPredictors (int list,
short ref,
int blocktype,
int pic_x,
int bs_x,
int bs_y,
int by,
int *prednum,
int img_width,
EPZSStructure * predictor)
{
#if EPZSREF
short ***mv = EPZSMotion[list][ref][blocktype];
//MotionVector ***prd_mv = &EPZS_Motion[list][ref][blocktype];
MotionVector *cur_mv = &predictor->point[*prednum].motion;
// Left Predictor
if (pic_x > 0)
{
cur_mv->mv_x = mv[by][pic_x - bs_x][0];
cur_mv->mv_y = mv[by][pic_x - bs_x][1];
*prednum += (*((int*) cur_mv) != 0);
cur_mv = &predictor->point[*prednum].motion;
}
by = (by > 0) ? by - bs_y: 4 - bs_y;
// Up predictor
cur_mv->mv_x = mv[by][pic_x][0];
cur_mv->mv_y = mv[by][pic_x][1];
*prednum += (*((int*) cur_mv) != 0);
// Up-Right predictor
if (pic_x + bs_x < img_width)
{
cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = mv[by][pic_x + bs_x][0];
cur_mv->mv_y = mv[by][pic_x + bs_x][1];
*prednum += (*((int*) cur_mv) != 0);
}
#else
int mot_scale = mv_scale[list][ref][0];
short **mv = EPZSMotion[list][blocktype];
MotionVector **predictor = &EPZS_Motion[list][blocktype];
// Left Predictor
predictor->point[*prednum].motion.mv_x = (pic_x > 0)
? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][0]), 8)
: 0;
predictor->point[*prednum].motion.mv_y = (pic_x > 0)
? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][1]), 8)
: 0;
*prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
// Up predictor
predictor->point[*prednum].motion.mv_x = (by > 0)
? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][0]), 8)
: rshift_rnd_sf((mot_scale * mv[4 - bs_y][pic_x][0]), 8);
predictor->point[*prednum].motion.mv_y = (by > 0)
? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][1]), 8)
: rshift_rnd_sf((mot_scale * mv[4 - bs_y][pic_x][1]), 8);
*prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
// Up-Right predictor
predictor->point[*prednum].motion.mv_x = (pic_x + bs_x < img_width)
? (by > 0)
? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][0]), 8)
: rshift_rnd_sf((mot_scale * mv[4 - bs_y][pic_x + bs_x][0]), 8)
: 0;
predictor->point[*prednum].motion.mv_y = (pic_x + bs_x < img_width)
? (by > 0)
? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][1]), 8)
: rshift_rnd_sf((mot_scale * mv[4 - bs_y][pic_x + bs_x][1]), 8)
: 0;
*prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
#endif
}
/*!
***********************************************************************
* \brief
* Temporal Predictors
* AMT/HYC
***********************************************************************
*/
static void
EPZSTemporalPredictors (int list, // <-- current list
int list_offset, // <-- list offset for MBAFF
short ref, // <-- current reference frame
int o_block_x, // <-- absolute x-coordinate of regarded AxB block
int o_block_y, // <-- absolute y-coordinate of regarded AxB block
EPZSStructure * predictor,
int *prednum,
int block_available_left,
int block_available_up,
int block_available_right,
int block_available_below,
int blockshape_x,
int blockshape_y,
int stopCriterion,
int min_mcost)
{
int mvScale = mv_scale[list + list_offset][ref][0];
MotionVector **col_mv = (list_offset == 0) ? EPZSCo_located->frame[list]
: (list_offset == 2) ? EPZSCo_located->top[list] : EPZSCo_located->bot[list];
short temp_shift_mv = 8 + mv_rescale; // 16 - invmv_precision + mv_rescale
MotionVector *cur_mv = &predictor->point[*prednum].motion;
*prednum += add_predictor(cur_mv, col_mv[o_block_y][o_block_x], mvScale, temp_shift_mv);
if (min_mcost > stopCriterion && ref < 2)
{
if (block_available_left)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, temp_shift_mv);
//Up_Left
if (block_available_up)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, temp_shift_mv);
}
//Down_Left
if (block_available_below)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, temp_shift_mv);
}
}
// Up
if (block_available_up)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, temp_shift_mv);
}
// Up - Right
if (block_available_right)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
if (block_available_up)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, temp_shift_mv);
}
if (block_available_below)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
}
}
if (block_available_below)
{
*prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, temp_shift_mv);
}
}
}
/*!
************************************************************************
* \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[list];
short block_shift_mv = 8 + mv_rescale;
MotionVector *cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][0]), mv_rescale);
cur_mv->mv_y = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][1]), mv_rescale);
//*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
*prednum += (*((int*) cur_mv) != 0);
if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
{
cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][0]), block_shift_mv );
cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][1]), block_shift_mv );
//*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
*prednum += (*((int*) cur_mv) != 0);
cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][0]), block_shift_mv );
cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][1]), block_shift_mv );
//*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
*prednum += (*((int*) cur_mv) != 0);
}
if (blocktype != 1)
{
cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = rshift_rnd((all_mv[ref][1][block_y][block_x][0]), mv_rescale);
cur_mv->mv_y = rshift_rnd((all_mv[ref][1][block_y][block_x][1]), mv_rescale);
//*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
*prednum += (*((int*) cur_mv) != 0);
}
if (blocktype != 4)
{
cur_mv = &predictor->point[*prednum].motion;
cur_mv->mv_x = rshift_rnd((all_mv[ref][4][block_y][block_x][0]), mv_rescale);
cur_mv->mv_y = rshift_rnd((all_mv[ref][4][block_y][block_x][1]), mv_rescale);
//*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
*prednum += (*((int*) cur_mv) != 0);
}
}
/*!
************************************************************************
* \brief
* EPZS Window Based Predictors
************************************************************************
*/
static void EPZSWindowPredictors (short mv[2], EPZSStructure *predictor, int *prednum, int extended)
{
int pos;
EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;
SPoint *wPoint = &windowPred->point[0];
SPoint *pPoint = &predictor->point[(*prednum)];
for (pos = 0; pos < windowPred->searchPoints; pos++)
{
(pPoint )->motion.mv_x = mv[0] + (wPoint )->motion.mv_x;
(pPoint++)->motion.mv_y = mv[1] + (wPoint++)->motion.mv_y;
}
*prednum += windowPred->searchPoints;
}
/*!
***********************************************************************
* \brief
* FAST Motion Estimation using EPZS
* AMT/HYC
***********************************************************************
*/
int // ==> minimum motion cost after search
EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock
imgpel * 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[2], // <-- motion vector predictor in sub-pel units
short mv[2], // <--> in: search center (x|y) / out: motion vector (x|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
int apply_weights) // <-- perform weight based ME
{
StorablePicture *ref_picture = listX[list+list_offset][ref];
short blocksize_y = params->blc_size[blocktype][1]; // vertical block size
short blocksize_x = params->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->opi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -