📄 dsp_mot.c
字号:
}//最近if(!out)
else
{
mv_x=mv_y=0;
sad_min=MV_MAX_ERROR; //punish the OUTER blocks with MV_MAX_ERROR in order to be INTRA CODED
}
min_error8 += sad_min;//ldm
mv8_x[block]=mv_x; mv8_y[block]=mv_y;//ldm向量赋值8*8
} //for block
if ((min_error16 -129) <min_error8 ){//判断MBmode
MBmode = MBM_INTER16;
min_error = min_error16;
}else {
MBmode = MBM_INTER8;
min_error = min_error8;
}
}//if(!out)
}//if(enable_8x8_mv==1) //enable_8x8_mv
*/
if(MBmode != MBM_INTRA)
{
if(TryIntraMode(g_currMB,min_error))
{
MBmode = MBM_INTRA;//如果属于剧烈运动区域则进行帧内编码
}
}
if(MBmode == MBM_INTRA)
{
for (k = 0; k < 256; k++)
{
min_error_intra += g_currMB[k];//recalculate the sad for intra MB
}
min_error = min_error_intra;
}
if((MBmode == MBM_INTER16)&&(mv16_x==0)&&(mv16_y==0))
min_error = min_error16 +129;
mvm_width = (p_par->width)/MB_SIZE;//一行所含宏块数
MB_md[j * mvm_width + i] = MBmode;
//四个小快位置
posBlock0 = 2*j*2*mvm_width + 2*i;
posBlock1 = 2*j*2*mvm_width + 2*i+1;
posBlock2 = (2*j+1)*2*mvm_width + 2*i;
posBlock3 = (2*j+1)*2*mvm_width + 2*i+1;
//如果是MBM_INTER16,则四个小块运动矢量一样
if(MBmode == MBM_INTER16){
motx[posBlock0]=mv16_x; moty[posBlock0]=mv16_y;
motx[posBlock1]=mv16_x; moty[posBlock1]=mv16_y;
motx[posBlock2]=mv16_x; moty[posBlock2]=mv16_y;
motx[posBlock3]=mv16_x; moty[posBlock3]=mv16_y;
}
//如果是MBM_INTER8,则四个小块具有不同的运动矢量
/*
else if(MBmode == MBM_INTER8){
motx[posBlock0]=mv8_x[0]; moty[posBlock0]=mv8_y[0];
motx[posBlock1]=mv8_x[1]; moty[posBlock1]=mv8_y[1];
motx[posBlock2]=mv8_x[2]; moty[posBlock2]=mv8_y[2];
motx[posBlock3]=mv8_x[3]; moty[posBlock3]=mv8_y[3];
}
*/
//不进行运动估计
else {
motx[posBlock0]=0; moty[posBlock0]=0;
motx[posBlock1]=0; moty[posBlock1]=0;
motx[posBlock2]=0; moty[posBlock2]=0;
motx[posBlock3]=0; moty[posBlock3]=0;
}
return min_error;
}
//进行帧间编码
void CodeInterVOP (
unsigned char * curr,//Vop *curr,
unsigned char * rec,//Vop *comp,
char *MB_decisions, char *mot_x, char *mot_y,
//Int f_code_for,
//Int intra_acdc_pred_disable,
unsigned char * ref //Vop *rec_curr
//Image *mottext_bitstream,
//Bits *bits
)
{
char Mode=0;
char QP = p_par->quantizer;
short* qcoeff;
register short i, j;
int CBP;
char COD;
char CBPY;
// char CBPC;
char MB_in_width, MB_in_height, B_in_width;
short boff;
char p;
char *ptr=NULL;
char *motx_ptr=NULL, *moty_ptr=NULL;
short num_pixels;
short num_lines;
char vop_type=PCT_INTER;
short ***DC_store_curr;
short ***DC_store_above;
short ***DC_store_tmp;
short m, n;
char ACpred_flag=-1;
char direction[6];
char dc_scaler_lum,dc_scaler_chr;
num_pixels = p_par->width;
num_lines = p_par->height;
MB_in_width = num_pixels / MB_SIZE;
MB_in_height = num_lines / MB_SIZE;
B_in_width = 2 * MB_in_width;
qcoeff = g_qcoeff;
for (i = 0; i < 6; i++) direction[i] = 0;
DC_store_above = g_DC_store[0];
DC_store_curr = g_DC_store[1];
vop_type = PCT_INTER;
ptr = MB_decisions;
motx_ptr = mot_x;
moty_ptr = mot_y;
dc_scaler_lum = cal_dc_scaler(QP,1);
dc_scaler_chr = cal_dc_scaler(QP,2);
for (j = 0; j < MB_in_height; j++)
{
for (i = 0; i < MB_in_width; i++)
{
p = *ptr;
if(p != MBM_INTRA)
for (m = 0; m < 6; m++)
{
DC_store_curr[i][m][0] = 1024;
for (n = 1; n < 15; n++)
DC_store_curr[i][m][n] = 0;
}
switch (p)
{
case MBM_INTRA:
Mode = MODE_INTRA;
break;
case MBM_INTER16:
Mode = MODE_INTER ;
break;
/*
case MBM_INTER8:
Mode = MODE_INTER4V;
break;
*/
default:
// printf("invalid MB_decision value :%d\n", p);
exit(0);
}
loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);//g_currMB now is the source MB
if(Mode != MODE_INTRA){
//采用帧间编码
compensation(ref,i,j,Mode,motx_ptr,moty_ptr,p_par->rounding_type);//comp to g_compMB
diffMB();// g_currMB - g_compMB to g_fblock
}else//采用帧内编码
FromCharToShort();//from g_currMB to g_fblock
DCT_Quant_Rec_MB (QP, Mode);// g_currMB is finally the reconstructed MB
CopyRecMBToRef(rec,i,j,p_par->width + 32, p_par->height + 32);//frome g_currMB to reference vop
CopyRecMBToResult(result,i,j,p_par->width, p_par->height);//获得重建图像
if(i==0)
{ paddingMBleft(rec,j,p_par->width + 32, p_par->height + 32);
paddingMBleft1(result,j,p_par->width, p_par->height);
}
else if(i==(MB_in_width-1))
{ paddingMBright(rec,j,p_par->width + 32, p_par->height + 32);
paddingMBright1(result,j,p_par->width, p_par->height);
}
boff = (2 * j * B_in_width + 2 * i);
CBP = FindCBP(qcoeff,Mode,64);
if ((CBP == 0) && (p == 1) && (*(motx_ptr +boff) == 0)
&& (*(moty_ptr +boff) == 0))
{
COD = 1; /* skipped macroblock */
BitstreamPutBits((UInt)COD, 1L); /* COD */
*ptr = SKIPP;
Mode = MODE_INTER;
}
else
{
COD = 0; /* coded macroblock */
}
if (COD == 0)
{
if (Mode == MODE_INTRA)
{
m =0;
DC_store_curr[ i][0][m] = qcoeff[m]*dc_scaler_lum;
DC_store_curr[ i][1][m] = qcoeff[m+64]*dc_scaler_lum;
DC_store_curr[ i][2][m] = qcoeff[m+128]*dc_scaler_lum;
DC_store_curr[ i][3][m] = qcoeff[m+192]*dc_scaler_lum;
DC_store_curr[ i][4][m] = qcoeff[m+256]*dc_scaler_chr;
DC_store_curr[ i][5][m] = qcoeff[m+320]*dc_scaler_chr;
for (m = 1; m < 8; m++)
{
DC_store_curr[ i][0][m] = qcoeff[m];
DC_store_curr[ i][1][m] = qcoeff[m+64];
DC_store_curr[ i][2][m] = qcoeff[m+128];
DC_store_curr[ i][3][m] = qcoeff[m+192];
DC_store_curr[ i][4][m] = qcoeff[m+256];
DC_store_curr[ i][5][m] = qcoeff[m+320];
}
for (m = 0; m < 7; m++)
{
DC_store_curr[ i][0][m+8] = qcoeff[(m+1)*8];
DC_store_curr[ i][1][m+8] = qcoeff[(m+1)*8+64];
DC_store_curr[ i][2][m+8] = qcoeff[(m+1)*8+128];
DC_store_curr[ i][3][m+8] = qcoeff[(m+1)*8+192];
DC_store_curr[ i][4][m+8] = qcoeff[(m+1)*8+256];
DC_store_curr[ i][5][m+8] = qcoeff[(m+1)*8+320];
}
ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store_curr,
DC_store_above, QP, direction);
}
CBPY = CBP >> 2;
CBPY = CBPY & 15; /* last 4 bits */
// CBPC = CBP & 3; /* last 2 bits */
Bits_CountMB_combined (Mode, COD, ACpred_flag, CBP,vop_type);//对宏块类型进行判断
Bits_CountMB_MV( mot_x, mot_y, Mode, i, j, p_par->fcode_for);//对矢量进行编码
MB_CodeCoeff( qcoeff, Mode, CBP, 64,direction);//对系数进行编码
}
ptr++;
} /* for i loop */
if(j==0)
{ paddingVOPTop(rec,p_par->width + 32, p_par->height + 32);
paddingVOPTop1(result,p_par->width, p_par->height);
}
DC_store_tmp = DC_store_curr;
DC_store_curr = DC_store_above;
DC_store_above = DC_store_tmp;
} /* for j loop */
paddingVOPBottom(rec,p_par->width + 32, p_par->height + 32);
paddingVOPBottom1(result,p_par->width, p_par->height);
}
void compensation(
unsigned char * ref,
short i,short j,char Mode,
char * motx_ptr,char * moty_ptr,
char rounding_type)//运动补偿函数
{
short xsum=0,ysum=0;
short dx,dy,xint,yint;
char xh,yh;
short mvm_width,posBlock0,posBlock1,posBlock2,posBlock3;
short lenRefY,lenRefUV,ofx,ofy,offset_b;
unsigned int offset;
unsigned char *refU,*refV;
mvm_width = p_par->width/MB_SIZE;
lenRefY = (p_par->width +32);
lenRefUV = lenRefY/2;//UV分量是Y分量的一半
posBlock0 = 2*j*2*mvm_width + 2*i;
if(Mode == MODE_INTER4V)//如果分成四个小块
{
posBlock1 = posBlock0+1;
posBlock2 = posBlock0 + 2*mvm_width ;
posBlock3 = posBlock2 +1;
//for blockY0
ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock0] ;
ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock0] ;
offset = ofy * lenRefY + ofx;
loadCompData(ref+offset,lenRefY,8,g_compMB,16);
//for blockY1
ofx = 16 + (i*MB_SIZE) + 8 + motx_ptr[posBlock1] ;
ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock1] ;
offset = ofy * lenRefY + ofx; offset_b = 8;
loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);
//for blockY2
ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock2] ;
ofy = 16 + (j*MB_SIZE) + 8 + moty_ptr[posBlock2] ;
offset = ofy * lenRefY + ofx; offset_b = 8*16;
loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);
//for blockY3
ofx = 16 + (i*MB_SIZE) + 8 + motx_ptr[posBlock3] ;
ofy = 16 + (j*MB_SIZE) + 8 + moty_ptr[posBlock3] ;
offset = ofy * lenRefY + ofx; offset_b = 8*16+8;
loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);
xsum = 2*(motx_ptr[posBlock0])+2*(motx_ptr[posBlock1])
+2*(motx_ptr[posBlock2])+2*(motx_ptr[posBlock3]);
ysum = 2*(moty_ptr[posBlock0])+2*(moty_ptr[posBlock1])
+2*(moty_ptr[posBlock2])+2*(moty_ptr[posBlock3]);
dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);
dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);
}
else /* Mode == MODE_INTER */
{
//for MBY
ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock0] ;
ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock0] ;
offset = ofy * lenRefY + ofx;
loadCompData(ref+offset,lenRefY,16,g_compMB,16);
dx = (2 * motx_ptr[posBlock0]);
dy = (2 * moty_ptr[posBlock0]);
dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
}
refU = ref + (p_par->width +32)*(p_par->height +32);
refV = refU + ((p_par->width +32)/2) * ((p_par->height +32)/2);
xint = dx>>1; xh = dx & 1;
yint = dy>>1; yh = dy & 1;
ofx = 8 + ((i*MB_SIZE)>>1) + xint ;
ofy = 8 + ((j*MB_SIZE)>>1) + yint ;
offset = ofy * lenRefUV + ofx;
//色度
loadCompData(refU+offset,lenRefUV,9,g_tmpcomUV,9);//load to g_tmpcomUV[81]
GetPredChroma(xh , yh , g_compMB+256,rounding_type);//compute from g_tmpcomUV[81] to g_compMB's blockU
loadCompData(refV+offset,lenRefUV,9,g_tmpcomUV,9);//load to g_tmpcomUV[81]
GetPredChroma(xh , yh , g_compMB+320,rounding_type);//compute from g_tmpcomUV[81] to g_compMB's blockV
}
void loadCompData(unsigned char *src,short lenSrc,char size,unsigned char *dst,char lenDst)
{
char ic;
unsigned char* pSrc = src;
unsigned char* pDst = dst;
for (ic = 0; ic < size; ic++) {
memcpy (pDst, pSrc, size);//size=8
pSrc += lenSrc; pDst += lenDst;
}
}
//获得预测色度函数
void GetPredChroma(char xh , char yh , unsigned char * dst, char rounding_control)
{
register char m,n;
if (!xh && !yh)
{
for (n = 0; n < 8; n++)
{
for (m = 0; m < 8; m++)
{
dst[n*8+m]= g_tmpcomUV[n*9+m];
}
}
}
else if (!xh && yh)
{
for (n = 0; n < 8; n++)
{
for (m = 0; m < 8; m++)
{
dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[(n+1)*9+m]+ 1- rounding_control) >>1;
}
}
}
else if (xh && !yh)
{
for (n = 0; n < 8; n++)
{
for (m = 0; m < 8; m++)
{
dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[n*9+m+1]+ 1- rounding_control)>>1;
}
}
}
else
{ /* xh && yh */
for (n = 0; n < 8; n++)
{
for (m = 0; m < 8; m++)
{
dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[n*9+m+1]
+ g_tmpcomUV[(n+1)*9+m] +g_tmpcomUV[(n+1)*9+m+1]+ 2- rounding_control)>>2;
}
}
}
return;
}
//宏块差值
void diffMB()// g_currMB - g_compMB to g_fblock
{
register short k,i,j;
short xwidth;
unsigned char *pxlcurr;
unsigned char *pxlcomp;
for(k=0; k<6; k++)
{
switch (k)
{
case 0:
pxlcurr = g_currMB;
pxlcomp = g_compMB;
xwidth = 16;
break;
case 1:
pxlcurr = g_currMB+8;
pxlcomp = g_compMB+8;
xwidth = 16;
break;
case 2:
pxlcurr = g_currMB+8*MB_SIZE;
pxlcomp = g_compMB+8*MB_SIZE;
xwidth = 16;
break;
case 3:
pxlcurr = g_currMB+8*MB_SIZE+8;
pxlcomp = g_compMB+8*MB_SIZE+8;
xwidth = 16;
break;
case 4:
pxlcurr = g_currMB + MB_SIZE*MB_SIZE;
pxlcomp = g_compMB + MB_SIZE*MB_SIZE;
xwidth = 8;
break;
case 5:
pxlcurr = g_currMB + (MB_SIZE*MB_SIZE/4)*5;
pxlcomp = g_compMB + (MB_SIZE*MB_SIZE/4)*5;
xwidth = 8;
break;
default:
break;
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
g_fblock[k][i*8 + j] = (short)pxlcurr[j] - (short)pxlcomp[j];
}
pxlcurr+=xwidth;
pxlcomp+=xwidth;
}
}//end k
}
void /* MVP/Noel */
find_pmvs(
char *mot_x, /* x-motion vector field */
char *mot_y, /* y-motion vector field */
short x, /* xpos of the MB in multiples of 16 (hor coord) */
short y, /* ypos of the MB in multiples of 16 (ver coord) */
char block, /* block number (0 if one vector per MB, 1..4 else) */
short *mvx, /* hor predicted motion vector [ in half-pixels units ] */
short *mvy /* ver predicted motion vector [ in half-pixels units ] */
)
{
char p1x,p2x,p3x;
char p1y,p2y,p3y;
char xin1, xin2, xin3;
char yin1, yin2, yin3;
char vec1, vec2, vec3;
char rule1, rule2, rule3;
char subdim=2;
char *motxdata = mot_x;
char *motydata = mot_y;
short xB = p_par->width/BLOCK_SIZE;
switch (block)
{
case 0:
vec1 = 1 ; yin1 = y ; xin1 = x-1;
vec2 = 2 ; yin2 = y-1; xin2 = x;
vec3 = 2 ; yin3 = y-1; xin3 = x+1;
break;
case 1:
vec1 = 1 ; yin1 = y ; xin1 = x-1;
vec2 = 2 ; yin2 = y-1; xin2 = x;
vec3 = 2 ; yin3 = y-1; xin3 = x+1;
break;
case 2:
vec1 = 0 ; yin1 = y ; xin1 = x;
vec2 = 3 ; yin2 = y-1; xin2 = x;
vec3 = 2 ; yin3 = y-1; xin3 = x+1;
break;
case 3:
vec1 = 3 ; yin1 = y ; xin1 = x-1;
vec2 = 0 ; yin2 = y ; xin2 = x;
vec3 = 1 ; yin3 = y ; xin3 = x;
break;
case 4:
vec1 = 2 ; yin1 = y ; xin1 = x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -