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

📄 b_picture.c

📁 H.263的压缩算法
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************ * *  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:         CodeOneTrueB *	Description:  code one true B image  *	 *	Input:        pointer to image, prev_image, prev_recon, Q *         *	Returns:      pointer to reconstructed image *	Side effects: memory is allocated to recon image * *	Date: 950930  Author: Michael Gallant <mikeg@ee.ubc.ca> * ***********************************************************************/void CodeOneTrueB(PictImage *curr, PictImage *B_image, PictImage *prev,           PictImage *pr, int QP, int frameskip, Bits *bits,          Pict *pic, PictImage *B_recon, PictImage *recon){  unsigned char *prev_ipol, *next_ipol, *pi, *ni;  PictImage *prev_recon=NULL, *next_recon=NULL, *pr_edge = NULL, *nr_edge = NULL;  MotionVector *MV[7][MBR+1][MBC+2];  MotionVector ZERO = {0,0,0,0,0};  MB_Structure *recon_data_true_B = NULL;  MB_Structure *diff;   int *rcoeff, *coeff;  int *qcoeff_true_B = NULL;  int Mode;  int CBP;  int newgob, advanced_temporarily_off = DEF_AIC_MODE;  int i,j,k;  int true_B_prediction_type;  /* buffer control vars */  float QP_cumulative = (float)0.0;  int abs_mb_num = 0, QuantChangePostponed = 0;  int QP_new, QP_prev, QP_xmitted=QP;  MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure));  /* advanced intra coding variables */  int *store_rcoeff, *store_coeff, *pcoeff;   ZeroBits(bits);  /* Currently, the MV info is stored in 7 MV structs per MB. MV[0]   * stores the 16x16 MV. MV[1] through MV[4] store the 8x8 MVs. MV[6]   * stores the PB delta MV or the forward predicted B MV. MV[5]   * stores the backward predicted MV for true-B pictures. */   InitializeMV(MV);  /* Mark PMV's outside the frame. */  for (i = 1; i < (pels>>4)+1; i++)   {    for (j = 0; j < 7; j++)    {      MarkVec(MV[j][0][i]);      }    MV[0][0][i]->Mode = MODE_INTRA;  }  /* Zero out PMV's outside the frame */  for (i = 0; i < (lines>>4)+1; i++)   {    for (j = 0; j < 7; j++)     {      ZeroVec(MV[j][i][0]);      ZeroVec(MV[j][i][(pels>>4)+1]);    }    MV[0][i][0]->Mode = MODE_INTRA;    MV[0][i][(pels>>4)+1]->Mode = MODE_INTRA;  }  GenerateFrameAndInterpolatedImages(pr, pic, &prev_ipol, &prev_recon, &pi, &pr_edge);  GenerateFrameAndInterpolatedImages(recon, pic, &next_ipol, &next_recon, &ni, &nr_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;  }  /* If coding a B-picture, need to pass pictures for forward AND   * backward prediction, as well as interpolated forward and backward   * pictures for half-pel prediction. */  MotionEstimatePicture( B_image->lum,prev_recon->lum, next_recon->lum,                                  prev_ipol, next_ipol, pic->seek_dist, MV,                         pic->use_gobsync, B_PICTURE_ESTIMATION);  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_True_B( B_image, prev_recon, prev_ipol,next_recon,                              next_ipol, pred,i*MB_SIZE, j*MB_SIZE,                             MV, True_B_Direct_Mode_MV, pic->TRB,                              &true_B_prediction_type, &Mode, pic->RTYPE);      if (B_INTRA_PREDICTION == true_B_prediction_type)      {        FillLumBlock(i*MB_SIZE, j*MB_SIZE, B_image, diff);        FillChromBlock(i*MB_SIZE, j*MB_SIZE, B_image, diff);      }      if ((qcoeff_true_B=(int *)malloc(sizeof(int)*384)) == 0)       {        fprintf(stderr,"coder(): Couldn't allocate qcoeff_true_B.\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_true_B,QP_xmitted, Mode,k);          CBP = FindCBP(qcoeff_true_B, 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_true_B,QP_xmitted, Mode,k);              Dequant(qcoeff_true_B, 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_true_B,QP_xmitted, Mode,k);        CBP = FindCBP(qcoeff_true_B, Mode, 64);        if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q))           ZeroMBlock(diff);        else        {          for (k=0;k<6;k++)              Dequant(qcoeff_true_B, rcoeff, QP_xmitted, Mode,k);           MB_Decode(rcoeff, diff);        }      }      recon_data_true_B = MB_Recon_True_B( prev_recon, prev_ipol, diff,                                            next_recon, next_ipol,                                            i*MB_SIZE,j*MB_SIZE,MV,                                           True_B_Direct_Mode_MV, pic->TRB,                                           true_B_prediction_type, pic->RTYPE);      Clip(recon_data_true_B);      free(diff);      free(coeff);      if ((CBP==0) && (B_DIRECT_PREDICTION == true_B_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, true_B_prediction_type, 0);      }      else       {        CountBitsScalMB(Mode,0,CBP,0,pic,bits,true_B_prediction_type, 0);        if (!CBP)            intra_refresh[j+1][i+1] += 1;        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++;          CountBitsVectors( MV, bits, i, j, Mode, newgob, pic,                             true_B_prediction_type);        }        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_true_B,0);          CountBitsCoeff(qcoeff_true_B, 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_true_B,B_recon);       free(qcoeff_true_B);      free(recon_data_true_B);      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(pred);  free(prev_recon);  free(next_recon);  FreeImage(pr_edge);  FreeImage(nr_edge);  free(pi);  free(ni);    for (j = 0; j < (lines>>4)+1; j++)    for (i = 0; i < (pels>>4)+2; i++)       for (k = 0; k < 7; k++)        free(MV[k][j][i]);  if (advanced_intra_coding)

⌨️ 快捷键说明

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