⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ei_picture.c

📁 H.263的压缩算法
💻 C
字号:
/************************************************************************ * *  coder.c, main coding engine of tmn (TMN encoder) * *  Copyright (C) 1997  University of BC, Canada * *  Contacts:  *  Michael Gallant                   <mikeg@ee.ubc.ca> *  Guy Cote                          <guyc@ee.ubc.ca> *  Berna Erol                        <bernae@ee.ubc.ca> * *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image *  2356 Main Mall                    tel.: +1 604 822 4051 *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949 * ************************************************************************//* * Disclaimer of Warranty * * These software programs are available to the user without any * license fee or royalty on an "as is" basis. The University of * British Columbia disclaims any and all warranties, whether * express, implied, or statuary, including any implied warranties * or merchantability or of fitness for a particular purpose.  In no * event shall the copyright-holder be liable for any incidental, * punitive, or consequential damages of any kind whatsoever arising * from the use of these programs. * * This disclaimer of warranty extends to the user of these programs * and user's customers, employees, agents, transferees, successors, * and assigns. * * The University of British Columbia does not represent or warrant * that the programs furnished hereunder are free of infringement of * any third-party patents. * * Commercial implementations of H.263, including shareware, are * subject to royalty fees to patent holders.  Many of these patents * are general enough such that they are unavoidable regardless of * implementation design. **/#include"sim.h"/********************************************************************** * *	Name:         CodeOneEI *	Description:  codes one image intra *	 *	Input:        pointer to image, QP *         *	Returns:      pointer to reconstructed image *	Side effects: memory is allocated to recon image * *	Date: 940110  Author: Michael Gallant	mikeg@ee.ubc.ca * ***********************************************************************/void CodeOneEI(PictImage *curr_image, PictImage *pr,                      int QP, Bits *bits, Pict *pic, PictImage *recon){  MB_Structure *diff = (MB_Structure *)malloc(sizeof(MB_Structure));  MB_Structure *recon_data_ei = (MB_Structure *)malloc(sizeof(MB_Structure));  PictImage *base_recon=NULL, *base_recon_edge=NULL;  int *qcoeff, *pcoeff, *rcoeff, *coeff;  int Mode = MODE_INTER;  int CBP;  int i,j,k;  int *store_coeff, *store_rcoeff; /* used to do prediction in advanced intra coding */  int newgob = 0;  int ei_prediction_type;  unsigned char *base_ipol, *bi;  int advanced_temporarily_off = DEF_AIC_MODE;  /* buffer control vars */  float QP_cumulative = (float)0.0;  int abs_mb_num = 0, QuantChangePostponed = 0;  int QP_new, QP_prev, QP_xmitted=QP;    ZeroBits(bits);  GenerateFrameAndInterpolatedImages(pr, pic, &base_ipol, &base_recon, &bi, &base_recon_edge);  if (adv_pred)  {    /* Turn off advanced coding since there can be only 1      * motion vector for B frames of IPB. */    advanced_temporarily_off = YES;    overlapping_MC = OFF;    adv_pred = OFF;    use_4mv = OFF;  }  QP_new = QP_xmitted = QP_prev = QP; /* Copy the passed value of QP */  for ( j = 0; j < lines/MB_SIZE; j++)   {    newgob = 0;    if (j == 0)     {      if (advanced_intra_coding)      {         /* store the coeff for the frame */         if ((store_coeff=(int *)calloc(384*(pels/MB_SIZE)*(lines/MB_SIZE), sizeof(int))) == 0)          {            fprintf(stderr,"coder(): Couldn't allocate store_coeff.\n");            exit(-1);         }         if ((store_rcoeff=(int *)calloc(384*(pels/MB_SIZE)*(lines/MB_SIZE), sizeof(int))) == 0)          {            fprintf(stderr,"coder(): Couldn't allocate store_rcoeff.\n");            exit(-1);         }      }      pic->QUANT = QP_new;      bits->header += CountBitsPicture(pic);      QP_xmitted = QP_prev = QP_new;    }    else if (pic->use_gobsync && j%pic->use_gobsync == 0)     {      bits->header += CountBitsGOB(j,QP_new,pic); /* insert gob sync */      QP_xmitted = QP_prev = QP_new;      newgob = 1;    }     for ( i = 0; i < pels/MB_SIZE; i++)     {      pic->MB = i + j * (pels/MB_SIZE);            /* store the QP for every macroblock */      quant_map[j+1][i+1] = QP_xmitted;      if ((rcoeff = (int *)malloc(sizeof(int)*384)) == NULL)       {        fprintf(stderr,"MB_Coder: Could not allocate space for rcoeff\n");        exit(-1);      }        /* Predict true B-MB */      diff = Predict_EI( curr_image, base_recon, base_ipol,                          i*MB_SIZE, j*MB_SIZE,                         &ei_prediction_type, &Mode, pic->RTYPE);            if (EI_INTRA_PREDICTION == ei_prediction_type)      {        FillLumBlock(i*MB_SIZE, j*MB_SIZE, curr_image, diff);        FillChromBlock(i*MB_SIZE, j*MB_SIZE, curr_image, diff);      }      if ((qcoeff=(int *)malloc(sizeof(int)*384)) == 0)       {        fprintf(stderr,"coder(): Couldn't allocate qcoeff.\n");        exit(-1);      }      coeff = MB_Encode(diff);      if (advanced_intra_coding)       {	        if (!(Mode == MODE_INTRA || Mode == MODE_INTRA_Q))         {          for (k=0;k<6;k++)           {                /* store default coeff if non-intra macroblock */            store_coeff[(i + j * pels/MB_SIZE) * 384 + k * 64] = 1024;            store_rcoeff[(i + j * pels/MB_SIZE) * 384 + k * 64] = 1024;          }          for (k=0;k<6;k++)            Quant_blk(coeff,qcoeff,QP_xmitted, Mode,k);          CBP = FindCBP(qcoeff, Mode, 64);          if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q))             ZeroMBlock(diff);          else          {              for (k=0;k<6;k++)            {              Quant_blk(coeff,qcoeff,QP_xmitted, Mode,k);              Dequant(qcoeff, rcoeff, QP_xmitted, Mode,k);            }            MB_Decode(rcoeff, diff);          }        }        else         {          if ((pcoeff=(int *)malloc(sizeof(int)*384)) == 0)           {            fprintf(stderr,"coder(): Couldn't allocate pcoeff.\n");            exit(-1);          }          /* store the quantized DCT coefficients */          memcpy( (void *) (store_coeff + (i + j*pels/MB_SIZE)*384), (void *) coeff, sizeof(int) * 384);          /* Do Intra mode prediction */          pic->Intra_Mode = Choose_Intra_Mode(pcoeff, store_coeff, i, j, newgob);          for (k=0;k<6;k++)           {             Intra_AC_DC_Encode(coeff, store_rcoeff, pic->Intra_Mode, i, j, newgob,k);            Quant_blk(coeff,pcoeff,QP_xmitted,Mode,k);            Dequant(pcoeff, rcoeff, QP_xmitted, Mode,k);            Intra_AC_DC_Decode(rcoeff, store_rcoeff, pic->Intra_Mode, i, j, newgob,k);          }          MB_Decode(rcoeff, diff);          CBP = FindCBP(pcoeff,Mode,64);        }          }      else      {          for (k=0;k<6;k++)          Quant_blk(coeff,qcoeff,QP_xmitted, Mode,k);        CBP = FindCBP(qcoeff, Mode, 64);        if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q))           ZeroMBlock(diff);        else        {          for (k=0;k<6;k++)              Dequant(qcoeff, rcoeff, QP_xmitted, Mode,k);           MB_Decode(rcoeff, diff);        }      }      recon_data_ei = MB_Recon_EI( base_recon, base_ipol, diff,                                    i*MB_SIZE,j*MB_SIZE,                                   ei_prediction_type, pic->RTYPE);      Clip(recon_data_ei);      free(diff);      free(coeff);      if (!CBP)        intra_refresh[j+1][i+1] += 1;      if ((CBP==0) && (EI_UPWARD_PREDICTION == ei_prediction_type) &&          (Mode == MODE_INTER) && (0 == pic->DQUANT) )       {        coded_map[j+1][i+1] = 0;        quant_map[j+1][i+1] = 0;        CountBitsScalMB(Mode, 1, CBP, 0, pic, bits, ei_prediction_type, 0);      }      else       {        CountBitsScalMB(Mode,0,CBP,0,pic,bits,ei_prediction_type, 0);        if (MODE_INTER == Mode || MODE_INTER_Q == Mode)        {          coded_map[j+1][i+1] = 1;          quant_map[j+1][i+1] = QP_xmitted;          bits->no_inter++;        }        else         {          /* MODE_INTRA or MODE_INTRA_Q */          coded_map[j+1][i+1] = 2;          quant_map[j+1][i+1] = QP_xmitted;          intra_refresh[j+1][i+1] = 0;          bits->no_intra++;        }                 if ( (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) && advanced_intra_coding )        {          Scan(pcoeff,pic->Intra_Mode);	  CountBitsCoeff(pcoeff, Mode, CBP, bits, 64);        }        else if (CBP || Mode == MODE_INTRA || Mode == MODE_INTRA_Q)        {          Scan(qcoeff,0);          CountBitsCoeff(qcoeff, Mode, CBP, bits, 64);        }      }      QP_prev = QP_xmitted;          abs_mb_num++;      QP_cumulative += QP_xmitted;     #ifdef PRINTQ       /* most useful when quantizer changes within a picture */      if (QuantChangePostponed)        fprintf(stdout,"@%2d",QP_xmitted);      else        fprintf(stdout," %2d",QP_xmitted);#endif      ReconImage(i,j,recon_data_ei,recon);       free(qcoeff);      free(recon_data_ei);      if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))          free(pcoeff);    }#ifdef PRINTQ    fprintf(stdout,"\n");#endif  }  pic->QP_mean = QP_cumulative/(float)abs_mb_num;  /* Free memory */  free(base_recon);  FreeImage(base_recon_edge);  free(bi);  if (advanced_intra_coding)  {    free(store_coeff);    free(store_rcoeff);  }  if (advanced_temporarily_off)  {    overlapping_MC = ON;    adv_pred = ON;    use_4mv = ON;    advanced_temporarily_off = NO;  }  return;}/*********************************************************************** * *	Name:           Predict_EI *	Description:    Predicts macroblock in EI picture  * *	Input:	        pointers to current frame, base recon. base *                      interpolated, pos. in image, MV data,  *                      and MB prediction type. *	Returns:        pointer to differential MB data after prediction *	Side effects: * *	Date: 970831    Author: Michael Gallant ---mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *Predict_EI( PictImage *curr_image, PictImage *base_recon,                           unsigned char *base_ipol, int x, int y,                          int *prediction_type , int *mode, int RTYPE){  int curr[16][16];  MB_Structure *upward_pred = (MB_Structure *)malloc(sizeof(MB_Structure));  MB_Structure *pred_error = (MB_Structure *) malloc (sizeof (MB_Structure));  MotionVector ZERO = {0,0,0,0,0};  int i,j;  int SADup;  /* Find MB in current image */  FindMB (x, y, curr_image->lum, curr);  /* Find predicted MB for current MB (upward prediction so MV=0 */  FindPred (x, y, &ZERO, base_ipol, &upward_pred->lum[0][0], 16, 0);  SADup = SAD_MB_integer (&curr[0][0], &upward_pred->lum[0][0], 16, INT_MAX);  SADup -= 150;  *(mode) = ChooseMode( curr_image->lum, x, y, SADup);                                  if (MODE_INTRA == *(mode) || MODE_INTRA_Q == *(mode))   {    *(prediction_type) = EI_INTRA_PREDICTION;  }  else  {    *(prediction_type) = EI_UPWARD_PREDICTION;  }  switch (*(prediction_type))  {    case EI_UPWARD_PREDICTION:          DoPredChrom_P (x, y, 0, 0, curr_image, base_recon, upward_pred, pred_error, RTYPE);          for (j = 0; j < MB_SIZE; j++)      {        for (i = 0; i < MB_SIZE; i++)        {           pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) -                                     upward_pred->lum[j][i];        }      }      break;    case EI_INTRA_PREDICTION:       break;    default:       break;  }  free (upward_pred);  return pred_error;}/*********************************************************************** * *	Name:           MB_Recon_EI *	Description:    Reconstructs EI macroblocks * *	Input:	         *	Returns:        pointer to differential MB data after prediction *	Side effects: * *	Date: 970831    Author: Michael Gallant ---mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *MB_Recon_EI( PictImage *base_recon, unsigned char *base_ipol,                            MB_Structure *diff, int x, int y,                           int prediction_type, int RTYPE){  MB_Structure *upward = (MB_Structure *) malloc (sizeof (MB_Structure));  MB_Structure *recon_data = (MB_Structure *) malloc (sizeof (MB_Structure));  MotionVector ZERO = {0,0,0,0,0};  switch (prediction_type)  {    case EI_UPWARD_PREDICTION:      /* Inter 16x16 */      ReconLumBlock_P (x, y, &ZERO, base_ipol, &diff->lum[0][0], 16, 0);      ReconChromBlock_P (x, y, 0, 0, base_recon, diff, RTYPE);      break;    case EI_INTRA_PREDICTION:          break;    default:      fprintf (stderr, "Illegal scalable prediction type in MB_Recon_EP (pred.c)\n");      exit (-1);      break;  }  memcpy (recon_data, diff, sizeof (MB_Structure));  free (upward);  return recon_data;}                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -