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

📄 coder.c

📁 H。263标准的编解码程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  Cr_ptr = &(data->Cr[0][0]);  /* Fill in chrominance data */  for (n = 0; n < MB_SIZE>>1; n++) {#ifdef LONGISDOUBLEINT    * (long *) recon_Cb_ptr = * (long *) Cb_ptr;    recon_Cb_ptr += 2; Cb_ptr += 2;    * (long *) recon_Cr_ptr = * (long *) Cr_ptr;    recon_Cr_ptr += 2; Cr_ptr += 2;    * (long *) recon_Cb_ptr = * (long *) Cb_ptr;    recon_Cb_ptr += 2; Cb_ptr += 2;    * (long *) recon_Cr_ptr = * (long *) Cr_ptr;    recon_Cr_ptr += 2; Cr_ptr += 2;    * (long *) recon_Cb_ptr = * (long *) Cb_ptr;    recon_Cb_ptr += 2; Cb_ptr += 2;    * (long *) recon_Cr_ptr = * (long *) Cr_ptr;    recon_Cr_ptr += 2; Cr_ptr += 2;    * (long *) recon_Cb_ptr = * (long *) Cb_ptr;    recon_Cb_ptr += cpels - 6; Cb_ptr += 2;    * (long *) recon_Cr_ptr = * (long *) Cr_ptr;    recon_Cr_ptr += cpels - 6; Cr_ptr += 2;#else    * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;       * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    recon_Cb_ptr++; Cb_ptr++;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cr_ptr++; Cr_ptr++;        * (int *) recon_Cb_ptr = * (int *) Cb_ptr;    * (int *) recon_Cr_ptr = * (int *) Cr_ptr;    recon_Cb_ptr += cpels - 7; Cb_ptr ++;    recon_Cr_ptr += cpels - 7; Cr_ptr ++;#endif  }  /* WAS:        for (m = 0; m < MB_SIZE>>1; m++) {     *(recon->Cr + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cr[n][m];     *(recon->Cb + (x_curr>>1)+m + ((y_curr>>1)+n)*cpels) = data->Cb[n][m];     }     */  return;}/********************************************************************** * *	Name:		ReconCopyImage *	Description:	Copies previous recon_image to current recon image *	 *	Input:		position of curr block, reconstructed *			macroblock, pointer to recontructed image *	Returns: *	Side effects: * *	Date: 960423  	Author: Roalt Aalmoes * ***********************************************************************/void ReconCopyImage (int i, int j, unsigned int *recon, unsigned int *prev_recon){  int n;  int x_curr, y_curr;  unsigned int *lum_now, *lum_prev, *cb_now, *cr_now, *cb_prev, *cr_prev;   x_curr = i * MB_SIZE;  y_curr = j * MB_SIZE;  lum_now = recon + x_curr + y_curr*pels;  lum_prev = prev_recon + x_curr + y_curr*pels;  /* Fill in luminance data */  for (n = 0; n < 16; n++) {#ifdef LONGISDOUBLEINT    *(long *)(lum_now) = *(long *)(lum_prev);    *(long *)(lum_now + 2) = *(long *)(lum_prev + 2);    *(long *)(lum_now + 4) = *(long *)(lum_prev + 4);    *(long *)(lum_now + 6) = *(long *)(lum_prev + 6);    *(long *)(lum_now + 8) = *(long *)(lum_prev + 8);    *(long *)(lum_now + 10) = *(long *)(lum_prev + 10);    *(long *)(lum_now + 12) = *(long *)(lum_prev + 12);    *(long *)(lum_now + 14) = *(long *)(lum_prev + 14);#else    *(int *)(lum_now) = *(int *)(lum_prev);    *(int *)(lum_now + 1) = *(int *)(lum_prev + 1);    *(int *)(lum_now + 2) = *(int *)(lum_prev + 2);    *(int *)(lum_now + 3) = *(int *)(lum_prev + 3);    *(int *)(lum_now + 4) = *(int *)(lum_prev + 4);    *(int *)(lum_now + 5) = *(int *)(lum_prev + 5);    *(int *)(lum_now + 6) = *(int *)(lum_prev + 6);    *(int *)(lum_now + 7) = *(int *)(lum_prev + 7);    *(int *)(lum_now + 8) = *(int *)(lum_prev + 8);    *(int *)(lum_now + 9) = *(int *)(lum_prev + 9);    *(int *)(lum_now + 10) = *(int *)(lum_prev + 10);    *(int *)(lum_now + 11) = *(int *)(lum_prev + 11);    *(int *)(lum_now + 12) = *(int *)(lum_prev + 12);    *(int *)(lum_now + 13) = *(int *)(lum_prev + 13);    *(int *)(lum_now + 14) = *(int *)(lum_prev + 14);    *(int *)(lum_now + 15) = *(int *)(lum_prev + 15);#endif    lum_now += pels;    lum_prev += pels;       }  cb_now = recon+uskip + (x_curr>>1) + (y_curr>>1)*cpels;  cr_now = recon+vskip + (x_curr>>1) + (y_curr>>1)*cpels;  cb_prev = prev_recon+uskip+ (x_curr>>1) + (y_curr>>1)*cpels;  cr_prev = prev_recon+vskip + (x_curr>>1) + (y_curr>>1)*cpels;  /* Fill in chrominance data */  for (n = 0; n < (MB_SIZE>>1); n++) {#ifdef LONGISDOUBLEINT    *(long *)(cb_now) = *(long *)(cb_prev);    *(long *)(cb_now + 2) = *(long *)(cb_prev + 2);    *(long *)(cb_now + 4) = *(long *)(cb_prev + 4);    *(long *)(cb_now + 6) = *(long *)(cb_prev + 6);    cb_now += cpels;    cb_prev += cpels;    *(long *)(cr_now) = *(long *)(cr_prev);    *(long *)(cr_now + 2) = *(long *)(cr_prev + 2);    *(long *)(cr_now + 4) = *(long *)(cr_prev + 4);    *(long *)(cr_now + 6) = *(long *)(cr_prev + 6);    cr_now += cpels;    cr_prev += cpels;#else    *(int *)(cb_now) = *(int *)(cb_prev);    *(int *)(cb_now + 1) = *(int *)(cb_prev + 1);    *(int *)(cb_now + 2) = *(int *)(cb_prev + 2);    *(int *)(cb_now + 3) = *(int *)(cb_prev + 3);    *(int *)(cb_now + 4) = *(int *)(cb_prev + 4);    *(int *)(cb_now + 5) = *(int *)(cb_prev + 5);    *(int *)(cb_now + 6) = *(int *)(cb_prev + 6);    *(int *)(cb_now + 7) = *(int *)(cb_prev + 7);    cb_now += cpels;    cb_prev += cpels;    *(int *)(cr_now) = *(int *)(cr_prev);    *(int *)(cr_now + 1) = *(int *)(cr_prev + 1);    *(int *)(cr_now + 2) = *(int *)(cr_prev + 2);    *(int *)(cr_now + 3) = *(int *)(cr_prev + 3);    *(int *)(cr_now + 4) = *(int *)(cr_prev + 4);    *(int *)(cr_now + 5) = *(int *)(cr_prev + 5);    *(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 ***********************************************************************/void 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 */      /* 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' */    }        /* One but last column */    *(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;      }  /* last lines */  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' */  }    /* bottom right corner pels */  *(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 * ***********************************************************************/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) ) {	       current_MV->x = current_MV->y = current_MV->x_half = 	 current_MV->y_half = 0;       current_MV->Mode = MODE_SKIP;      } else {			/* EncodeThisBlock */       	FullMotionEstimation(curr, prev_ipol, seek_dist, current_MV, 			     i*MB_SIZE, j*MB_SIZE);		current_MV->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE,				      current_MV->min_error);	if(current_MV->Mode == MODE_INTRA) 	  ZeroVec(current_MV);      }    }  }}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 */  InterpolateImage(prev_recon,params->interpolated_lum,pels,lines);  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);    }    else if (pic->use_gobsync && j%pic->use_gobsync == 0) {      bits->header += CountBitsSlice(j,params->Q_inter); /* insert gob sync */      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;	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; 	  /* Now send code for "skip this MB" */	  CountBitsMB(Mode,1,CBP,CBPB,pic,bits);   	  ReconCopyImage(i,j,new_recon,prev_recon);	} else { /* Encode this block */	  if (Mode == MODE_INTER) {	    /* SITUATION 2 */	    /* Predict P-MB */	    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));	    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 = MB_EncodeAndFindCBP(diff, params->Q_inter, Mode,&CBP);		  /*   CBP = FindCBP(qcoeff_P, Mode, 64); -> Not required anymore */	  /* All encoded, now calculate decoded image	     for comparison in next frame */	  /* Do DECODING */	  if (CBP == 0 && (Mode == MODE_INTER) ) {				/* SITUATION 4 */	    ZeroMBlock(diff);	  } else {	    /*  qcoeff_P -> Dequantized -> IDCT -> diff */	    MB_Decode(qcoeff_P, diff, params->Q_inter, Mode);	  }	  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);	  /* Do bitstream encoding */		  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 */	    /* Now send code for "skip this MB" */	    CountBitsMB(Mode,1,CBP,CBPB,pic,bits);	  } else {	    /* Normal MB */	    /* VLC */	    CountBitsMB(Mode,0,CBP,CBPB,pic,bits);	    if (Mode == MODE_INTER) {	      bits->no_inter++;	      CountBitsVectors(MV, bits, i, j, Mode, newgob, pic);	    } else {	      /* MODE_INTRA */	      bits->no_intra++;	    }	    /* Only encode coefficient if they are nonzero or Mode is INTRA*/	    	    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 + -