text_code.c
来自「实现在linux下的mpeg4编解码」· C语言 代码 · 共 981 行 · 第 1/2 页
C
981 行
free(DC_store); free ((Char*)qcoeff);}/***********************************************************CommentBegin****** * * -- Bits_CountMB_combined -- texture encoding for combined texture/motion * * Purpose : * Used for texture encoding in case of combined texture/motion * encoding. This function encodes the : * - COD flag * - MCBPC flag * - CBPY flag * - CBPC flag * - DQUANT information * * Arguments in : * SInt Mode : The macroblock encoding mode * Int CBP : Coded block pattern information * Int COD : Indicates whether this macroblock is coded or not * Int ACpred_flag * Int vop_type : indicates the picture coding type * (Intra,Inter) * * Arguments out : * Bits* bits : a structure counting the number of bits * Image *bitstream : output texture bit stream * * ***********************************************************CommentEnd********/Void Bits_CountMB_combined(Int DQUANT, Int Mode, Int COD, Int ACpred_flag,Int CBP, Int vop_type,Bits* bits, Image *mottext_bitstream,Int *MB_transp_pattern){ Int cbpy ,cbpc, length; Int 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; /* modified by NTT for GMC coding : start if ( Mode == MODE_DYN_SP) MBtype = 0; if ( Mode == MODE_DYN_SP_Q) MBtype = 1; */ if ( Mode == MODE_GMC) MBtype = 0; if ( Mode == MODE_GMC_Q) MBtype = 1; /* modified by NTT for GMC coding : end */ #ifdef D_TRACE fprintf(ftrace, "DQUANT : %d\tMODE : %d\tVop Type : %d\n", DQUANT, Mode, vop_type); fprintf(ftrace, "COD : %d\tCBP : %d\tAC Pred Flag : %d\n\n", COD, CBP, ACpred_flag); #endif cbpc = CBP & 3; cbpy = CBP>>2; /* COD */ 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); } /* write COD */ BitstreamPutBits(mottext_bitstream, (long)(COD), 1L); bits->COD++; } /* MCBPC */ if (vop_type == PCT_INTRA) length = PutMCBPC_Intra (cbpc, MBtype, mottext_bitstream); else length = PutMCBPC_Inter (cbpc, MBtype, mottext_bitstream); bits->MCBPC += length; /* MCSEL syntax */ /* modified by NTT for GMC coding : start if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q)) && (vop_type == PCT_SPRITE)) */ if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_GMC) || (Mode == MODE_GMC_Q)) && (vop_type == PCT_SPRITE)) /* modified by NTT for GMC coding : end */ { if ((Mode == MODE_INTER) || (Mode == MODE_INTER_Q)) BitstreamPutBits(mottext_bitstream, (long) 0, 1L); /* modified by NTT for GMC coding : start if ((Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q)) */ if ((Mode == MODE_GMC) || (Mode == MODE_GMC_Q)) /* modified by NTT for GMC coding : end */ BitstreamPutBits(mottext_bitstream, (long) 1, 1L); bits->MCBPC += 1; } /* ACpred_flag */ /* 17-Jan-97 JDL : correction no ACpred_flag in combined mode when intra_acdc_pred_disable is true */ if ((Mode == MODE_INTRA || Mode==MODE_INTRA_Q) && ACpred_flag != -1) { BitstreamPutBits(mottext_bitstream, (long)ACpred_flag, 1L); bits->ACpred_flag += 1; } /* CBPY */ length = PutCBPY (cbpy, (Char)(Mode==MODE_INTRA||Mode==MODE_INTRA_Q),/*MB_transp_pattern*/NULL,mottext_bitstream); bits->CBPY += length; /* DQUANT */ /* modified by NTT for GMC coding : start if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_DYN_SP_Q)) */ if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_GMC_Q)) /* modified by NTT for GMC coding : end */ { switch (DQUANT) { case -1: BitstreamPutBits(mottext_bitstream, 0L, 2L); break; case -2: BitstreamPutBits(mottext_bitstream, 1L, 2L); break; case 1: BitstreamPutBits(mottext_bitstream, 2L, 2L); break; case 2: BitstreamPutBits(mottext_bitstream, 3L, 2L); break; default: fprintf(stderr,"Invalid DQUANT\n"); exit(1); } bits->DQUANT += 2; }}/***********************************************************CommentBegin****** * * -- doDCACpred -- Does DC/AC prediction. Changes qcoeff values as * appropriate. * * Purpose : * Does DC/AC prediction. Changes qcoeff values as appropriate. * * Arguments in : * Int CBP * Int ncoeffs * Int x_pos * Int y_pos * Int DC_store[][6][15] Stores coefficient values per MB for * prediction (for one Vop) * Int QP QP value for this MB * Int MB_width * * Arguments in/out : * Int *qcoeff * * Return values : * Int The ACpred_flag, which is to be put into the bitstream * * Side effects : * Modifies qcoeff if needed for the prediction. * ***********************************************************CommentEnd********/Int doDCACpred(Int *qcoeff, Int *CBP, Int ncoeffs, Int x_pos, Int y_pos,Int ***DC_store, Int QP, Int MB_width,Int direction[], Int mid_grey ){ Int i, m; Int block_A, block_B, block_C; Int Xpos[6] = {-1, 0, -1, 0, -1, -1}; Int Ypos[6] = {-1, -1, 0, 0, -1, -1}; Int Xtab[6] = {1, 0, 3, 2, 4, 5}; Int Ytab[6] = {2, 3, 0, 1, 4, 5}; Int Ztab[6] = {3, 2, 1, 0, 4, 5}; Int grad_hor, grad_ver, DC_pred; Int pred_A[15], pred_C[15]; Int S = 0, S1, S2; Int diff; Int pcoeff[384]; Int ACpred_flag=-1; /* Copy qcoeff to the prediction array pcoeff */ for (i = 0; i < (6*ncoeffs); i++) { pcoeff[i] = qcoeff[i]; } for (i = 0; i < 6; i++) { if ((x_pos == 0) && y_pos == 0) /* top left corner */ { block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8; block_B = (i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8; block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8; } else if (x_pos == 0) /* left edge */ { block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8; block_B = (i == 1 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8; block_C = DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0]; } else if (y_pos == 0) /* top row */ { block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0]; block_B = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8; block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8; } else { block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0]; block_B = (DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])] [Ztab[i]][0]); block_C = DC_store[(y_pos+Ypos[i])*MB_width+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; } pcoeff[i*ncoeffs] = qcoeff[i*ncoeffs] - (DC_pred+cal_dc_scaler(QP,(i<4)?1:2)/2)/cal_dc_scaler(QP,(i<4)?1:2); /* 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] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP); else nullfill(pred_A,mid_grey); if (i == 2 || i == 3) for (m = 0; m < 15; m++) pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP); else nullfill(pred_C,mid_grey); } else if (x_pos == 0) /* left edge */ { if (i == 1 || i == 3) for (m = 0; m < 15; m++) pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP); else nullfill(pred_A,mid_grey); for (m = 0; m < 15; m++) pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP); } else if (y_pos == 0) /* top row */ { for (m = 0; m < 15; m++) pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP); if (i == 2 || i == 3) for (m = 0; m < 15; m++) pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP); else nullfill(pred_C,mid_grey); } else { for (m = 0; m < 15; m++) { pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP); pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP); } } #if 1 /* I think it should be like this, 14-NOV-1996 MW */ S1 = 0; S2 = 0; /* 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 = pcoeff[i*ncoeffs+(m+1)*8] = qcoeff[i*ncoeffs+(m+1)*8] - pred_A[m+8]; S2 += ABS(diff); } } else /* Vertical, top ROW of block C */ { for (m = 1; m < 8; m++) { S1 += ABS(qcoeff[i*ncoeffs+m]); diff = pcoeff[i*ncoeffs+m] = qcoeff[i*ncoeffs+m] - pred_C[m]; S2 += ABS(diff); } } S += (S1 - S2); #endif } /* Now change qcoeff for DC pred or DC/AC pred */ if (S >=0) { for (i=0;i<ncoeffs*6; i++) /* Modified due to N2171 Cl. 2.2.14 MW 25-MAR-1998 */ /* if ((i%64)&&(abs(pcoeff[i])>127)) { */ if ((i%64)&&(abs(pcoeff[i])>2047)) { printf("predicted AC out of range"); S=-1;break; } } if (S >= 0) /* Both DC and AC prediction */ { ACpred_flag = 1; for (i = 0; i < ncoeffs*6; i++) { qcoeff[i] = pcoeff[i]; } /* 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] = pcoeff[i*ncoeffs]; direction[i] = 0; } } return ACpred_flag; /* To be put into bitstream */}/** * Small routine to fill default prediction values into a DC_store entry */Void nullfill(Int pred[], Int mid_grey){ Int i; pred[0] = mid_grey*8; for (i = 1; i < 15; i++) { pred[i] = 0; }}Int Idir_c(Int val, Int QP){ if (val<0) return (val-QP/2)/QP; else return (val+QP/2)/QP;}/***********************************************************CommentBegin****** * * -- IntraDCSwitch_decisions -- * * Purpose : * decide whether to use inter AC table to encode DC * * Arguments in : * Int Mode * Int intra_dc_vlc_thr * Int Qp * ***********************************************************CommentEnd********/Int IntraDCSwitch_Decision(Int Mode,Int intra_dc_vlc_thr,Int Qp){ Int switched =0; if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { if (intra_dc_vlc_thr==0) switched=0; else if (intra_dc_vlc_thr==7) switched=1; else if (Qp>=intra_dc_vlc_thr*2+11) switched=1; } return switched;}/***********************************************************CommentBegin****** * * -- cal_dc_scaler -- calculation of DC quantization scale according * to the incoming Q and type; * * Arguments in : * Int Qp * ***********************************************************CommentEnd********/Int cal_dc_scaler (Int QP, Int type){ Int 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;}/***********************************************************CommentBegin****** * * -- FindCBP -- Find the CBP for a macroblock * * Purpose : * Find the CBP for a macroblock * * Arguments in : * Int *qcoeff : pointer to quantized coefficients * Int Mode : macroblock encoding mode information * Int ncoeffs : the number of coefficients * * Return values : * Int CBP : The coded block pattern for a macroblock * ***********************************************************CommentEnd********/IntFindCBP (Int* qcoeff, Int Mode, Int ncoeffs){ Int i,j; Int CBP = 0; Int 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 if (i == 5) {CBP |= 1;} else { fprintf (stderr, "Error in CBP assignment\n"); exit(-1); } break; } } } return CBP;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?