📄 dsp_vop.c
字号:
qcoeff_ind = g_qcoeff;
// fdct_8x8(g_fblock[0],6);
for (k = 0; k < 6; k++)
{
// fdct_enc(g_fblock[k]);
IMG_fdct_8x8(g_fblock[k],1);//TI库函数调用
if (k < 4) type = 1;
else type = 2;
BlockQuantH263(g_fblock[k],QP,Mode,type,qcoeff_ind);//量化
BlockDequantH263(qcoeff_ind,QP,Mode,type,g_fblock[k]);//反量化
qcoeff_ind += 64;
}
// idct_8x8(g_fblock[0],6);
for (k = 0; k < 6; k++)
{
// idct_enc(g_fblock[k]);
IMG_idct_8x8(g_fblock[k],1);
switch (k)
{
case 0:
offset = 0;
xwidth = 16;
break;
case 1:
offset = 8;
xwidth = 16;
break;
case 2:
offset = 8*MB_SIZE;
xwidth = 16;
break;
case 3:
offset = 8*MB_SIZE+8;
xwidth = 16;
break;
case 4:
offset = MB_SIZE*MB_SIZE;
xwidth = 8;
break;
case 5:
offset = (MB_SIZE*MB_SIZE/4)*5;
xwidth = 8;
break;
default:
break;
}
if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
{
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
g_currMB[offset+j] = (unsigned char)MIN(255, MAX(0, g_fblock[k][i*8 +j]) );
}//copy from g_fblock to g_currMB
offset += xwidth;
}
}else{
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
g_currMB[offset+j] =(unsigned char)MIN(255, MAX(0, (g_fblock[k][i*8 +j]+g_compMB[offset+j]) ) );
}//copy from (g_fblock + g_compMB) to g_currMB
offset += xwidth;
}
}
}
return;
}
//量化函数
inline void
BlockQuantH263 (short *coeff, char QP, char mode, char type, short *qcoeff)
{
short maxDC=255,level,dc_scaler;
register short i;
dc_scaler = cal_dc_scaler(QP,type);
if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
{
// qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] >= 0) ? (coeff[0] + dc_scaler/2)/dc_scaler : (coeff[0] - dc_scaler/2) /dc_scaler));
qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler) );
for (i = 1; i < 64; i++)
{
level = (ABS(coeff[i])) / (2*QP);
qcoeff[i] = MIN(2047,MAX(-2048,SIGN(coeff[i]) * level));
}
}
else /* non Intra */
{
for (i = 0; i < 64; i++)
{
level = (ABS(coeff[i])-QP/2) / (2*QP);
qcoeff[i] = MIN(2047,MAX(-2048,SIGN(coeff[i]) * level));
}
}
return;
}
char cal_dc_scaler (char QP, char type)
{
char dc_scaler;
if (type == 1)
{
if (QP > 0 && QP < 5) dc_scaler = 8;
else if (QP > 4 && QP < 9) dc_scaler = 2 * QP;
else if (QP > 8 && QP < 25) dc_scaler = QP + 8;
else dc_scaler = 2 * QP - 16;
}
else
{
if (QP > 0 && QP < 5) dc_scaler = 8;
else if (QP > 4 && QP < 25) dc_scaler = (QP + 13) / 2;
else dc_scaler = QP - 6;
}
return dc_scaler;
}
//反量化函数
inline void BlockDequantH263 (short *qcoeff, char QP, char mode, char type, short *rcoeff)
{
register char i;
char dc_scaler;
short lim;
lim = 2048; //(1 << (bits_per_pixel + 3));
for (i = 0; i < 64; i++)
{
if (qcoeff[i])
{
//@ qcoeff[i] = MIN(2047, MAX(-2048, qcoeff[i] ));
if ((QP % 2) == 1)
rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
else
rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
}
else
rcoeff[i] = 0;
}
if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
{ /* Intra */
// if (short_video_header)
// dc_scaler = 8;
// else
dc_scaler = cal_dc_scaler(QP,type);
rcoeff[0] = qcoeff[0] * dc_scaler;
}
for (i=0;i<64;i++)
if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
return;
}
Int FindCBP (short* qcoeff, char Mode, char ncoeffs)
{
register short i,j;
Int CBP = 0;
char intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
/* Set CBP for this Macroblock */
for (i = 0; i < 6; i++)
{
for (j = i*ncoeffs + intra; j < (i+1)*ncoeffs; j++)
{
if (qcoeff[j])
{
if (i == 0) {CBP |= 32;}
else if (i == 1) {CBP |= 16;}
else if (i == 2) {CBP |= 8;}
else if (i == 3) {CBP |= 4;}
else if (i == 4) {CBP |= 2;}
else {CBP |= 1;}
break;
}
}
}
return CBP;
}
char doDCACpred(short *qcoeff, Int *CBP, char ncoeffs, short x_pos, short y_pos,
short ***DC_store_curr, short ***DC_store_above, char QP, char direction[] )
{
register short i, m;
short block_A, block_B, block_C;
short defaultDC;
char Xpos[6] = {-1, 0, -1, 0, -1, -1};
// char Ypos[6] = {-1, -1, 0, 0, -1, -1};
char Xtab[6] = {1, 0, 3, 2, 4, 5};
char Ytab[6] = {2, 3, 0, 1, 4, 5};
char Ztab[6] = {3, 2, 1, 0, 4, 5};
short grad_hor, grad_ver, DC_pred;
short pred_A[15], pred_C[15];
Int S = 0, S1, S2;
Int diff;
short diff_coeff[6][15];
char ACpred_flag=-1;
char dc_scaler,acPredOutOfRange;
acPredOutOfRange =0;
defaultDC=1024;
for(i=0;i<8;i++)
{
diff_coeff[0][i]=qcoeff[i];
diff_coeff[1][i]=qcoeff[64+i];
diff_coeff[2][i]=qcoeff[128+i];
diff_coeff[3][i]=qcoeff[192+i];
diff_coeff[4][i]=qcoeff[256+i];
diff_coeff[5][i]=qcoeff[320+i];
}
for(i=0;i<7;i++)
{
diff_coeff[0][i+8]=qcoeff[(i+1)*8];
diff_coeff[1][i+8]=qcoeff[ 64+(i+1)*8];
diff_coeff[2][i+8]=qcoeff[128+(i+1)*8];
diff_coeff[3][i+8]=qcoeff[192+(i+1)*8];
diff_coeff[4][i+8]=qcoeff[256+(i+1)*8];
diff_coeff[5][i+8]=qcoeff[320+(i+1)*8];
}
S1 = 0;
S2 = 0;
for (i = 0; i < 6; i++)
{
if ((x_pos == 0) && (y_pos == 0)) /* top left corner */
{
block_A = (i == 1 || i == 3) ? DC_store_curr[0][Xtab[i]][0] : defaultDC;
block_B = (i == 3) ? DC_store_curr[0][Ztab[i]][0] : defaultDC;
block_C = (i == 2 || i == 3) ? DC_store_curr[0][Ytab[i]][0] : defaultDC;
}
else if (x_pos == 0) /* left edge */
{
block_A = (i == 1 || i == 3) ? DC_store_curr[x_pos][Xtab[i]][0] : defaultDC;
block_B = (i == 1) ? DC_store_above[x_pos][Ztab[i]][0] : (i == 3) ? DC_store_curr[x_pos][Ztab[i]][0] : defaultDC;
block_C = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][0] : DC_store_above[x_pos][Ytab[i]][0];
}
else if (y_pos == 0) /* top row */
{
block_A = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][0];
block_B = (i == 2 || i == 3) ? DC_store_curr[x_pos+Xpos[i] ][Ztab[i]][0] : defaultDC;
block_C = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][0] : defaultDC;
}
else
{
block_A = DC_store_curr[x_pos+Xpos[i] ][Xtab[i]][0];
block_B = (i == 2 || i == 3) ? (DC_store_curr[(x_pos+Xpos[i])][Ztab[i]][0]):
(DC_store_above[(x_pos+Xpos[i])][Ztab[i]][0]);
block_C = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][0] : DC_store_above[x_pos][Ytab[i]][0];
}
grad_hor = block_B - block_C;
grad_ver = block_A - block_B;
if ((ABS(grad_ver)) < (ABS(grad_hor)))
{
DC_pred = block_C;
direction[i] = 2;
}
else
{
DC_pred = block_A;
direction[i] = 1;
}
dc_scaler = cal_dc_scaler(QP,(i<4)?1:2);
diff_coeff[i][0] = qcoeff[i*ncoeffs] - (DC_pred+dc_scaler/2)/dc_scaler;//DC_pred must be positive for intra MB
if(acPredOutOfRange==0)
{
/* Find AC predictions */
if ((x_pos == 0) && (y_pos == 0)) /* top left corner */
{
if (i == 1 || i == 3)
for (m = 0; m < 15; m++)
pred_A[m] = DC_store_curr[0][Xtab[i]][m] ;
else
for (m = 1; m < 15; m++)
{
pred_A[m] = 0;
}
if (i == 2 || i == 3)
for (m = 0; m < 15; m++)
pred_C[m] = DC_store_curr[0][Ytab[i]][m];
else
for (m = 1; m < 15; m++)
{
pred_C[m] = 0;
}
}
else if (x_pos == 0) /* left edge */
{
if (i == 1 || i == 3)
for (m = 0; m < 15; m++)
pred_A[m] = DC_store_curr[0][Xtab[i]][m];
else
for (m = 1; m < 15; m++)
{
pred_A[m] = 0;
}
for (m = 0; m < 15; m++)
pred_C[m] = (i == 2 || i == 3) ? DC_store_curr[0][Ytab[i]][m] : DC_store_above[0][Ytab[i]][m];
}
else if (y_pos == 0) /* top row */
{
for (m = 0; m < 15; m++)
pred_A[m] = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][m];
if (i == 2 || i == 3)
for (m = 0; m < 15; m++)
pred_C[m] = DC_store_curr[x_pos][Ytab[i]][m];
else
for (m = 1; m < 15; m++)
{
pred_C[m] = 0;
}
}
else
{
for (m = 0; m < 15; m++)
{
pred_A[m] = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][m];
pred_C[m] = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][m] : DC_store_above[x_pos][Ytab[i]][m];
}
}
/* Now decide on AC prediction */
if (direction[i] == 1) /* Horizontal, left COLUMN of block A */
{
for (m = 0; m < 7; m++)
{
S1 += ABS(qcoeff[i*ncoeffs+(m+1)*8]);
diff =diff_coeff[i][m+8]
= qcoeff[i*ncoeffs+(m+1)*8] - pred_A[m+8];
//ldm I think the outOfRange should be done this way
if(ABS(diff)>127)
{ acPredOutOfRange=1;
break;
}
S2 += ABS(diff);
}
}
else /* Vertical, top ROW of block C */
{
for (m = 1; m < 8; m++)
{
S1 += ABS(qcoeff[i*ncoeffs+m]);
diff = diff_coeff[i][m]
= qcoeff[i*ncoeffs+m] - pred_C[m];
//ldm I think the outOfRange should be done this way
if(ABS(diff)>127)
{ acPredOutOfRange=1;
break;
}
S2 += ABS(diff);
}
}
S += (S1 - S2);
}
}
if( (S >= 0)&&(acPredOutOfRange==0) ) /* Both DC and AC prediction */
{
ACpred_flag = 1;
for(m=0;m<8;m++)
{
qcoeff[m] =diff_coeff[0][m];
qcoeff[64+m] =diff_coeff[1][m];
qcoeff[128+m]=diff_coeff[2][m];
qcoeff[192+m]=diff_coeff[3][m];
qcoeff[256+m]=diff_coeff[4][m];
qcoeff[320+m]=diff_coeff[5][m];
}
for(m=0;m<7;m++)
{
qcoeff[(m+1)*8] =diff_coeff[0][m+8];
qcoeff[ 64+(m+1)*8]=diff_coeff[1][m+8];
qcoeff[128+(m+1)*8]=diff_coeff[2][m+8];
qcoeff[192+(m+1)*8]=diff_coeff[3][m+8];
qcoeff[256+(m+1)*8]=diff_coeff[4][m+8];
qcoeff[320+(m+1)*8]=diff_coeff[5][m+8];
}
/* Update CBP for predicted coeffs. */
*CBP = FindCBP(qcoeff, MODE_INTRA, 64);
}
else /* Only DC prediction */
{
ACpred_flag = 0;
for (i = 0; i < 6; i++)
{
qcoeff[i*ncoeffs] = diff_coeff[i][0];
direction[i] = 0;
}
}
return ACpred_flag; /* To be put into bitstream */
}
void Bits_CountMB_combined(char Mode, char COD, char ACpred_flag,Int CBP, char vop_type)
{
char cbpy ,cbpc;
char MBtype=-1;
if ( Mode == MODE_INTRA ) MBtype = 3;//对宏块类型进行判断
if ( Mode == MODE_INTER ) MBtype = 0;
if ( Mode == MODE_INTRA_Q) MBtype = 4;
if ( Mode == MODE_INTER_Q) MBtype = 1;
if ( Mode == MODE_INTER4V) MBtype = 2;
if ( Mode == MODE_GMC) MBtype = 0;
if ( Mode == MODE_GMC_Q) MBtype = 1;
cbpc = CBP & 3;
cbpy = CBP>>2;
if (vop_type != PCT_INTRA )
{
//@ if (COD)
//@ {
//@ printf("COD = 1 in Bits_CountMB_combined \n");
//@ printf("This function should not be used if COD is '1' \n");
//@ exit(1);
//@ }
// if it is an interMB in PVOP, the COD here should be 0, if the COD is 1,
// it means the MB is not-coded, and the COD is put into stream outside of the function.
BitstreamPutBits((UInt)COD, 1L); /* COD */
}
/* MCBPC */
if (vop_type == PCT_INTRA)
PutMCBPC_Intra (cbpc, MBtype);
else
PutMCBPC_Inter (cbpc, MBtype);
/* MCSEL syntax for sprite */
//@ if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_GMC) || (Mode == MODE_GMC_Q)) && (vop_type == PCT_SPRITE))
//@ {
//@ if ((Mode == MODE_INTER) || (Mode == MODE_INTER_Q))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -