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

📄 ratecontrol.c

📁 用MPEG-4对YUV视频文件编码压缩成divx视频文件
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <math.h>
#include "../user_macro.h"
#include "rc_data.h"
#include "ratecontrol.h"  


/*!
 *****************************************************************************
 ========== old quantize=====================================================
 ****************************************************************************
 */

/*!
 ****************************************************************************
 * \brief
 *
 * init ratecontrol param
 *
 ***************************************************************************
*/

void
RateControlInit(RateControl * rate_control,			/*<--> 指向RateControl结构*/
				uint32_t target_rate,				/*<--  目标位率*/
				uint32_t reaction_delay_factor,		/*<--  位率控制反应因子*/
				uint32_t averaging_period,			/*<--  平均反应因子*/
				uint32_t buffer,					/*<--  缓冲区*/
				int framerate,						/*<--  帧率*/
				int max_quant,						/*<--  最大量化值*/
				int min_quant						/*<--  最小量化值*/
				)
{
	int i=0;
	rate_control->frames = 0;
	rate_control->total_size = 0;
	rate_control->framerate = framerate / 1000.0;
	rate_control->target_rate = target_rate;
	rate_control->rtn_quant = get_initial_quant(0);
	rate_control->max_quant = max_quant;
	rate_control->min_quant = min_quant;
	for (i = 0; i < 32; ++i) {
		rate_control->quant_error[i] = 0.0;
	}
	rate_control->target_framesize =
		(double) target_rate / 8.0 / rate_control->framerate;
	rate_control->sequence_quality = 2.0 / (double) rate_control->rtn_quant;
	rate_control->avg_framesize = rate_control->target_framesize;
	rate_control->reaction_delay_factor = reaction_delay_factor;
	rate_control->averaging_period = averaging_period;
	rate_control->buffer = buffer;
}

/*!
 ****************************************************************************
 * \brief
 *
 * Returned value : - the current 'rate_control' quantizer value
 *
 ***************************************************************************
*/

int												/*==> 返回量化值*/
RateControlGetQ(RateControl * rate_control,		/*<--指向RateControl结构 */
				int keyframe					/*<--是否关键帧,no use now */
				)
{
	return rate_control->rtn_quant;
}

/*!
 **************************************************************************
 * \brief
 *
 * This function is called once a coded frame to update all internal
 * parameters of 'rate_control'.
 *
 * Returned value : None
 *
 ***************************************************************************
*/

void
RateControlUpdate(RateControl * rate_control,	/*<--> 指向RateControl结构*/
				  uint32_t quant,				/*<--  量化值*/
				  int frame_size,				/*<--  帧大小*/
				  int keyframe					/*<--  是否关键帧*/
				  )
{
	int64_t deviation;
	double overflow, averaging_period, reaction_delay_factor;
	double quality_scale, base_quality, target_quality;
	int32_t rtn_quant;

	rate_control->frames++;
	rate_control->total_size += frame_size;

	deviation =
		( int64_t ) ( (double) rate_control->total_size -
				   ((double)
					((double) rate_control->target_rate / 8.0 /
					 (double) rate_control->framerate) *
					(double) rate_control->frames));
/*分配位数与实际位数的差别*/
	DEBUGCBR((int32_t) (rate_control->frames - 1), rate_control->rtn_quant,
			 (int32_t) deviation);

	if (rate_control->rtn_quant >= 2) 
	{
		averaging_period = (double) rate_control->averaging_period;

		rate_control->sequence_quality -=
			rate_control->sequence_quality / averaging_period;

		rate_control->sequence_quality +=
			2.0 / (double) rate_control->rtn_quant / averaging_period;

		if (rate_control->sequence_quality < 0.1)
			rate_control->sequence_quality = 0.1;

		if ( !keyframe ) 
		{
			reaction_delay_factor =
				(double) rate_control->reaction_delay_factor;

			rate_control->avg_framesize -=
				rate_control->avg_framesize / reaction_delay_factor;

			rate_control->avg_framesize += frame_size / reaction_delay_factor;
		}
/*调整I,P帧,avg_framesize增大,则quality_scale减小,
		base_quality减小,最后的量化值增大*/
	}

	quality_scale =
		rate_control->target_framesize / rate_control->avg_framesize *
		rate_control->target_framesize / rate_control->avg_framesize;
/*衡量质量*/
	base_quality = rate_control->sequence_quality;
	if (quality_scale >= 1.0) {
		base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
	} else {
		base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
	}

	overflow = -((double) deviation / (double) rate_control->buffer);
/*偏差大小*/
	target_quality =
		base_quality + (base_quality -
						0.06452) * overflow / rate_control->target_framesize;
/*偏差大,质量差*/

	if (target_quality > 2.0)
		target_quality = 2.0;
	else if (target_quality < 0.06452)
		target_quality = 0.06452;

	rtn_quant = (int32_t) (2.0 / target_quality);

	if (rtn_quant < 31) {
		rate_control->quant_error[rtn_quant] +=
			2.0 / target_quality - rtn_quant;
		if (rate_control->quant_error[rtn_quant] >= 1.0) {
			rate_control->quant_error[rtn_quant] -= 1.0;
			rtn_quant++;
		}
	}

	if (rtn_quant > rate_control->rtn_quant + 1)
		rtn_quant = rate_control->rtn_quant + 1;
	else if (rtn_quant < rate_control->rtn_quant - 1)
		rtn_quant = rate_control->rtn_quant - 1;

	if (rtn_quant > rate_control->max_quant)
		rtn_quant = rate_control->max_quant;
	else if (rtn_quant < rate_control->min_quant)
		rtn_quant = rate_control->min_quant;

	rate_control->rtn_quant = rtn_quant;
}

/*!
 ****************************************************************************
 * \brief
 * return the first frame quant
 ***************************************************************************
 */

__inline static int						/*==> return init quant */
get_initial_quant(int bpp				/*<-- the param no use now */
				  )
{
	return 8;
}


/*!
 ****************************************************************************
 ======= new quantize,quadratic distortion model,only for I,P=============================
 ======= add by lxq 2002.5.22===============
 ***************************************************************************
 */

/*!
 ****************************************************************************
 *  \brief
 *  init rate control model  param needed   
 *  step 1: Initialization stage
 ***************************************************************************
 */
void RCInitialization(					
					  RCQ2* rc,				/*<--> rc struct */	
					  int bitrate,			/*<--  bits per second*/
					  int framerate,		/*<--  frame number per second*/
					  int sequence_time		/*<--  sequence duration time */
					 
					  )
	{	
		int i=0;
		rch_init(rc->rc_queue);
		rc->Rs=bitrate;
		rc->Ts=sequence_time;
		rc->max_key_interval=framerate*sequence_time;
		rc->Nr=framerate*sequence_time;
		rc->Ns=25/framerate;
		rc->Rf=0;	
		rc->Rr =rc->Ts*rc->Rs;
		rc->Rp = rc->Rs/framerate;
		rc->Bs=rc->Rs*rc->Ts/2;
		rc->B=rc->Bs/2;
		rc->N_Total=0;
		for(i=0;i<2;i++){
			rc->data[i].IsFirst=TRUE;
			rc->data[i].X1=rc->data[i].X2=rc->data[i].X11=0;
			rc->data[i].Rc=0;
			rc->data[i].Ql=rc->data[i].Qc=Get_Initial_Quant(rc,i);
		}
		
	}
/*!
 ****************************************************************************
 * \brief
 *
 * Returned value : - first I or P quantizer value
 *
 ***************************************************************************
 */
	
__inline int Get_Initial_Quant(					/*-->  current frame quant */		
							   RCQ2* rc,		/*<--> rc struct */
							   int frametype	/*<--  I or P frame type */
							   )/*the first param is of no use */ 
{	
	int Q=15;
	switch(frametype)
	{
		case 0:
			Q=15;
			break;
		case 1:
			Q=15;
			break;
	}
	return Q;/*第一个I帧使用的量值*/
}

/*!
 ****************************************************************************
 * \brief
 *
 * get quant before coding each frame
 *
 ***************************************************************************
 */

int RC_GetQ(						/*-->  current frame quant */
			FILE *pfile,			/*<--  file pointer,output stat*/
			RCQ2* rc,				/*<--> rc struct */
			int frametype,			/*<--  I or P frame type */
			int mad					/*<--  frame mad */
			)
/* the third param is of no use */
{

/*	rc->data[frametype].Ec=mad;        */
	if(frametype==0&&rc->Nr<=0)
	{

		rc->Nr=rc->max_key_interval;
		if(rc->Rr>0 )         /*下溢*/
			rc->Rr = rc->Ts*rc->Rs;			/* total number of bits available for this segment */
		else
			rc->Rr+= rc->Ts*rc->Rs;/*只对上溢进行处理*/
  
	}
	if(rc->data[frametype].IsFirst){
		rc->data[frametype].IsFirst=FALSE;
		
		return Get_Initial_Quant(rc,frametype);

	}
	else
	{	
	
		Target_Bit_Calculation(rc,frametype);
		Quantisation_Calculation(pfile,rc,frametype);
	/*	printf("rc->Ec=%d ,rc->T=%d ,rc->Qc=%d ,rc->Nr=%d\n",rc->data[frametype].Ec,rc->T,rc->data[frametype].Qc,rc->Nr);*/
#ifdef stat_output
		fprintf(pfile,"frametype=%d,rc->Ec=%d ,rc->T=%d ,rc->Qc=%d ,rc->Nr=%d\n",frametype,rc->data[frametype].Ec,rc->T,rc->data[frametype].Qc,rc->Nr);
#endif
		return rc->data[frametype].Qc;
	}


}

/*!
 ****************************************************************************

⌨️ 快捷键说明

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