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

📄 p_picture.c

📁 H.263的压缩算法
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************ * *  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 * *  Copyright (C) 1995, 1996  Telenor R&D, Norway *   *  Contacts:  *  Robert Danielsen                  <Robert.Danielsen@nta.no> * *  Telenor Research and Development  http://www.nta.no/brukere/DVC/ *  P.O.Box 83                        tel.:   +47 63 84 84 00 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76 *   ************************************************************************//* * 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. **//***************************************************************** * * Modified by Pat Mulroy, BT Labs to run syntax based arithmetic * coding.  SAC option, H.263 (Annex E). * *****************************************************************/#include"sim.h"/********************************************************************** * *	Name:           CodeOneOrTwo *	Description:	code one image normally or two images *                      as a PB-frame (CodeTwoPB and CodeOnePred merged) *	 *	Input:          pointer to image, prev_image, prev_recon, Q *         *	Returns:	pointer to reconstructed image *	Side effects:	memory is allocated to recon image * *	Date: 950221	Author:	<klillevo@mailbox.jf.intel.com> *            970831    modified by mikeg@ee.ubc.ca *            970815    modified by guyc@ee.ubc.ca * ***********************************************************************/void CodeOneOrTwo(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,*prev_ipol_woRTYPE, *pi, *pi_woRTYPE;  PictImage *prev_recon=NULL, *pr_edge = NULL;  MotionVector *MV[7][MBR+1][MBC+2];  MotionVector *B_f_MV[7][MBR+1][MBC+2];  MotionVector ZERO = {0,0,0,0,0};  MB_Structure *recon_data_P;   MB_Structure *recon_data_B=NULL;   MB_Structure *diff;   int *qcoeff_P, *rcoeff, *coeff;  int *qcoeff_B=NULL;  int Mode;  int CBP, CBPB=0;  int bquant[] = {5,6,7,8};  int QP_B;  int newgob, advanced_temporarily_off = DEF_ADV_MODE;  int i,j,k,B;  /* buffer control vars */  float QP_cumulative = (float)0.0;  int abs_mb_num = 0, QuantChangePostponed = 0;  int QP_new, QP_prev, dquant, QP_xmitted=QP;  /* Rate control variables */  Bits *bits_prev = (Bits*)calloc(1,sizeof(Bits));  MB_Structure *pred_P = (MB_Structure *)malloc(sizeof(MB_Structure));  MB_Structure *pred_B = (MB_Structure *) malloc (sizeof (MB_Structure));    int PB_pred_type;  /* advanced intra coding variables */  int *store_rcoeff, *store_coeff, *pcoeff; /* used to do prediction in advanced intra coding */  int store_pb;   /* Reference Picture Selection variables */  static int sync_gob = 0;  int sync_gob_done = 0;  int encode_this_gob = 1; /* Always on if Annex N not used */  int sync_gob_this_frame = 0;  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);  InitializeMV(B_f_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]);       MarkVec(B_f_MV[j][0][i]);     }    MV[0][0][i]->Mode = MODE_INTRA;    B_f_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]);      ZeroVec(B_f_MV[j][i][0]);      ZeroVec(B_f_MV[j][i][(pels>>4)+1]);    }    MV[0][i][0]->Mode = MODE_INTRA;    MV[0][i][(pels>>4)+1]->Mode = MODE_INTRA;    B_f_MV[0][i][0]->Mode = MODE_INTRA;    B_f_MV[0][i][(pels>>4)+1]->Mode = MODE_INTRA;  }  GenerateFrameAndInterpolatedImages(pr, pic, &prev_ipol, &prev_recon, &pi, &pr_edge);  /* Integer and half pel motion estimation */  MotionEstimatePicture( curr->lum,prev_recon->lum, NULL, prev_ipol,                         NULL, pic->seek_dist, MV, pic->use_gobsync,                         P_PICTURE_ESTIMATION);  if (successive_B_frames)  {    StoreDirectModeVectors(MV, True_B_Direct_Mode_MV);  }  if (pic->PB)  { /* Interpolate the image for B picture prediction without using ETYPE*/    if (mv_outside_frame)     {      if (long_vectors) B = 16; else  B = 8;      pi_woRTYPE = InterpolateImage(pr_edge->lum, pels+4*B, lines+4*B,0);      prev_ipol_woRTYPE = pi_woRTYPE + (2*pels + 8*B) * 4*B + 4*B;     }    else     {      pi_woRTYPE = InterpolateImage(pr->lum,pels,lines,0);      prev_ipol_woRTYPE = pi_woRTYPE;    }  }  if (PCT_IPB == pic->picture_coding_type)  {    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;    }    /* Forward motion Integer and half pel estimation for improved PB frames.     * Motion estimation type is set to PB_PICTURE so that long vectors will      * not be used. */    MotionEstimatePicture( B_image->lum,prev_recon->lum, NULL, prev_ipol_woRTYPE,                           NULL, pic->seek_dist, B_f_MV, pic->use_gobsync,                            PB_PICTURE_ESTIMATION);                              if (advanced_temporarily_off)    {      advanced_temporarily_off = NO;      overlapping_MC = ON;      adv_pred = ON;      use_4mv = ON;    }  }  switch (rate_control_method)   {    case NO:    case OFFLINE_RC:      QP_new = QP_xmitted = QP_prev = QP; /* Copy the passed value of QP */      break;    case  TMN8_RC:            /* Initialization routine for Frame Layer Rate Control */      /* Jordi Ribas added more parameters to InitializeRateControlMB */      InitializeRateControlMB(curr, (float)pic->bit_rate,                               (pic->PB ? pic->target_frame_rate/2 : pic->target_frame_rate), MV,                              prev_recon, prev_ipol,                               pred_P, pic->PB, pic->RTYPE);      /* compute the first QP to be included in the picture header */      QP_new = Compute_QP(0,0);      QP_xmitted = QP_prev = QP_new;       break;    case  TMN5_RC:      /* Initialization routine for MB Layer Rate Control */      QP_new = InitializeQuantizer(PCT_INTER, (float)pic->bit_rate,                (pic->PB ? pic->target_frame_rate/2 : pic->target_frame_rate),               pic->QP_mean);      QP_xmitted = QP_prev = QP_new;      break;    default:      break;  }  dquant = 0;   for ( j = 0; j < lines/MB_SIZE; j++)   {    if (rate_control_method == TMN5_RC)     {      /* QP updated at the beginning of each row for Frame layer rate control */      AddBitsPicture(bits);      QP_new =  UpdateQuantizer(abs_mb_num, pic->QP_mean, PCT_INTER,                 (float)pic->bit_rate, pels/MB_SIZE, lines/MB_SIZE,                 bits->total);    }      newgob = 0;    /* Do VRC on GOBs -- just add sync gobs at user defined frequency for now      * and only in the sync frames */    if (pic->reference_picture_selection && pic->sync         && (pic->use_gobsync && j%pic->use_gobsync == 0))    {      /* Determine if this GOB is a sync GOB */      if (j == sync_gob && !sync_gob_done)      {        ++sync_gob_this_frame;        sync_gob = (sync_gob+pic->use_gobsync);        if (sync_gob >= (lines/MB_SIZE)) sync_gob = 0;        fprintf(stdout, "Coding Sync GOB: %d\n", j);        encode_this_gob = 1;        if (sync_gob_this_frame == sync_gobs_per_frame) sync_gob_done = 1;      }      else        encode_this_gob = 0;    }     /* encoder this GOBs (used for VRC on GOBs, otherwise always true) */    if (encode_this_gob)    {    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 header */      QP_xmitted = QP_prev = QP_new;      newgob = 1;    }      for ( i = 0; i < pels/MB_SIZE; i++)     {           if (rate_control_method == TMN8_RC)       {        /* Compute optimized quantizer for the current macroblock */        QP_new = Compute_QP(i,j);      }      /* Update of dquant, check and correct its limit */      if (PCT_B != pic->picture_coding_type)      {                dquant = QP_new - QP_prev;        if ( dquant != 0 && MV[0][j+1][i+1]->Mode == MODE_INTER4V	     && !EPTYPE)         {          /* It is not possible to change the quantizer and at the same           * time use 8x8 vectors, unless H.263+ PLUS PTYPE is used.            * Turning off 8x8 vectors is not           * possible at this stage because the previous macroblock           * encoded assumed this one should use 8x8 vectors. Therefore           * the change of quantizer is postponed until the first MB           * without 8x8 vectors */      	   dquant = 0;           QP_xmitted = QP_prev;           QuantChangePostponed = 1;        }        else         {          QP_xmitted = QP_new;          QuantChangePostponed = 0;        }        /* Unless modified quantization mode is in use restrict the range of         * dquant to [-2,+2]*/        if (!modified_quantization) 	      {      	  if (dquant > 2)            {             dquant =  2;             QP_xmitted = QP_prev + dquant;          }   	      if (dquant < -2)           {             dquant = -2;             QP_xmitted = QP_prev + dquant;          }	      }        else         {          /* Modified quantization mode is in use. */#ifdef RESTRICTED_MQ          /* restrict dquant so that when the modified quantization mode is on quant only uses 2 bits*/          if (dquant != 0)          {            dquant= Get_restricted_MQ(dquant,QP_prev);            QP_xmitted = QP_prev + dquant;          }#endif          if (dquant!=0) 		        {            if ((QP_prev >= 21 && dquant == -3) ||                (QP_prev >= 11 && QP_prev <= 20 && dquant == -2) ||                (QP_prev >= 2  && QP_prev <= 10 && dquant == -1) ||                (QP_prev == 1  && dquant == 2)) 	          {   	          /* dquant will be coded into 2 bits*/       	      pic->dquant_size = 2;	            dquant = 2;            }            else             {              if ((QP_prev == 31 && dquant == -5) ||                  (QP_prev == 30 && dquant == 1) ||                  (QP_prev == 29 && dquant == 2) ||                  (QP_prev >= 21 && QP_prev <= 28 && dquant == 3) ||                  (QP_prev >= 11 && QP_prev <= 20 && dquant == 2) ||                  (QP_prev >= 1 && QP_prev <= 10 && dquant == 1))	            {		            /* dquant will be coded into 2 bits*/	      	      pic->dquant_size = 2;		            dquant = 3;	            } 	            else 	            {	              /* dquant will be coded intou 6 bits. */		            pic->dquant_size=6;		            /* instead of the difference between current quantizer and

⌨️ 快捷键说明

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