📄 fast_me.c
字号:
}
else if (img->pix_y == 0)
{
flag_intra_SAD = flag_intra[((img->pix_x)>>4)-1];
}
else
{
flag_intra_SAD = ((flag_intra[(img->pix_x)>>4])||(flag_intra[((img->pix_x)>>4)-1])||(flag_intra[((img->pix_x)>>4)+1])) ;
}
}
return;
}
void skip_intrabk_SAD(int best_mode, int ref_max)
{
int i,j,k, ref;
if (img->number > 0)
flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1:0;
if (img->type!=0 && (best_mode == 9 || best_mode == 10))
{
for (i=0; i < 4; i++)
{
for (j=0; j < 4; j++)
{
for (k=1; k < 8;k++)
{
for (ref=0; ref<ref_max;ref++)
{
all_mincost[(img->pix_x>>2)+i][(img->pix_y>>2)+j][ref][k][0] = 0;
}
}
}
}
}
return;
}
int // ==> minimum motion cost after search
FME_BlockMotionSearch_bid (int ref, // <-- reference frame (0... or -1 (backward))
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)
int search_range, // <-- 1-d search range for integer-position search
double lambda // <-- lagrangian parameter for determining motion cost
)
{
static pel_t orig_val [256];
static pel_t *orig_pic [16] = {orig_val, orig_val+ 16, orig_val+ 32, orig_val+ 48,
orig_val+ 64, orig_val+ 80, orig_val+ 96, orig_val+112,
orig_val+128, orig_val+144, orig_val+160, orig_val+176,
orig_val+192, orig_val+208, orig_val+224, orig_val+240};
int pred_mv_x, pred_mv_y, mv_x, mv_y, i, j;
int max_value = (1<<20);
int min_mcost = max_value;
int mb_x = pic_pix_x-img->pix_x;
int mb_y = pic_pix_y-img->pix_y;
int bsx = input->blc_size[blocktype][0];
int bsy = input->blc_size[blocktype][1];
int refframe = (ref==-1 ? 0 : ref);
int* pred_mv;
int** ref_array = ((img->type!=B_IMG /*&& img->type!=BS_IMG*/) ? refFrArr : ref>=0 ? fw_refFrArr : bw_refFrArr);
int*** mv_array = ((img->type!=B_IMG /*&& img->type!=BS_IMG*/) ? tmp_mv : ref>=0 ? tmp_fwMV : tmp_bwMV);
int***** all_bmv = img->all_bmv;
int***** all_mv = (ref==-1 ? img->all_bmv : img->all_omv);//lgp
byte** imgY_org_pic = imgY_org;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
int N_Bframe = input->successive_Bframe, n_Bframe =(N_Bframe) ? ((Bframe_ctr%N_Bframe) ? Bframe_ctr%N_Bframe : N_Bframe) : 0 ;
int incr_y=1,off_y=0;/*lgp*/
int b8_x = (mb_x>>3);/*lgp*/
int b8_y = (mb_y>>3);/*lgp*/
int center_x = pic_pix_x;/*lgp*/
int center_y = pic_pix_y;/*lgp*/
int MaxMVHRange,MaxMVVRange;
int blocksize_y = input->blc_size[blocktype][1]; // vertical block size
int blocksize_x = input->blc_size[blocktype][0];
int temp_x,temp_y;
#ifdef TimerCal
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
#endif
if (!img->picture_structure) // field coding
{
if (img->type==B_IMG)
refframe = ref<0 ? ref+2 : ref; // Yulj 2004.07.15
}
pred_mv = ((img->type!=B_IMG) ? img->mv : ref>=0 ? img->omv/*img->p_fwMV*/ : img->p_bwMV)[mb_x>>3][mb_y>>3][refframe][blocktype];
//==================================
//===== GET ORIGINAL BLOCK =====
//==================================
for (j = 0; j < bsy; j++)
{
for (i = 0; i < bsx; i++)
{
orig_pic[j][i] = imgY_org_pic[pic_pix_y+/*j*/incr_y*j+off_y/*lgp*/][pic_pix_x+i];
// orig_pic[j][i] = imgY_org_pic[pic_pix_y+j][pic_pix_x+i];
}
}
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
if(blocktype>6)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][5][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][5][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][5][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype>4)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][4][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][4][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][4][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype == 4)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][2][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][2][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][2][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype > 1)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][1][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][1][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][1][0]);
pred_SAD_uplayer /= 2;
}
pred_SAD_uplayer = flag_intra_SAD ? 0 : pred_SAD_uplayer;// for irregular motion
//coordinate prediction
if (img->number > refframe+1)
{
pred_SAD_time = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][0];
pred_MV_time[0] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][1];
pred_MV_time[1] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][2];
}
if (ref == -1 && Bframe_ctr > 1)
{
pred_SAD_time = all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][0];
pred_MV_time[0] = (int)(all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][1] * ((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
pred_MV_time[1] = (int)(all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][2] *((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
}
{
if (refframe > 0)
{//field_mode top_field
pred_SAD_ref = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][0];
pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
pred_MV_ref[0] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][1];
pred_MV_ref[0] = (int)(pred_MV_ref[0]*(refframe+1)/(float)(refframe));
pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][2];
pred_MV_ref[1] = (int)(pred_MV_ref[1]*(refframe+1)/(float)(refframe));
}
if (img->type == B_IMG && ref == 0)
{
pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][0];
pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
pred_MV_ref[0] =(int) (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); //should add a factor
pred_MV_ref[1] =(int) ( all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
}
//===========================================
//===== GET MOTION VECTOR PREDICTOR =====
//===========================================
FME_SetMotionVectorPredictor (pred_mv, ref_array, mv_array, refframe, mb_x, mb_y, bsx, bsy, blocktype, ref);
pred_mv_x = pred_mv[0];
pred_mv_y = pred_mv[1];
#ifdef TimerCal
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
#endif
//==================================
//===== INTEGER-PEL SEARCH =====
//==================================
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
mv_x = pred_mv_x / 4;
mv_y = pred_mv_y / 4;
if (!input->rdopt)
{
//--- adjust search center so that the (0,0)-vector is inside ---
mv_x = max (-search_range, min (search_range, mv_x));
mv_y = max (-search_range, min (search_range, mv_y));
}
min_mcost = FastIntegerPelBlockMotionSearch(orig_pic, ref, center_x/*lgp*/, center_y/*lgp*/,/*pic_pix_x, pic_pix_y,*/ blocktype,
pred_mv_x, pred_mv_y, &mv_x, &mv_y, search_range,
min_mcost, lambda);
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
for (i=0; i < (bsx>>2); i++)
{
for (j=0; j < (bsy>>2); j++)
{
if (ref > -1)
all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][0] = min_mcost;
else
all_bwmincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][0][blocktype][0] = min_mcost;
}
}
#ifdef TimerCal
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2 - QPart1);
dfTim = dfMinus / dfFreq;
integer_time=integer_time + dfTim;//tmp_time;
#endif
//==============================
//===== SUB-PEL SEARCH =====
//==============================
if (input->hadamard)
{
min_mcost = max_value;
}
#ifdef TimerCal
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
#endif
if(blocktype >3)
{
min_mcost = FastSubPelBlockMotionSearch_bid (orig_pic, ref, center_x, center_y, blocktype,
pred_mv_x, pred_mv_y, &mv_x, &mv_y, 9, 9,min_mcost, lambda, 0);
}
else
min_mcost = SubPelBlockMotionSearch_bid (orig_pic, ref, center_x/*lgp*/, center_y/*lgp*/, blocktype,
pred_mv_x, pred_mv_y, &mv_x, &mv_y, 9, 9, min_mcost, lambda);
for (i=0; i < (bsx>>2); i++)
{
for (j=0; j < (bsy>>2); j++)
{
if (ref > -1)
{
all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][1] = mv_x;
all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][2] = mv_y;
}
else
{
all_bwmincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][0][blocktype][1] = mv_x;
all_bwmincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][0][blocktype][2] = mv_y;
}
}
}
#ifdef TimerCal
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2 - QPart1);
dfTim = dfMinus / dfFreq;
fractional_time=fractional_time + dfTim;
#endif
if (!input->rdopt)
{
// Get the skip mode cost
if (blocktype == 1 && img->type == INTER_IMG)
{
int cost;
FindSkipModeMotionVector ();
cost = GetSkipCostMB (lambda);
cost -= (int)floor(8*lambda+0.4999);
if (cost < min_mcost)
{
min_mcost = cost;
mv_x = img->all_mv [0][0][0][0][0];
mv_y = img->all_mv [0][0][0][0][1];
}
}
}
temp_x = 4*pic_pix_x + pred_mv_x+mv_x; //add by wuzhongmou 200612
temp_y = 4*pic_pix_y + pred_mv_y+mv_y; //add by wuzhongmou 200612
if(temp_x<=-64) //add by wuzhongmou 200612
{
mv_x=-63-4*pic_pix_x-pred_mv_x;
}
if(temp_x >= 4*(img->width -1-blocksize_x+16))
{
mv_x=4*(img->width -1-blocksize_x+15-pic_pix_x)-pred_mv_x;
}
if(temp_y <=-64)
{
mv_y=-63-4*pic_pix_y-pred_mv_y;
}
if(temp_y >= 4*(img->height-1-blocksize_y+16))
{
mv_y=4*(img->height -1-blocksize_y+15-pic_pix_y)-pred_mv_y;
}
MaxMVHRange= MAX_H_SEARCH_RANGE; //add by wuzhongmou
MaxMVVRange= MAX_V_SEARCH_RANGE;
if(!img->picture_structure) //field coding
{
MaxMVVRange=MAX_V_SEARCH_RANGE_FIELD;
}
if(mv_x < -MaxMVHRange )
mv_x = -MaxMVHRange;
if( mv_x> MaxMVHRange-1)
mv_x=MaxMVHRange-1;
if( mv_y < -MaxMVVRange)
mv_y = -MaxMVVRange;
if( mv_y > MaxMVVRange-1)
mv_y = MaxMVVRange-1; // add by wuzhongmou
//===============================================
//===== SET MV'S AND RETURN MOTION COST =====
//===============================================
/*lgp*/
for (i=0; i < (bsx>>3); i++)
{
for (j=0; j < (bsy>>3); j++)
{
all_mv[b8_x+i][b8_y+j][refframe][blocktype][0] = mv_x;
all_mv[b8_x+i][b8_y+j][refframe][blocktype][1] = mv_y;
}
}
return min_mcost;
}
int // ==> minimum motion cost after search
FastSubPelBlockMotionSearch_bid (pel_t** orig_pic, // <-- original pixel values for the AxB block
int ref, // <-- reference frame (0... or -1 (backward))
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)
int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
int* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
int* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
int search_pos2, // <-- search positions for half-pel search (default: 9)
int search_pos4, // <-- search positions for quarter-pel search (default: 9)
int min_mcost, // <-- minimum motio
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -