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

📄 coder.c

📁 h.263 c编码源码。目录下有input。qcif原始未压缩文件
💻 C
📖 第 1 页 / 共 3 页
字号:
    *(int *)(cr_now + 6) = *(int *)(cr_prev + 6);    *(int *)(cr_now + 7) = *(int *)(cr_prev + 7);    cr_now += cpels;    cr_prev += cpels;#endif  }  return;}/********************************************************************** * *	Name:		InterpolateImage *	Description:    Interpolates a complete image for easier half *                      pel prediction *	 *	Input:	        pointer to image structure *	Returns:        pointer to interpolated image *	Side effects:   allocates memory to interpolated image * *	Date: 950207 	Author: Karl.Lillevold@nta.no *            960207    Author: Roalt aalmoes ***********************************************************************///插入半象素整个图像,新图像为ipol_image
//得到的新图像大小为    width*2  height*2void InterpolateImage(unsigned int *image, unsigned int *ipol_image, 			       int width, int height){  /* If anyone has better ideas to optimize this code, be my guest!     note: assembly or some advanced bitshifts routine might do the trick...*/  register unsigned int *ii, *oo,     *ii_new,     *ii_new_line2,     *oo_prev,     *oo_prev_line2;    register int i,j;  register unsigned int pix1,pix2,pix3,pix4;  ii = ipol_image;  oo = image;  oo_prev = image;  oo_prev_line2 = image + width;  ii_new = ipol_image;  ii_new_line2 = ipol_image + (width<<1);  /* main image */  for (j = 0; j < height-1; j++) {				/* get Pix1 and Pix3, because they are				   not known the first time */    pix1 = *oo_prev;    pix3 = *oo_prev_line2;    for (i = 0; i  < width-1; i++) {				/* Pix1 Pix2				   Pix3 Pix4 */     //  pix1            (pix1+pix2)/2               pix2           
		                            //  (pix1+pix3)/2   (pix1+pix2+pix3+pix4)/4     (pix2+pix4)/2
		                            //        /* Pix2 and Pix4 are used here for first time */      pix2 = *(oo_prev + 1);      pix4 = *(oo_prev_line2 + 1);      *(ii_new) = pix1;					/* X.							   ..*/      *(ii_new + 1) = (pix1 + pix2 + 1)>>1; 		/* *X							   .. */      *ii_new_line2 = (pix1 + pix3 + 1)>>1; 		/* *.						           X. */      *(ii_new_line2 + 1) = (pix1 + pix2 + pix3 + pix4 + 2)>>2;            oo_prev++; oo_prev_line2++; ii_new += 2; ii_new_line2 += 2;            pix1 = pix2;      pix3 = pix4;		/* Pix1 Pix2=Pix1' Pix2' */				/* Pix3 Pix4=Pix3' Pix4' */    }        /* 最后一列*/    *(ii_new++) = pix1;	    *(ii_new++) = pix3;        /* Last column -On the Edge - */    *(ii_new_line2++) = (pix1 + pix3 + 1 ) >>1;    *(ii_new_line2++) = (pix1 + pix3 + 1 ) >>1;    ii_new += (width<<1);	/* ii_new now on old position ii_new_line2,so one interpolated screen line must be added*/    ii_new_line2 += (width<<1);	/* In fact, ii_new_line here has same value as ii_new */    oo_prev += 1; /* Remember, loop is done one time less! */    oo_prev_line2 += 1;      }  /* 最后一行 */  pix1 = *oo_prev;  for (i = 0; i < width-1; i++) {    pix2 = *(oo_prev + 1);    *ii_new = *ii_new_line2 = pix1;    *(ii_new + 1) = *(ii_new_line2 + 1) = (pix1 + pix2 + 1)>>1;    ii_new += 2;    ii_new_line2 += 2;    oo_prev += 1;    pix1 = pix2;			/* Pix1 Pix2=Pix1' Pix2' */  }    /* 右下角*/  *(ii_new) = pix1;  *(ii_new + 1) = pix1;  *(ii_new_line2) = pix1;  *(ii_new_line2+1) = pix1;  return;}/********************************************************************** * *	Name:		FullMotionEstimatePicture *	Description:    Finds integer and half pel motion estimation *	 *	Input:	       current image, previous image, interpolated *                     reconstructed previous image, seek_dist, *                     motion vector array *	Returns:        *	Side effects: allocates memory for MV structure * *	Date: 960418	Author: Roatlt * ***********************************************************************/// 找到整象素和半象素的运动估计// curr现在图像,prev重建后图像,prev_ipol插入半象素后的,seek_dist 搜索窗,MV 放置mv结果,advanced_method    ,EncodeThisBlock编码
void FullMotionEstimatePicture(unsigned int *curr, unsigned int *prev, 			       unsigned int *prev_ipol, int seek_dist, 			       MotionVector *MV_ptr,			       int advanced_method,			       int *EncodeThisBlock){  int i,j;  MotionVector *current_MV;  for(j = 0; j < mbr; j++) {   for(i = 0; i < mbc; i++) {       current_MV = MV_ptr + j*mbc + i;       if(advanced_method && !*(EncodeThisBlock + j*mbc + i) )  // encoderthisblock 检测宏块hasmove,为0时,表示重建的宏块和当前宏块近似,不需编码,为skip
	   {		   current_MV->x = current_MV->y = current_MV->x_half = current_MV->y_half = 0; // 整象素和半象素全部为0时,为SKIP		   current_MV->Mode = MODE_SKIP;       } 
	   else 
	   {	/* EncodeThisBlock */

		   //估计宏块运动矢量,到current_mv(x,y值和误差值)    ???????????????????????	       FullMotionEstimation(curr, prev_ipol, seek_dist, current_MV, i*MB_SIZE, j*MB_SIZE);
           // 选择编码模式,宏块的方差较小时,用intra	       current_MV->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE,current_MV->min_error);
	       if(current_MV->Mode == MODE_INTRA) 	            ZeroVec(current_MV);      }    }  }}//编码一帧P帧void CodeInterH263(CParam *params, Bits *bits){  MotionVector *MV;	  MotionVector ZERO = {0,0,0,0,0};  MB_Structure *recon_data_P;   MB_Structure *diff;  int *qcoeff_P;  unsigned int *new_recon=NULL;  unsigned int *prev_recon;  int Mode;    int CBP, CBPB=0;  int newgob;  int i,j;  search_p_frames = params->search_method;  MV = malloc(sizeof(MotionVector)*mbc*mbr);
  // 新重建图像  new_recon = malloc(sizeof_frame);
  //上帧重建图像  prev_recon = params->recon;  /* buffer control vars */    ZeroBits(bits);  /* Interpolate luminance from reconstr. picture */  // 插入半象素图像,得到params->interpolated_lum (宽,长都为原来2倍)  InterpolateImage(prev_recon,params->interpolated_lum,pels,lines);
  //找到运动矢量,放入MV序列,params->advanced_method=1 ,定义宏块的类型.如果当前和重建的宏块相同,则为skip. intra误差小时,定义为intra.  FullMotionEstimatePicture( params->data,prev_recon, params->interpolated_lum, params->half_pixel_searchwindow,MV,params->advanced_method, params->EncodeThisBlock);    /* Calculate MV for each MB */  /* ENCODE TO H.263 STREAM */  //开始编码  for ( j = 0; j < mbr; j++) {    newgob = 0;    if (j == 0) 
	{      pic->QUANT = params->Q_inter;      pic->picture_coding_type = PCT_INTER;      bits->header += CountBitsPicture(pic);                                    // 估计P帧的文件头bit数,   50     }    else if (pic->use_gobsync && j%pic->use_gobsync == 0) // 0
	{      bits->header += CountBitsSlice(j,params->Q_inter); /* insert gob sync */    // 估计片的bit数      newgob = 1; //新的片    }    for ( i = 0; i < mbc; i++) {      /* This means: For every macroblock (i,j) do ... */      /* We have 4 different situations:         1) !EncodeThisBlock: this means that the macroblock in not encoded         2) EncodeThisBlock: This means that the MB is  encoded by using the predicted motion vector.         3) EncodeThisBlock: However, the approx of the  motion vector was so bad, that INTRA coding is more appropiate here ...	     4) EncodeThisBlock: The approx is so good that the coefficients are all zero (after quant.) and are not send.      */	/* This means: For every macroblock (i,j) do ... */        pic->DQUANT = 0;	    Mode = MV[j*mbc + i].Mode;	   /* Determine position of MB */	    pic->MB = i + j * mbc;
         //宏块SKIP,不需编码	    if(Mode == MODE_SKIP) 
		{	      /* SITUATION 1 */		  Mode = MODE_INTRA;	/* This might be done "better" in the future*/		  MV[j*mbc + i].Mode = Mode;		  ZeroVec(&(MV[j*mbc + i]));		  CBP = CBPB = 0;
		  /* COD值为1,skip */		  CountBitsMB(Mode,1,CBP,CBPB,pic,bits); 		  ReconCopyImage(i,j,new_recon,prev_recon);		} 
		else //需对宏块编码
		{ 
			//帧间0	      if (Mode == MODE_INTER)
		  {	      /* SITUATION 2 */	      /* Predict P-MB *///返回根据mv位置得到的插入图像和现在图像的差值,放入mb结构的diff	         diff = Predict_P(params->data,prev_recon,params->interpolated_lum,i*MB_SIZE,j*MB_SIZE,MV);		  } 
		  else //帧内
		  {	        /* SITUATION 3 */	         /* Create MB_Structure diff that contains coefficients that must be sent to the other end */				diff = (MB_Structure *)malloc(sizeof(MB_Structure));

			//从原数据params->data中复制宏块数据到diff[16][16]中			FillLumBlock(i*MB_SIZE, j*MB_SIZE, params->data, diff); 
			/* Copy curr->lum to diff for macroblock (i,j) */			FillChromBlock(i*MB_SIZE, j*MB_SIZE, params->data, diff);			/* Equiv. for curr->Cb and curr->Cr */		  }		  /* P or INTRA Macroblock */		  /*  diff -> DCT -> QUANTIZED -> qcoeff_P */
		  //编码差值系数,放入量化后的系数qcoeff_P		  qcoeff_P = MB_EncodeAndFindCBP(diff, params->Q_inter, Mode,&CBP);		  /*   CBP = FindCBP(qcoeff_P, Mode, 64); -> Not required anymore */
		  /* 解码宏块 */	     if (CBP == 0 && (Mode == MODE_INTER) )
		 {			 /* SITUATION 4 */	         ZeroMBlock(diff);		 } 
		 else 
		 {	         /*  qcoeff_P -> Dequantized -> IDCT -> diff */
			 //宏块解码,从量化系数qcoeff_P返回到diff	         MB_Decode(qcoeff_P, diff, params->Q_inter, Mode);		 }         //重建p宏块,返回重建宏块结构 ??????????????	     recon_data_P = MB_Recon_P(prev_recon, params->interpolated_lum,diff,  i*MB_SIZE,j*MB_SIZE,MV);		  Clip(recon_data_P);		  free(diff);
		  /* 比特流编码 */	     if((CBP==0) && (EqualVec(&(MV[j*mbc+i]),&ZERO)) &&(Mode == MODE_INTER) )
		 {	    /* Skipped MB : both CBP and CBPB are zero, 16x16 vector is zero,	       PB delta vector is zero and Mode = MODE_INTER */	    /* SKIP */	      CountBitsMB(Mode,1,CBP,CBPB,pic,bits);		 } 
		 else //非skip
		 {			/* Normal MB */			/* VLC */			CountBitsMB(Mode,0,CBP,CBPB,pic,bits);			if (Mode == MODE_INTER) //inter
			{			  bits->no_inter++;
			  //对mv系数编码,i,j宏块			  CountBitsVectors(MV, bits, i, j, Mode, newgob, pic);     //bits->vec 中记录编码了的bit位数			} 
			else 
			{			  /* MODE_INTRA */			  bits->no_intra++;			}	        /* Only encode coefficient if they are nonzero or Mode is INTRA*/
	        // 对qcoeff编码(16*16宏块),写入bit流,并将写入bit数加入到 bits->Y,和 bits->U中	        if (CBP || Mode == MODE_INTRA)  //帧内	             CountBitsCoeff(qcoeff_P, Mode, CBP, bits, 64);	   		 } /* End skip/not skip macroblock encoding */		  ReconImage(i,j,recon_data_P,new_recon);		  free(recon_data_P);		  free(qcoeff_P);		}  /* End advanced */          } /* End for i */  } /* End for j */  pic->QP_mean = params->Q_inter;    free(prev_recon);  params->recon = new_recon;  AddBitsPicture(bits);  free(MV);  return;}				

⌨️ 快捷键说明

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