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

📄 encoder.c

📁 用MPEG-4对YUV视频文件编码压缩成divx视频文件
💻 C
📖 第 1 页 / 共 2 页
字号:

#ifdef _DEBUG_PSNR
	float psnr;
#endif

	/* 	decide by Overflow. Add by fyh */
	if(pEnc->rc_type)
		IsOverFlow=IsSkipFrame(&pEnc->rc);/*判断是否需要跳帧 */
	else
		IsOverFlow=FALSE;
    
	/* skip frame flag is used by outputing reconstructed frame. */
	pFrame->flag_skipframe=IsOverFlow;

	if(!IsOverFlow)/*判断是否需要跳帧*/
	{
		start_global_timer();

		/* swap current frame structure and reference frame structure */
		SWAP(pEnc->current, pEnc->reference);

		pEnc->current->global_flags = pFrame->general;
		pEnc->current->motion_flags = pFrame->motion;

		/* copy source YUV buffer to YUV buffer of edged extending. Add by fyh */
		start_timer();
		/*
		if (image_input
			(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
			 pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace) < 0)
			return XVID_ERR_FORMAT;
*/
            image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
			 pEnc->mbParam.edged_width, pFrame->image);
			
		stop_conv_timer();

		/* copy source YUV data from pEnc->current->image to pEnc->sOriginal,
		   in order to calculate psnr value */
	#ifdef _DEBUG_PSNR
		image_copy(&pEnc->sOriginal, &pEnc->current->image,
				   pEnc->mbParam.edged_width, pEnc->mbParam.height);
	#endif

		/* bits streams initialize */
		BitstreamInit(&bs, pFrame->bitstream, 0);

		/* decide frame encoding type(I,P). Add by fyh */ 
		    if ((pEnc->iFrameNum == 0)
				|| ((pEnc->iMaxKeyInterval > 0)
					&& (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) 
			{
				frametype=0;
			} 
			else 
			{
				frametype=1;
			}

		/* get frame level quantization step */
		if(pEnc->rc_type)
			pEnc->current->quant=RC_GetQ(pEncLogFile,&pEnc->rc,frametype,0);
		else
			pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0);

		pEnc->mbParam.m_quant_type = MPEG4_QUANT;
		/*write_vol_header=0;*/
		
		/* coding I/P frame */
		if(frametype==0)
			/*			pFrame->intra = FrameCodeI(pEnc, &bs, &bits,&head_vector,FALSE,&mad);*/
        {
//			pEnc->current->quant = pEnc->current->quant * 2 / 3;
            pFrame->intra = FrameCodeI(pEnc, &bs, &bits,&head_vector,&mad);
		}
		else 
			/*pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header,&head_vector,&mad);*/
            pFrame->intra = FrameCodeP(pEnc, &bs, &bits,&head_vector,&mad);
	
		/* fyh comment code */
		/*
		BitstreamPutBits(&bs, 0xFFFF, 16);
		BitstreamPutBits(&bs, 0xFFFF, 16);
		*/
		
		/* Pad bitstream to the next byte boundary. Add by fyh */
		BitstreamPad(&bs);
		
		/* Get frame bitstream length. Add by fyh */
		pFrame->length = BitstreamLength(&bs);

		/* reset frametype for scene changing. Add by fyh (comment code)*/
		/*if(pFrame->intra)   frametype=0;*/

		/* update rate control model after encoding a frame. Add by fyh */ 
		if(pEnc->rc_type)
			After_encoding_current(pEncLogFile, &pEnc->rc,frametype,
					pFrame->length*8,head_vector,mad);
		else
			RateControlUpdate(&pEnc->rate_control, pEnc->current->quant,
							  pFrame->length, pFrame->intra);

        /* claculate psnr value for current encoding iamge */
#ifdef _DEBUG_PSNR
		psnr =
			image_psnr(&pEnc->sOriginal, &pEnc->current->image,
					   pEnc->mbParam.edged_width, pEnc->mbParam.width,
					   pEnc->mbParam.height);
		pFrame->psnr=psnr; 	
#endif

		/* output constructed image */
#ifdef _OUT_CONSTRUCT_IMAGE		
/*		image_output(&pEnc->current->image , pEnc->mbParam.width,pEnc->mbParam.height,
							 pEnc->mbParam.edged_width, pFrame->constructimage,
							 pFrame->stride ,pFrame->colorspace );*/
		image_output(&pEnc->current->image , pEnc->mbParam.width,pEnc->mbParam.height,
							 pEnc->mbParam.edged_width, pFrame->constructimage,
							 pFrame->stride);
#endif         
	  
		pEnc->iFrameNum++;
		stop_global_timer();
		write_timer();
	}
	else
	{	pEnc->iFrameNum++;
	  	pFrame->length=0;
		pFrame->intra=0;
	}

	return XVID_ERR_OK;/* normal exit */
}
/*
   set macoblock coding mode and quantization step size.
   zero motion vector and sad value for motion estimation.
*/

static __inline void
CodeIntraMB(Encoder * pEnc,
			MACROBLOCK * pMB)
{
    /* set macoblock coding mode */
	pMB->mode = MODE_INTRA;

	/* zero mv statistics */
	pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
	pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
    pMB->mv16.x=pMB->mv16.y=0;/* fyh add code 2002.12.22*/

	/* zero sad value */
	pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
	pMB->sad16 = 0;

    /* set macoblock quantization step size */
	pMB->quant = pEnc->current->quant;
}

/* store dct transform coefficient */
static int16_t dct_codes_storage[6*64+CACHE_LINE-1];
/* store quantization coefficient */
static int16_t    qcoeff_storage[6*64+CACHE_LINE-1];

/* 
scence_change: no meaning(delete)
*/
/* 
static int
FrameCodeI(Encoder * pEnc,
		   Bitstream * bs,
		   uint32_t * pBits,int* head,BOOL scence_change,int *mad)*/
/*
   Finish I frame encoding.
*/
static int  /* frame type flag */
FrameCodeI(Encoder * pEnc, /* ponit to global Encoder structure */
		   Bitstream * bs, /* ponit to Bitstream structure */
		   uint32_t * pBits,/* bit streams length */
		   int* head,/* header information encoding bits number */
		   int *mad/* use mad value to measure encoding complexity */
		   )
{
  
    uint16_t x, y;/* macroblock coordinate */
	MACROBLOCK *pMB;

	/*  
	   int16_t dct_codes_storage[6*64+16-1];
	   int16_t *dct_codes=(int16_t *)((uint32_t)dct_codes_storage+
	           (16-1))&~((uint32_t)((uint32_t)(16)-1));
       alloc dctcodes[6][64] and qcoeff[6][64] 
	*/
	/* modify */
	/*
	DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
	DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
	*/

    /* point to dct transform coefficient buffer */
    int16_t *dct_codes=(int16_t *)(((uint32_t)dct_codes_storage+
	           CACHE_LINE-1)&~(CACHE_LINE-1));
	/* point to quantization coefficient buffer */
    int16_t *qcoeff=(int16_t *)(((uint32_t)qcoeff_storage+
	           CACHE_LINE-1)&~(CACHE_LINE-1));
	
	/* whq,2002.12.18,get dcscaler here */
	/*
	add dcscaler
	*/
	pEnc->current->lum_dcscaler    = get_dc_scaler(pEnc->current->quant, 1);
	pEnc->current->chrom_dcscaler  = get_dc_scaler(pEnc->current->quant, 0);	
	/* whq,2002.12.18,get dcscaler here */


	/*
	if(scence_change==FALSE)
		pEnc->iFrameNum = 0;
    */
    pEnc->iFrameNum = 0;

	/* 
	   半像素插值时使用四舍五入
    */
/*	pEnc->mbParam.m_rounding_type = 1;*/
    pEnc->mbParam.m_rounding_type = 0;

	pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;

    /* calculate mad value for I frame */
	*mad=compute_MAD(pEnc);

	pEnc->current->coding_type = I_VOP;

	/* write vol and vop headers */
	*head=BitstreamPos(bs);
	BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
	BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
	*pBits = BitstreamPos(bs);
	*head=BitstreamPos(bs)-*head;
		
	/* process all macroblock of frame */
	for (y = 0; y < pEnc->mbParam.mb_height; y++)
	{
		for (x = 0; x < pEnc->mbParam.mb_width; x++)
		{
			/* get current macroblock structure address */
			/*MACROBLOCK *pMB =
				&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];*/
            pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];

			/* modify */
			/* get mb quantization step size. Add by fyh */
			CodeIntraMB(pEnc, pMB);
			/*
		    pMB->mode = MODE_INTRA;
            pMB->quant = pEnc->current->quant;
            */
			/*whq,2002.12.18,add a param or struct member in pEnc->current*/
			/* transform and quantize. */
			MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
							  dct_codes, qcoeff);

			/* whq,2002.12.19,add prediction into transquant */
			/*start_timer();
			
			MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
			stop_prediction_timer();
			*/
			/* whq */

			/* vlc coding */
			start_timer();
			MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
			stop_coding_timer();
		}
	}

	/* get bit stream length */
	*pBits = BitstreamPos(bs) - *pBits;
    pEnc->mbParam.m_fcode = 1;
       
	/* decide P frame type by use amvfast . Add by fyh */
	first_P_gop=1;

	return 1;				
}


/*#define INTRA_THRESHOLD 0.5*/

/*
static int
FrameCodeP(Encoder * pEnc,
		   Bitstream * bs,
		   uint32_t * pBits,
		   bool force_inter,
		   bool vol_header,int* head_vector,int *mad)
*/
/*
   Finish P frame encoding.
*/


static int                        /* frame type flag */
FrameCodeP(Encoder * pEnc,
		   Bitstream * bs,        /* ponit to global Encoder structure */
		   uint32_t * pBits,      /* bit streams length */
		   int* head_vector,      /* header information and vector encoding bits number */
		   int *mad               /* use mad value to measure encoding complexity */ 
		   )
{
/*	int iLimit;*/
	uint32_t x, y;/* current macroblock coordinate(unit: 16 pixel) */
	int bIntra;   /* intra macroblock flag */
	MACROBLOCK *pMB;/* current macroblock structure address */

	IMAGE *pRef = &pEnc->reference->image;/* reference image address */

    /* midify */
	/*
	DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
	DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
	*/
    /* point to dct transform coefficient buffer */
    int16_t *dct_codes=(int16_t *)(((uint32_t)dct_codes_storage+
	           CACHE_LINE-1)&~(CACHE_LINE-1));
	/* point to quantization coefficient buffer */
    int16_t *qcoeff=(int16_t *)(((uint32_t)qcoeff_storage+
	           CACHE_LINE-1)&~(CACHE_LINE-1));


    /* reference image edge padding (include Y/U/V component) */
	start_timer();
/*	image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
				   pEnc->mbParam.width, pEnc->mbParam.height,
				   pEnc->current->global_flags & XVID_INTERLACING);*/
   image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
				   pEnc->mbParam.width, pEnc->mbParam.height);
	stop_edges_timer();
	
	pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
	pEnc->current->fcode = pEnc->mbParam.m_fcode;
/*
	if (!force_inter)
		iLimit =
			(int) (pEnc->mbParam.mb_width * pEnc->mbParam.mb_height *
				   INTRA_THRESHOLD);
	else
		iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
*/
/*    iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;*/

	/* reference image half pixel interpolation (only process Y component)*/
	if ((pEnc->current->global_flags & XVID_HALFPEL)) {
		start_timer();
		image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV,
						  &pEnc->vInterHV, pEnc->mbParam.edged_width,
						  pEnc->mbParam.edged_height,
						  pEnc->current->rounding_type);
		stop_inter_timer();
	}

	/* motion estimation for current image */
	start_timer();
	/*bIntra =
			MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
							 &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,mad,
							 iLimit);*/
    MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
					 &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,mad);

	stop_motion_timer();
/*
	if (bIntra == 1) 
	{
		return FrameCodeI(pEnc, bs, pBits,head_vector,TRUE,mad);
	}
*/	

	/* write vop header and get header length */
	*head_vector=BitstreamPos(bs);
	pEnc->current->coding_type = P_VOP;
/*
	if (vol_header)
		BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
*/
	BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
	*pBits = BitstreamPos(bs);
	*head_vector=BitstreamPos(bs)-*head_vector;
	*head_vector=0;

	/* whq,2002.12.18,get dcscaler here */
	/*
	add dcscaler
	*/
	pEnc->current->lum_dcscaler    = get_dc_scaler(pEnc->current->quant, 1);
	pEnc->current->chrom_dcscaler  = get_dc_scaler(pEnc->current->quant, 0);	
	/* whq,2002.12.18,get dcscaler here */

	/* macroblock level loop */
	for (y = 0; y < pEnc->mbParam.mb_height; y++) {
		for (x = 0; x < pEnc->mbParam.mb_width; x++) {
			/* get current macroblock structure address */
/*
			MACROBLOCK *pMB =
				&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];*/
            pMB =&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];

			bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);

			if (!bIntra) {/* process inter macroblock */
				
				/* motion compensation for inter macroblock */
				start_timer();
				MBMotionCompensation(pMB, x, y, &pEnc->reference->image,
									 &pEnc->vInterH, &pEnc->vInterV,
									 &pEnc->vInterHV, &pEnc->current->image,
									 dct_codes, pEnc->mbParam.width,
									 pEnc->mbParam.height,
									 pEnc->mbParam.edged_width,
									 pEnc->current->rounding_type);
				stop_comp_timer();

				pMB->quant = pEnc->current->quant;

				/* modify */
			/*	pMB->field_pred = 0; */

                /* transform and quantize for inter macroblock */ 
				pMB->cbp =
					MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y,
									  dct_codes, qcoeff);
			} else {
				/* process intra macroblock */

				/* get quantization step size */
				CodeIntraMB(pEnc, pMB);

                /* transform and quantize for intra macroblock */ 
				MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
								  dct_codes, qcoeff);

			    /* whq,2002.12.19,add prediction into transquant*/
				/*start_timer();   */
			    /*MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
			     stop_prediction_timer();*/
				 /*whq */
			}

			/* vlc coding for current macroblock */
			start_timer();
			*head_vector+=MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
			stop_coding_timer();
		}
	}

    pEnc->mbParam.m_fcode=1;/* motion vector range code */
	*pBits = BitstreamPos(bs) - *pBits;/* get bit streams length */


    /* decide P frame type by use amvfast . Add by fyh */
	first_P_seq=0;
    first_P_gop=0;

	return 0; /* normal exit */					
}

⌨️ 快捷键说明

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