📄 block.cpp
字号:
if(current_inter_sad < MinCost)
{
img->mb_mode=3;
img->imod=INTRA_MB_INTER;
for(i=0;i<4;i++)
{
tmp_mv[pic_block_y+i][pic_block_x+2][0]=curr_mvx2[0];
tmp_mv[pic_block_y+i][pic_block_x+2][1]=curr_mvy2[0];
tmp_mv[pic_block_y+i][pic_block_x+3][0]=curr_mvx2[0];
tmp_mv[pic_block_y+i][pic_block_x+3][1]=curr_mvy2[0];
tmp_mv[pic_block_y+i][pic_block_x+4][0]=curr_mvx2[1];
tmp_mv[pic_block_y+i][pic_block_x+4][1]=curr_mvy2[1];
tmp_mv[pic_block_y+i][pic_block_x+5][0]=curr_mvx2[1];
tmp_mv[pic_block_y+i][pic_block_x+5][1]=curr_mvy2[1];
intra_mb_pos[pic_block_y+i][pic_block_x+2] = 0;
intra_mb_pos[pic_block_y+i][pic_block_x+3] = 0;
intra_mb_pos[pic_block_y+i][pic_block_x+4] = 0;
intra_mb_pos[pic_block_y+i][pic_block_x+5] = 0;
}
MinCost = current_inter_sad;
}
return MinCost;
}
int motion_search(struct img_par *img,int tot_intra_sad)
{
int i;
int vec0_x,vec0_y,vec1_x,vec1_y,vec2_x,vec2_y;
int pic_block_x,pic_block_y,pic_pix_y,pic_pix_x;
int ip0,ip1,ip2,ip3,ip4,ip5;
int best_inter_sad,current_inter_sad,skip_sad=65536,skip_offset;
int tmp0,tmp1;
int lambda = QP2QUANT[img->qp-SHIFT_QP];
int x,y,offset,type,pos,skipcomp;
byte* curr;
byte* prev;
Point* point=search;
SAD_TABLE * sadTbl=sadTable;
int maxX=img->width-12;
int maxY=img->height-12;
int sadTimes=25;
int mvx0=0,mvy0=0,mvx1,mvy1;
int x_curr,y_curr;
int width=img->width+IMG_PAD_SIZE;
#ifdef FAST_INTEGER
int prev_AE1[17];
int prev_m1,prev_m2=0;
static int prevm[4] = {2, 3, 0, 1};
static int htp[4] = {-1, 0, 1, 0};
static int vtp[4] = {0, 1, 0, -1};
int j_min_now, i_min_now,i_min_next=0, j_min_next=0, Coffset,sad_layr,ioffset=0,l,m,j;
int distortion_0, distortion_1, distortion_2;
#endif
pic_block_y=img->block_y;
pic_pix_y=img->pix_y;
pic_block_x=img->block_x;
pic_pix_x=img->pix_x;
x_curr=pic_pix_x;
y_curr=pic_pix_y;
vec0_x=pic_block_x-1; /*left block*/
vec0_y=pic_block_y;
vec1_x=pic_block_x;
vec1_y=pic_block_y-1; /*up block*/
vec2_x=pic_block_x+4;
vec2_y=pic_block_y-1; /*upright block*/
if (pic_block_y == 0) /*current block has no up blocks, reset refference block*/
{
vec1_x=vec0_x;
vec2_x=vec0_x;
vec1_y=vec0_y;
vec2_y=vec0_y;
}
if (vec2_x > (img->width>>2)-1) /*current block has no upright block,reset refference block*/
{
vec2_x=pic_block_x-1;
}
ip0=tmp_mv[vec0_y][vec0_x+4][0];
ip1=tmp_mv[vec1_y][vec1_x+4][0];
ip2=tmp_mv[vec2_y][vec2_x+4][0];
ip3=tmp_mv[vec0_y][vec0_x+4][1];
ip4=tmp_mv[vec1_y][vec1_x+4][1];
ip5=tmp_mv[vec2_y][vec2_x+4][1];
if((!intra_mb_pos[vec0_y][vec0_x+4])&&(intra_mb_pos[vec1_y][vec1_x+4])&&(intra_mb_pos[vec2_y][vec2_x+4]))
{
img->mv[0] = ip0;
img->mv[1] = ip3;
}
else if((intra_mb_pos[vec0_y][vec0_x+4])&&(!intra_mb_pos[vec1_y][vec1_x+4])&&(intra_mb_pos[vec2_y][vec2_x+4]))
{
img->mv[0] = ip1;
img->mv[1] = ip4;
}
else if((intra_mb_pos[vec0_y][vec0_x+4])&&(intra_mb_pos[vec1_y][vec1_x+4])&&(!intra_mb_pos[vec2_y][vec2_x+4]))
{
img->mv[0] = ip2;
img->mv[1] = ip5;
}
else
{
img->mv[0]=ip0+ip1+ip2-min(min(ip0,ip1),ip2)-max(max(ip0,ip1),ip2);
img->mv[1]=ip3+ip4+ip5-min(min(ip3,ip4),ip5)-max(max(ip3,ip4),ip5);
}
ip0=img->mv[0];
ip1=img->mv[1];
//by guoxq
if(pic_pix_y==0 || pic_pix_x==0)
{
skip_mv[0]=0;
skip_mv[1]=0;
}
else if(tmp_mv[vec0_y][vec0_x+4][0]==0 && tmp_mv[vec0_y][vec0_x+4][1]==0 && (!intra_mb_pos[vec0_y][vec0_x+4]))
{
skip_mv[0]=0;
skip_mv[1]=0;
}
else if(tmp_mv[vec1_y][vec1_x+4][0]==0 && tmp_mv[vec1_y][vec1_x+4][1]==0 && (!intra_mb_pos[vec1_y][vec1_x+4]))
{
skip_mv[0]=0;
skip_mv[1]=0;
}
else
{
skip_mv[0]=ip0;
skip_mv[1]=ip1;
}
img->bSkipMode=0;
offset=width*pic_pix_y+pic_pix_x;
curr=imgY_org + offset;
x=pic_pix_x+(skip_mv[0]>>2)+(((skip_mv[0]>>1)|skip_mv[0])&1);
y=pic_pix_y+(skip_mv[1]>>2)+(((skip_mv[1]>>1)|skip_mv[1])&1);
if((x>=-4)&&(y>=-4)&&(x<=maxX)&&(y<=maxY))//16表示模式1,16x16块
{
skipcomp=(skip_mv[1]&3)*4+(skip_mv[0]&3);
skip_offset=(pic_pix_y+(skip_mv[1]>>2))*width + pic_pix_x+(skip_mv[0]>>2);
prev=ipol[skipcomp] + skip_offset;
skip_sad=SAD_Macroblock(img,curr,prev,MAX_VALUE,0);
skip_sad -= 8*lambda;
if (skip_sad <= 10*lambda)
{
img->bSkipMode=1;
img->offset=skip_offset;
img->comp =skipcomp;
best_inter_sad=skip_sad;
curr_mvx=skip_mv[0];
curr_mvy=skip_mv[1];
img->mb_mode=1;
img->imod=INTRA_MB_INTER;
for(i=0;i<4;i++)
{
tmp_mv[pic_block_y][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=curr_mvy;
intra_mb_pos[pic_block_y][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 0;
}
return best_inter_sad;
}
}
prev=ipol[0] + offset;
tmp0=-ip0;
tmp1=-ip1;
current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
best_inter_sad = SAD_Macroblock(img,curr, prev, MAX_VALUE,current_inter_sad);
best_inter_sad -= lambda * 16;
#ifndef FAST_INTEGER
pos=0;
for (i = 1; i < sadTimes; i++)
{
sadTbl++;
x=x_curr+sadTbl->dx;
y=y_curr+sadTbl->dy;
tmp0=((mvx0+sadTbl->dx)<<2)-ip0;
tmp1=((mvy0+sadTbl->dy)<<2)-ip1;
current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
// current_inter_sad += SAD_Macroblock(img,prev+sadTbl->offset, curr, best_inter_sad,current_inter_sad);
current_inter_sad = SAD_Macroblock(img,prev+sadTbl->offset, curr, best_inter_sad,current_inter_sad);
if (current_inter_sad < best_inter_sad)
{
pos=i;
best_inter_sad = current_inter_sad;
}
}
mvx0 = sadTable[pos].dx;
mvy0 = sadTable[pos].dy;
offset+=sadTable[pos].offset;
x_curr+=mvx0;
y_curr+=mvy0;
#else
i_min_now = min(maxX,max(-4, x_curr+(ip0>>2)));
j_min_now = min(maxY,max(-4, y_curr+(ip1>>2)));
/*full pixel motion estimation*/
distortion_0 = distortion_1 = distortion_2 = 65536;
prev_AE1[0] = best_inter_sad;
prev_m1 = -1;
for (l = 1; l <= 16; l++){
sad_layr = 65536;
for (m = 0; m < 4; m++){
i = i_min_now + htp[m];
j = j_min_now + vtp[m];
Coffset = i - x_curr + (j - y_curr)*width;
if(l>2&&prev_m1 == m)
{
current_inter_sad = prev_AE1[l-2];
if (current_inter_sad < sad_layr){
sad_layr = current_inter_sad;
i_min_next = i;
j_min_next = j;
prev_m2=prevm[m];
prev_AE1[l]=current_inter_sad;
}
}
else if (i >= -4 && i <= maxX && j >= -4 && j <= maxY){
tmp0=((i - x_curr)<<2)-ip0;
tmp1=((j - y_curr)<<2)-ip1;
current_inter_sad=(lambda*(img->mv_bituse[IABS(tmp0)]+img->mv_bituse[IABS(tmp1)]));
// current_inter_sad += SAD_Macroblock(img,curr, prev+Coffset, sad_layr,current_inter_sad);
current_inter_sad = SAD_Macroblock(img,curr, prev+Coffset, sad_layr,current_inter_sad);
if (current_inter_sad < best_inter_sad){
mvx0 = i - x_curr;
mvy0 = j - y_curr;
ioffset = Coffset;
best_inter_sad = current_inter_sad ;
}
if (current_inter_sad < sad_layr){
sad_layr = current_inter_sad;
i_min_next = i;
j_min_next = j;
prev_m2 = prevm[m];
prev_AE1[l] = current_inter_sad;
}
}
}
prev_m1 = prev_m2;
i_min_now = i_min_next;
j_min_now = j_min_next;
distortion_2 = distortion_1;
distortion_1 = distortion_0;
distortion_0 = sad_layr;
if (distortion_1 <= distortion_0 && distortion_2 <= distortion_0){
break;
}
}
offset+=ioffset;
x_curr+=mvx0;
y_curr+=mvy0;
#endif
/*********************************
***** *****
***** HALF-PEL REFINEMENT *****
***** *****
*********************************/
pos=0;
for (i = 1; i < 9; i++)
{
point++;
x=x_curr+point->x;
y=y_curr+point->y;
#ifdef FAST_INTEGER
if((x<-4)||(y<-4)||(x>maxX)||(y>maxY))
continue;
#endif
tmp0=(mvx0<<2)+point->x-ip0;
tmp1=(mvy0<<2)+point->y-ip1;
current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
prev=ipol[point->comp] + offset + point->offset;
// current_inter_sad+=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);
current_inter_sad=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);
if (current_inter_sad < best_inter_sad)
{
best_inter_sad=current_inter_sad;
pos=i;
}
}
mvx1 = search[pos].x;
mvy1 = search[pos].y;
offset+=search[pos].offset;
type =search[pos].type;
x_curr+=(mvx1>>1);
y_curr+=(mvy1>>1);
/************************************
***** *****
***** QUARTER-PEL REFINEMENT *****
***** *****
************************************/
point=qsearch[type];
pos=0;
for (i = 1; i < 9; i++)
{
point++;
x=x_curr+point->x;
y=y_curr+point->y;
#ifdef FAST_INTEGER
if((x<-4)||(y<-4)||(x>maxX)||(y>maxY))
continue;
#endif
tmp0=(mvx0<<2)+mvx1+point->x-ip0;
tmp1=(mvy0<<2)+mvy1+point->y-ip1;
current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
prev=ipol[point->comp] + offset + point->offset;
current_inter_sad=SAD_Macroblock(img,prev,curr,best_inter_sad,current_inter_sad);
if (current_inter_sad < best_inter_sad)
{
best_inter_sad=current_inter_sad;
pos=i;
}
}
offset+=qsearch[type][pos].offset;
img->offset=offset;
img->comp =qsearch[type][pos].comp;
curr_mvx=(mvx0<<2)+mvx1+qsearch[type][pos].x;
curr_mvy=(mvy0<<2)+mvy1+qsearch[type][pos].y;
if (skip_sad <= best_inter_sad)
{
img->bSkipMode=1;
img->offset=skip_offset;
img->comp =skipcomp;
best_inter_sad=skip_sad;
curr_mvx=skip_mv[0];
curr_mvy=skip_mv[1];
}
if (tot_intra_sad < best_inter_sad)
{
img->mb_mode=img->imod+8*img->type;
for(i=0;i<4;i++)
{
tmp_mv[pic_block_y][pic_block_x+4+i][0]=0;
tmp_mv[pic_block_y][pic_block_x+4+i][1]=0;
tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=0;
tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=0;
tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=0;
tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=0;
tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=0;
tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=0;
intra_mb_pos[pic_block_y][pic_block_x+4+i] = 1;
intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 1;
intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 1;
intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 1;
}
best_inter_sad = tot_intra_sad;
}
else
{
img->mb_mode=1;
img->imod=INTRA_MB_INTER;
for(i=0;i<4;i++)
{
tmp_mv[pic_block_y][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+1][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+1][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+2][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+2][pic_block_x+4+i][1]=curr_mvy;
tmp_mv[pic_block_y+3][pic_block_x+4+i][0]=curr_mvx;
tmp_mv[pic_block_y+3][pic_block_x+4+i][1]=curr_mvy;
intra_mb_pos[pic_block_y][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+1][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+2][pic_block_x+4+i] = 0;
intra_mb_pos[pic_block_y+3][pic_block_x+4+i] = 0;
}
}
return best_inter_sad;
}
int Intra_Sad(struct img_par *img,byte *ii, int *pp)
{
int i,sad=0;
int x0,x1,x2,x3;
int y0,y1,y2,y3;
int lx=img->width+IMG_PAD_SIZE;
for(i=0;i<4;i++)
{
x0=ii[0]; y0=pp[0];
x1=ii[1]; y1=pp[1];
x2=ii[2]; y2=pp[2];
x3=ii[3]; y3=pp[3];
sad+=IABS(x0-y0)+IABS(x1-y1)+IABS(x2-y2)+IABS(x3-y3);
ii+=lx; pp+=4;
}
return sad;
}
int IntraMB_Sad(struct img_par *img,byte *ii, int *pp)
{
int sad=0;
int i,j;
int mm,jj;
int current_intra_sad_2;
int lx=img->width+IMG_PAD_SIZE;
int M1[16][16],M0[4][4][4][4],M3[4],M4[4][4];
for (j=0;j<16;j++)
{
jj=j>>2;
for (i=0;i<16;i+=4)
{
mm=i>>2;
M1[i][j] =ii[i] -pp[i]; M1[i+1][j]=ii[i+1]-pp[i+1];
M1[i+2][j]=ii[i+2]-pp[i+2]; M1[i+3][j]=ii[i+3]-pp[i+3];
M0[0][mm][j&0x03][jj]= M1[i][j];
M0[1][mm][j&0x03][jj]=M1[i+1][j];
M0[2][mm][j&0x03][jj]=M1[i+2][j];
M0[3][mm][j&0x03][jj]=M1[i+3][j];
}
ii+=lx; pp+=16;
}
current_intra_sad_2=0; // no SAD start handicap here
for (jj=0;jj<4;jj++)
{
for (mm=0;mm<4;mm++)
{
for (j=0;j<4;j++)
{
M3[0]=M0[0][mm][j][jj]+M0[3][mm][j][jj];
M3[1]=M0[1][mm][j][jj]+M0[2][mm][j][jj];
M3[2]=M0[1][mm][j][jj]-M0[2][mm][j][jj];
M3[3]=M0[0][mm][j][jj]-M0[3][mm][j][jj];
M0[0][mm][j][jj]=M3[0]+M3[1];
M0[2][mm][j][jj]=M3[0]-M3[1];
M0[1][mm][j][jj]=M3[2]+M3[3];
M0[3][mm][j][jj]=M3[3]-M3[2];
}
for (i=0;i<4;i++)
{
M3[0]=M0[i][mm][0][jj]+M0[i][mm][3][jj];
M3[1]=M0[i][mm][1][jj]+M0[i][mm][2][jj];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -