text_code.c
上传用户:enenge
上传日期:2007-01-08
资源大小:96k
文件大小:28k
- /**************************************************************************
- * *
- * This code is developed by Adam Li. This software is an *
- * implementation of a part of one or more MPEG-4 Video tools as *
- * specified in ISO/IEC 14496-2 standard. Those intending to use this *
- * software module in hardware or software products are advised that its *
- * use may infringe existing patents or copyrights, and any such use *
- * would be at such party's own risk. The original developer of this *
- * software module and his/her company, and subsequent editors and their *
- * companies (including Project Mayo), will have no liability for use of *
- * this software or modifications or derivatives thereof. *
- * *
- * Project Mayo gives users of the Codec a license to this software *
- * module or modifications thereof for use in hardware or software *
- * products claiming conformance to the MPEG-4 Video Standard as *
- * described in the Open DivX license. *
- * *
- * The complete Open DivX license can be found at *
- * http://www.projectmayo.com/opendivx/license.php . *
- * *
- **************************************************************************/
- /**************************************************************************
- *
- * text_code.c
- *
- * Copyright (C) 2001 Project Mayo
- *
- * Adam Li
- *
- * DivX Advance Research Center <darc@projectmayo.com>
- *
- **************************************************************************/
- /* This file contains some functions for text coding of image. */
- /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
- /* Please see seperate acknowledgement file for a list of contributors. */
- #include "text_defs.h"
- #include "mot_code.h"
- #include "bitstream.h"
- #include "putvlc.h"
- #include "mot_util.h"
- #include "text_code_mb.h"
- #include "text_code.h"
- #define SKIPP 6
- extern FILE *ftrace;
- 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 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
- );
- Void nullfill(Int pred[], Int mid_grey);
- Int Idir_c(Int val, Int QP);
- Int IntraDCSwitch_Decision _P_(( Int Mode,
- Int intra_dc_vlc_thr,
- Int Qp
- ));
- Int FindCBP _P_(( Int *qcoeff,
- Int Mode,
- Int ncoeffs
- ));
- /***********************************************************CommentBegin******
- *
- * -- VopCodeShapeTextIntraCom --Intra texture encoding of one vop,
- * Combined shape/(motion)/texture mode
- *
- * Purpose :
- * Intra texture encoding of one vop (combined shape/(mot)/text mode)
- *
- * Arguments in :
- * Vop curr : the current vop to be coded
- * Int intra_dcpred_disable : disable intradc prediction
- * Image* AB_SizeConversionDecisions:
- * Image* AB_first_MMR_values
- * VolConfig *vol_config : configuration information
- * Int rc_type : rate control type:
- *
- * Arguments out :
- * Vop *rec_curr : the reconstructed current vop
- * Image *texture_bitstream : the output bitstream
- * Bits : statistics information
- *
- * Description :
- * This function performs Intra texture encoding of one vop.
- *
- ***********************************************************CommentEnd********/
- Void VopCodeShapeTextIntraCom(Vop *curr,
- Vop *rec_curr, Image *mottext_bitstream)
- {
- Int QP = GetVopIntraQuantizer(curr);
- Int Mode = MODE_INTRA;
- Int* qcoeff;
- Int i, j;
- Int CBP, COD;
- Int CBPY, CBPC;
- Int num_pixels = GetImageSizeX(GetVopY(curr));
- Int num_lines = GetImageSizeY(GetVopY(curr));
- Int vop_type;
- Int ***DC_store;
- Int MB_width = num_pixels / MB_SIZE;
- Int MB_height = num_lines / MB_SIZE;
- Int m;
- Int ACpred_flag=-1;
- Int direction[6];
- Int switched=0;
- Int DQUANT =0;
- Bits nbits, *bits;
- bits = &nbits;
- qcoeff = (Int *) malloc (sizeof (Int) * 384);
- #ifdef _RC_DEBUG_
- fprintf(ftrace, "RC - VopCodeShapeTextIntraCom(): ---> CODING WITH: %d n",QP);
- #endif
- for (i = 0; i < 6; i++)
- direction[i] = 0;
- /* allocate space for 3D matrix to keep track of prediction values
- for DC/AC prediction */
- DC_store = (Int ***)calloc(MB_width*MB_height, sizeof(Int **));
- for (i = 0; i < MB_width*MB_height; i++)
- {
- DC_store[i] = (Int **)calloc(6, sizeof(Int *));
- for (j = 0; j < 6; j++)
- DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
- }
- Bits_Reset (bits);
- vop_type = PCT_INTRA;
- for (j = 0; j < num_lines/MB_SIZE; j++) /* Macro Block loop */
- {
- for (i = 0; i < num_pixels/MB_SIZE; i++)
- {
- DQUANT = 0;
- COD = 0;
- bits->no_intra++;
- CodeMB (curr, rec_curr, NULL, i*MB_SIZE, j*MB_SIZE,
- num_pixels, QP+DQUANT, MODE_INTRA, qcoeff);
- m =0;
- DC_store[j*MB_width+i][0][m] = qcoeff[m]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_width+i][1][m] = qcoeff[m+64]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_width+i][2][m] = qcoeff[m+128]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_width+i][3][m] = qcoeff[m+192]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_width+i][4][m] = qcoeff[m+256]*cal_dc_scaler(QP+DQUANT,2);
- DC_store[j*MB_width+i][5][m] = qcoeff[m+320]*cal_dc_scaler(QP+DQUANT,2);
-
- for (m = 1; m < 8; m++)
- {
- DC_store[j*MB_width+i][0][m] = qcoeff[m];
- DC_store[j*MB_width+i][1][m] = qcoeff[m+64];
- DC_store[j*MB_width+i][2][m] = qcoeff[m+128];
- DC_store[j*MB_width+i][3][m] = qcoeff[m+192];
- DC_store[j*MB_width+i][4][m] = qcoeff[m+256];
- DC_store[j*MB_width+i][5][m] = qcoeff[m+320];
- }
- for (m = 0; m < 7; m++)
- {
- DC_store[j*MB_width+i][0][m+8] = qcoeff[(m+1)*8];
- DC_store[j*MB_width+i][1][m+8] = qcoeff[(m+1)*8+64];
- DC_store[j*MB_width+i][2][m+8] = qcoeff[(m+1)*8+128];
- DC_store[j*MB_width+i][3][m+8] = qcoeff[(m+1)*8+192];
- DC_store[j*MB_width+i][4][m+8] = qcoeff[(m+1)*8+256];
- DC_store[j*MB_width+i][5][m+8] = qcoeff[(m+1)*8+320];
- }
- CBP = FindCBP(qcoeff,Mode,64);
- /* Do the DC/AC prediction, changing the qcoeff values as
- appropriate */
- if (GetVopIntraACDCPredDisable(curr) == 0)
- {
- ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store,
- QP+DQUANT, MB_width,
- direction,GetVopMidGrey(curr));
- }
- else
- ACpred_flag = -1;
- switched = IntraDCSwitch_Decision(Mode,
- GetVopIntraDCVlcThr(curr),
- QP);
- if (switched)
- CBP = FindCBP(qcoeff,MODE_INTER,64);
- if (DQUANT) Mode=MODE_INTRA_Q;else Mode=MODE_INTRA;
- QP+=DQUANT;
- CBPY = CBP >> 2;
- CBPY = CBPY & 15; /* last 4 bits */
- CBPC = CBP & 3; /* last 2 bits */
- Bits_CountMB_combined (DQUANT, Mode, COD, ACpred_flag, CBP,
- vop_type,
- bits, mottext_bitstream,/*MB_transp_pattern*/NULL);
- /* added the variable intra_dcpred_diable */
- MB_CodeCoeff(bits, qcoeff, Mode, CBP, 64,
- GetVopIntraACDCPredDisable(curr),
- NULL, mottext_bitstream,
- /*MB_transp_pattern*/NULL, direction,
- 1 /*GetVopErrorResDisable(curr)*/,
- 0 /*GetVopReverseVlc(curr)*/,
- switched,
- 0 /*curr->alternate_scan*/);
- }
- }
- /* Free allocated memory for 3D matrix */
- for (i = 0; i < MB_width*MB_height; i++)
- {
- for (j = 0; j < 6; j++)
- free(DC_store[i][j]);
- free(DC_store[i]);
- }
- free(DC_store);
- free ((Char*)qcoeff);
- }
- /***********************************************************CommentBegin******
- *
- * -- VopShapeMotText -- Combined Inter encoding of shape motion and texture
- *
- * Purpose :
- * Combined Inter encoding of texture and motion.
- * Used by VopCodeMotTextInter
- *
- * Arguments in :
- * Vop *curr : the current vop to be encoded
- * Vop *rec_prev: the previous reconstructed vop
- * Image *mot_x : the x-coordinates of the motion vectors
- * Image *mot_y : the y-coordinates of the motion vectors
- * Image *MB_decisions: Contains for each macroblock the encoding mode
- * Int f_code_for: MV search range 1/2 pel: 1=32,2=64,...,7=2048
- * Image* AB_SizeConversionDecisions:
- * Image* AB_first_MMR_values :
- * Int intra_dcpred_disable : disable the intra dc prediction
- * VolConfig *vol_config : configuration information
- * Int rc_type : rate control type
- *
- * Arguments out :
- * Vop *rec_curr : the reconstructed current vop
- * Image *mottext_bitstream : the output texture/motion bitstream
- * Bits *bits : Coding statistics
- *
- ***********************************************************CommentEnd********/
- Void VopShapeMotText (Vop *curr, Vop *comp,
- Image *MB_decisions, Image *mot_x, Image *mot_y,
- Int f_code_for,
- Int intra_acdc_pred_disable,
- Vop *rec_curr,
- Image *mottext_bitstream
- )
- {
- Int Mode=0;
- Int QP = GetVopQuantizer(curr);
- Int* qcoeff=NULL;
- Int i, j;
- Int CBP;
- Int COD;
- Int CBPY, CBPC;
- Int MB_in_width, MB_in_height, B_in_width, mbnum, boff;
- SInt p;
- SInt *ptr=NULL;
- Float *motx_ptr=NULL, *moty_ptr=NULL;
- Int num_pixels;
- Int num_lines;
- Int vop_type=PCT_INTER;
- Int ***DC_store=NULL;
- Int m, n;
- Int ACpred_flag=-1;
- Int direction[6];
- Int switched=0;
- Int DQUANT=0;
- Bits nbits, *bits;
- bits = &nbits;
- qcoeff = (Int *) malloc (sizeof (Int) * 384);
- num_pixels = GetImageSizeX(GetVopY(curr));
- num_lines = GetImageSizeY(GetVopY(curr));
- MB_in_width = num_pixels / MB_SIZE;
- MB_in_height = num_lines / MB_SIZE;
- B_in_width = 2 * MB_in_width;
- for (i = 0; i < 6; i++) direction[i] = 0;
- #ifdef _RC_DEBUG_
- printf("RC - VopShapeMotText(): ---> CODING WITH: %d n",QP);
- #endif
- /* allocate space for 3D matrix to keep track of prediction values
- for DC/AC prediction */
- DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
- sizeof(Int **));
- for (i = 0; i < MB_in_width*MB_in_height; i++)
- {
- DC_store[i] = (Int **)calloc(6, sizeof(Int *));
- for (j = 0; j < 6; j++)
- DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
- }
- Bits_Reset (bits);
- vop_type = PCT_INTER;
- ptr = (SInt *) GetImageData(MB_decisions);
- motx_ptr = (Float *) GetImageData(mot_x);
- moty_ptr = (Float *) GetImageData(mot_y);
- for (j = 0; j < num_lines/MB_SIZE; j++)
- {
- for (i = 0; i < MB_in_width; i++)
- {
- switched=0;
- p = *ptr;
- DQUANT = 0;
- /* Fill DC_store with default coeff values */
- for (m = 0; m < 6; m++)
- {
- DC_store[j*MB_in_width+i][m][0] = GetVopMidGrey(curr)*8;
- for (n = 1; n < 15; n++)
- DC_store[j*MB_in_width+i][m][n] = 0;
- }
- switch (p)
- {
- case MBM_INTRA:
- Mode = (DQUANT == 0) ? MODE_INTRA : MODE_INTRA_Q;
- bits->no_intra++;
- break;
- case MBM_INTER16:
- Mode = (DQUANT == 0) ? MODE_INTER : MODE_INTER_Q;
- bits->no_inter++;
- break;
- case MBM_INTER8:
- Mode = MODE_INTER4V;
- bits->no_inter4v++;
- DQUANT = 0; /* Can't change QP for 8x8 mode */
- break;
- default:
- printf("invalid MB_decision value :%dn", p);
- exit(0);
- }
- CodeMB (curr, rec_curr, comp, i*MB_SIZE, j*MB_SIZE,
- num_pixels, QP + DQUANT, Mode, qcoeff);
- mbnum = j*MB_in_width + i;
- boff = (2 * (mbnum / MB_in_width) * B_in_width
- + 2 * (mbnum % MB_in_width));
- CBP = FindCBP(qcoeff,Mode,64);
- if ((CBP == 0) && (p == 1) && (*(motx_ptr +boff) == 0.0)
- && (*(moty_ptr +boff) == 0.0))
- {
- COD = 1; /* skipped macroblock */
- BitstreamPutBits(mottext_bitstream, (long) (COD), 1L);
- bits->COD ++;
- *ptr = SKIPP;
- Mode = MODE_INTER;
- }
- else
- {
- COD = 0; /* coded macroblock */
- if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
- {
- /* Store the qcoeff-values needed later for prediction */
- m =0;
- DC_store[j*MB_in_width+i][0][m] = qcoeff[m]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_in_width+i][1][m] = qcoeff[m+64]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_in_width+i][2][m] = qcoeff[m+128]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_in_width+i][3][m] = qcoeff[m+192]*cal_dc_scaler(QP+DQUANT,1);
- DC_store[j*MB_in_width+i][4][m] = qcoeff[m+256]*cal_dc_scaler(QP+DQUANT,2);
- DC_store[j*MB_in_width+i][5][m] = qcoeff[m+320]*cal_dc_scaler(QP+DQUANT,2);
- for (m = 1; m < 8; m++)
- {
- DC_store[j*MB_in_width+i][0][m] = qcoeff[m];
- DC_store[j*MB_in_width+i][1][m] = qcoeff[m+64];
- DC_store[j*MB_in_width+i][2][m] = qcoeff[m+128];
- DC_store[j*MB_in_width+i][3][m] = qcoeff[m+192];
- DC_store[j*MB_in_width+i][4][m] = qcoeff[m+256];
- DC_store[j*MB_in_width+i][5][m] = qcoeff[m+320];
- }
- for (m = 0; m < 7; m++)
- {
- DC_store[j*MB_in_width+i][0][m+8] = qcoeff[(m+1)*8];
- DC_store[j*MB_in_width+i][1][m+8] = qcoeff[(m+1)*8+64];
- DC_store[j*MB_in_width+i][2][m+8] = qcoeff[(m+1)*8+128];
- DC_store[j*MB_in_width+i][3][m+8] = qcoeff[(m+1)*8+192];
- DC_store[j*MB_in_width+i][4][m+8] = qcoeff[(m+1)*8+256];
- DC_store[j*MB_in_width+i][5][m+8] = qcoeff[(m+1)*8+320];
- }
- if (intra_acdc_pred_disable == 0)
- ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j,
- DC_store,
- QP+DQUANT, MB_in_width,
- direction,GetVopMidGrey(curr));
- else
- ACpred_flag = -1; /* Not to go into bitstream */
- }
- switched = IntraDCSwitch_Decision(Mode,
- GetVopIntraDCVlcThr(curr),
- QP);
- if (switched)
- CBP = FindCBP(qcoeff,MODE_INTER,64);
- CBPY = CBP >> 2;
- CBPY = CBPY & 15; /* last 4 bits */
- CBPC = CBP & 3; /* last 2 bits */
- Bits_CountMB_combined (DQUANT, Mode, COD, ACpred_flag, CBP,
- vop_type, bits,
- mottext_bitstream,/*MB_transp_pattern*/NULL);
- Bits_CountMB_Motion( mot_x, mot_y, NULL,
- MB_decisions, i, j, f_code_for, 0 /*quarter_pel*/,
- mottext_bitstream,
- 1 /*GetVopErrorResDisable(curr)*/, 0,
- (Int **)NULL, 0 /*GetVopShape(curr)*/);
- MB_CodeCoeff(bits, qcoeff, Mode, CBP, 64,
- intra_acdc_pred_disable,
- NULL, mottext_bitstream,
- /*MB_transp_pattern*/NULL, direction,
- 1/*GetVopErrorResDisable(curr)*/,
- 0/*GetVopReverseVlc(curr)*/,
- switched,
- 0 /*curr->alternate_scan*/);
- }
- ptr++;
- } /* for i loop */
- } /* for j loop */
- /* Free allocated memory for 3D matrix */
- for (i = 0; i < MB_in_width*MB_in_height; i++)
- {
- for (j = 0; j < 6; j++)
- free(DC_store[i][j]);
- free(DC_store[i]);
- }
- 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 : %dtMODE : %dtVop Type : %dn", DQUANT, Mode, vop_type);
- fprintf(ftrace, "COD : %dtCBP : %dtAC Pred Flag : %dnn", 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 DQUANTn");
- 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********/
- Int
- FindCBP (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 assignmentn");
- exit(-1);
- }
- break;
- }
- }
- }
- return CBP;
- }