📄 mot_est.cpp
字号:
p1 = 2*MV[vec][yin1][xin1]->x;
p2 = 2*MV[vec][yin2][xin2]->x;
p3 = 2*MV[vec][yin3][xin3]->x;
}
if (newgob)
{
p2 = 2 * NO_VEC; //!< MV above can not be accessed
}
if (p2 == 2*NO_VEC)
{
p2 = p3 = p1; //!< When MV above can not be accessed, use left MV instead
}
*pmv0 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
if (half_pel)
{
p1 = 2*MV[vec][yin1][xin1]->y + MV[vec][yin1][xin1]->y_half;
p2 = 2*MV[vec][yin2][xin2]->y + MV[vec][yin2][xin2]->y_half;
p3 = 2*MV[vec][yin3][xin3]->y + MV[vec][yin3][xin3]->y_half;
}
else
{
p1 = 2*MV[vec][yin1][xin1]->y;
p2 = 2*MV[vec][yin2][xin2]->y;
p3 = 2*MV[vec][yin3][xin3]->y;
}
if (newgob)
{
p2 = 2 * NO_VEC; //!< MV above can not be accessed
}
if (p2 == 2*NO_VEC)
{
p2 = p3 = p1; //!< When MV above can not be accessed, use left MV instead
}
*pmv1 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
}
/*!
*******************************************************************************
*
* Name: mv_search_fs
* Description: find best integer motion vector for a block(Full Search)
* Input: position of current block
* current lum image and reference lum image
* Output: integer MV value
* Last modified: 2002/12/17 by lcl
*
*******************************************************************************/
void mv_search_fs(H263VencStatus *encoder, MCParam *MC, int curr_x, int curr_y, int blocksize, int BACKWARD)
{
int iMinSAD = (MC->mv)->min_sad;
int iCurrSAD;
int i;
int iXCheckPt;
int iYCheckPt;
int iCenterX = curr_x + (MC->mv)->x;
int iCenterY = curr_y + (MC->mv)->y;
int iXDest = iCenterX;
int iYDest = iCenterY;
int search_range = (8 == blocksize ? MC->search_range_8x8 : MC->search_range);
int iNbr = (2*search_range + 1) * (2*search_range + 1);
int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
int lx1 = encoder->pels;
int lx2 = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
int index = BACKWARD ? encoder->zero_index : encoder->ref_index;
unsigned char *p1 = (encoder->frameToEncode).pLum ;
unsigned char *p2 = (encoder->frame_buf[index]).pLum ;
if (encoder->PTYPE == B_IMG)
{
mv_out = 1;
p1 = (encoder->BPicture[encoder->B_count]).pLum;
}
else
{
mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
}
for (i = 1; i < iNbr; i++)
{
iXCheckPt = iCenterX + MC->SpiralX[i];
iYCheckPt = iCenterY + MC->SpiralY[i];
if ( (iXCheckPt<0||iYCheckPt<0||
iXCheckPt>encoder->pels - blocksize ||
iYCheckPt>encoder->lines - blocksize)
&& !mv_out)
continue;
iCurrSAD = encoder->method.me_sad_a(lx1, lx2, curr_x, curr_y, iXCheckPt, iYCheckPt, p1, p2, iMinSAD, blocksize);
if (iCurrSAD >= iMinSAD)
continue;
iMinSAD= iCurrSAD;
iXDest = iXCheckPt;
iYDest = iYCheckPt;
}
(MC->mv)->x = iXDest-curr_x;
(MC->mv)->y = iYDest-curr_y;
(MC->mv)->min_sad = iMinSAD;
}
/*!
*******************************************************************************
*
* Name: mv_search_dmd
* Description: find best integer motion vector for a block(Noval Diomand Search)
* Input: position of current block
* current lum image and reference lum image
* Output: integer MV value
* Last modified: 2002/12/17 by lcl
*
*******************************************************************************/
void mv_search_dmd(H263VencStatus *encoder, MCParam *MC, int curr_x, int curr_y, int blocksize, int BACKWARD)
{
int iMinSAD=(MC->mv)->min_sad;
int mbDiff;
int iTotalCheckPts, iCheckPts, iMotDirn=0, iPtNmbr=0;
int MOTION_ACTIVITY;
int stopFlag=0, stopDiamondMotion=0;
int dXCentre=curr_x + (MC->mv)->x;
int dYCentre=curr_y + (MC->mv)->y;
int iXDest=dXCentre;
int iYDest=dYCentre;
int iXCheckPt, iYCheckPt;
int dType;
int L1=1, L2=2, L3=4;
int LMotion = 0;
int block = 0;
int mb_x = curr_x/16;
int mb_y = curr_y/16;
int vec_x;
int vec_y;
int search_range = (8 == blocksize) ? MC->search_range_8x8 : MC->search_range;
int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
int lx1 = encoder->pels;
int lx2 = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
int index = BACKWARD ? encoder->zero_index : encoder->ref_index;
unsigned char *p1 = (encoder->frameToEncode).pLum ;
unsigned char *p2 = (encoder->frame_buf[index]).pLum ;
if (encoder->PTYPE == B_IMG)
{
mv_out = 1;
p1 = (encoder->BPicture[encoder->B_count]).pLum;
}
else
{
mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
}
//! assign neighborhood MVs as points of diamond[2], which is MotAdaptPat
FindNbrMV(MC->mv_frame, block, 0, mb_x, mb_y, &vec_x, &vec_y, BACKWARD); //!< left
diamond[2].dpoint[0].x = vec_x - (MC->mv)->x;
diamond[2].dpoint[0].y = vec_y - (MC->mv)->y;
FindNbrMV(MC->mv_frame, block, 1, mb_x, mb_y, &vec_x, &vec_y, BACKWARD); //!< up
diamond[2].dpoint[1].x = vec_x - (MC->mv)->x;
diamond[2].dpoint[1].y = vec_y - (MC->mv)->y;
FindNbrMV(MC->mv_frame, block, 2, mb_x, mb_y, &vec_x, &vec_y, BACKWARD); //!< up-right
diamond[2].dpoint[2].x = vec_x - (MC->mv)->x;
diamond[2].dpoint[2].y = vec_y - (MC->mv)->y;
//! compute motion activity
MOTION_ACTIVITY = max(abs(diamond[2].dpoint[0].x)+abs(diamond[2].dpoint[0].y) , max( abs(diamond[2].dpoint[1].x)+abs(diamond[2].dpoint[1].y) , abs(diamond[2].dpoint[2].x)+abs(diamond[2].dpoint[2].y)) );
if (MOTION_ACTIVITY > L3)
LMotion = 1; //!> detect large motion
dType=(MOTION_ACTIVITY > L2) ? MotAdaptPat : ((MOTION_ACTIVITY > L1) ? LDiamond : SDiamond);
iTotalCheckPts=diamond[dType].no_check_pts;
while(stopFlag!=1)
{
iCheckPts=iTotalCheckPts;
do
{
iXCheckPt=diamond[dType].dpoint[iPtNmbr].x+dXCentre;
iYCheckPt=diamond[dType].dpoint[iPtNmbr].y+dYCentre;
if ( (iXCheckPt < 0||iYCheckPt < 0||
iXCheckPt > (encoder->pels - blocksize)||
iYCheckPt > (encoder->lines - blocksize))
&& !mv_out)
goto NEXT_POSITION;
if ( (iXCheckPt-curr_x) < -search_range||
(iXCheckPt-curr_x) > search_range||
(iYCheckPt-curr_y) < -search_range||
(iYCheckPt-curr_y) > search_range)
goto NEXT_POSITION; //!< skip this check point
else
{
mbDiff = encoder->method.me_sad_a(lx1, lx2, curr_x, curr_y, iXCheckPt, iYCheckPt, p1, p2, iMinSAD, blocksize);
if (mbDiff < iMinSAD)
{
iMinSAD= mbDiff;
iXDest = iXCheckPt;
iYDest = iYCheckPt;
iMotDirn=iPtNmbr;
}
}
NEXT_POSITION:
iPtNmbr+=1;
iPtNmbr=(dType==LDiamond) ? iPtNmbr % diamond[LDiamond].no_check_pts : iPtNmbr % diamond[SDiamond].no_check_pts;
iCheckPts-=1;
}while(iCheckPts>0);
if(dType==MotAdaptPat)
{
dType = LMotion?LDiamond:SDiamond; //!> if large motion, Large Diamond used
iPtNmbr=0;
iTotalCheckPts=diamond[dType].no_check_pts;
}
else
{
if((iXDest==dXCentre)&&(iYDest==dYCentre))
stopDiamondMotion=1;
else
{
iTotalCheckPts=(((iXDest==dXCentre) || (iYDest==dYCentre))&&(dType==LDiamond)) ? 5 :3;
iPtNmbr=diamond[dType].dpoint[iMotDirn].iStartNmbr;
}
}
if(stopDiamondMotion)
{
if(dType==LDiamond)
{
dType = SDiamond;
iPtNmbr = 0;
iTotalCheckPts = diamond[dType].no_check_pts;
}
else
stopFlag=1;
}
dXCentre=iXDest;
dYCentre=iYDest;
}
(MC->mv)->x = iXDest - curr_x;
(MC->mv)->y = iYDest - curr_y;
(MC->mv)->min_sad = iMinSAD;
}
/*!
*******************************************************************************
*
* Name: findhalfpel
* Description: find best motion vectors in half resolution
* Input: position of current block
* current lum image and interpolated reference lum image
* Output: half MV value
* Last modified: 2002/11/23 by lcl
*
*******************************************************************************/
void findhalfpel(H263VencStatus *encoder, MCParam *MC, int x, int y, int blocksize, int BACKWARD)
{
int iXPos[9] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
int iYPos[9] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int iMinSAD, iCurrSAD;
int iCenterX;
int iCenterY;
int iCheckPtX;
int iCheckPtY;
int iPoint, iBestPt;
int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
int lx1 = encoder->pels;
int lx2 = encoder->mv_outside_frame ? encoder->pels*2+64 : encoder->pels*2;
unsigned char *ipol = BACKWARD ? encoder->next_ipol : encoder->prev_ipol;
unsigned char *p1 = (encoder->frameToEncode).pLum;
unsigned char *p2 = ipol;
if (encoder->PTYPE == B_IMG)
{
mv_out = 1;
p1 = (encoder->BPicture[encoder->B_count]).pLum;
}
else
{
mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
}
iBestPt = 0;
iMinSAD = (MC->mv)->min_sad;
iCenterX = (x + (MC->mv)->x)<<1;
iCenterY = (y + (MC->mv)->y)<<1;
for (iPoint = 1; iPoint < 9; iPoint++)
{
iCheckPtX = iCenterX + iXPos[iPoint]; //!< Current absolute X position in the reference pic
iCheckPtY = iCenterY + iYPos[iPoint]; //!< Current absolute Y position in the reference pic
if ( (iCheckPtX<0 ||
iCheckPtY<0 ||
iCheckPtX>(encoder->pels - blocksize)*2 || //!< keep in agreement with h.263 coder
iCheckPtY>(encoder->lines - blocksize)*2) //!< should be considered later
&& !mv_out)
continue;
iCurrSAD = encoder->method.me_sad_b(lx1, lx2, x, y, iCheckPtX, iCheckPtY, p1, p2, iMinSAD, blocksize);
if (iCurrSAD >= iMinSAD)
continue;
iMinSAD = iCurrSAD;
iBestPt = iPoint;
}
(MC->mv)->x_half = iXPos[iBestPt];
(MC->mv)->y_half = iYPos[iBestPt];
(MC->mv)->min_sad = iMinSAD;
}
/*!
*******************************************************************************
*
* Name: zeroVec
* Description:
* Input:
* Output:
* Last modified: 2002/11/23 by lcl
*
*******************************************************************************/
void zeroVec(MotionVector *MV)
{
MV->x = 0;
MV->y = 0;
MV->x_half = 0;
MV->y_half = 0;
}
/*!
*******************************************************************************
*
* Name: me_sad_a16
* Description: compute sad for integer pel motion search
* Input: current lum image and reference lum image
* position of current block in current image
* position of reference block in reference image
* Output: sad returned
* Optimization: sadmmx.cpp
* Last modified: 2003/02/20 by lcl
*
*******************************************************************************/
int me_sad_a_c(int lx1, int lx2, int x1, int y1, int x2, int y2,
unsigned char *P1, unsigned char *P2,
int sad_last, int blocksize)
{
int i, j;
int sad = 0;
unsigned char *p1 = P1 + y1*lx1 + x1;
unsigned char *p2 = P2 + y2*lx2 +x2 ;
for(i = 0; i < blocksize; i++)
{
for(j = 0; j < blocksize; j+=4)
{
sad+=absm(p1[j] - p2[j]);
sad+=absm(p1[j+1] - p2[j+1]);
sad+=absm(p1[j+2] - p2[j+2]);
sad+=absm(p1[j+3] - p2[j+3]);
if (sad > sad_last)
return MAX_SAD;
}
p1+=lx1;
p2+=lx2;
}
return sad;
}
/*!
*******************************************************************************
*
* Name: me_sad_b
* Description: compute sad for half pel motion search
* Input: current lum image, interpolated image derived from reference frame
* position of current block in current lum image,
* position of reference block in interpolated reference image
* Output: sad returned
* Optimization: sadmmx.cpp
* Last modified: 2002/12/17 by lcl
*
*******************************************************************************/
int me_sad_b_c(int lx1, int lx2, int x1, int y1, int x2, int y2,
unsigned char *P1, unsigned char *P2,
int sad_last, int blocksize)
{
int i, j, k;
int sad = 0;
unsigned char *p1 = P1 + y1*lx1 + x1;
unsigned char *p2 = P2 + y2*lx2 + x2 ;
for(i = 0; i < blocksize; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -