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

📄 encoder.h

📁 经典的MP4编解码核心库
💻 H
字号:

#ifndef _ENCODER_H_
#define _ENCODER_H_


#include "../mp4v.h"
#include "../common/common.h"
#include "../image/image.h"

// indicates no quantizer changes in INTRA_Q/INTER_Q modes
#define NO_CHANGE 64

void select_optcode_encoder(uint32_t cpu_flags);

int RMP4_enc_open(MP4V_ENC_PARAM * pParam);
int RMP4_enc_close(Encoder * pEnc);
int RMP4_enc_processing(Encoder * pEnc, MP4V_ENC_FRAME * pFrame);

// Added by David, 2002
#define TRB_Max	4

int RateControlInit(RateControl *rc, int32_t target_rate, int32_t reaction_delay_factor, int framerate,
		     int max_quant, int min_quant, double buffered_delay, int rc_mode, int quant, int quality);

int GetEstimatedQ(RateControl *rc);

int RateControlGetQ(RateControl *rc, const int32_t coding_type, const int32_t BVOP_following);

int RateControlUpdate(RateControl *rc, int16_t quant, const int32_t frame_size, const int32_t vop_type);

void find_distortion(RateControl *rc, uint8_t *org, uint8_t *rec, int32_t width, int32_t height);
void find_vop_properties(RateControl *rc, uint8_t *src, uint8_t *rec, uint32_t width, uint32_t height,\
						 MACROBLOCK *pMBs, uint32_t mb_width, uint32_t mb_height);

static __inline int IVOP_encode(Encoder * pEnc);
static __inline int PVOP_encode(Encoder * pEnc, bool force_inter);
static __inline int BVOP_encode(Encoder * pEnc, uint32_t TRB, uint32_t TRD);


#define Dark_threshold		30
#define Bright_threshold	180

static int DQtab[4] = 
{
	-1, -2, 1, 2
};


__inline void setMB_quant(const int32_t vop_type, MACROBLOCK *pMBs, uint32_t iquant, uint32_t iMB_number)
{
	uint32_t i;
	switch(vop_type)
	{
	case I_VOP:
	 for(i=0; i<iMB_number; i++)
	 {
		pMBs->quant = iquant;
		pMBs->dquant = NO_CHANGE;
		pMBs->mode = MODE_INTRA;
		pMBs ++;
	 }
	 break;
	case P_VOP:
	 for(i=0; i<iMB_number; i++)
	 {
		pMBs->quant = iquant;
		pMBs->dquant = NO_CHANGE;
		pMBs ++;
	 }
	 break;
	case B_VOP:
	 for(i=0; i<iMB_number; i++)
	 {
		pMBs->quant = iquant;
		pMBs->dquant = NO_CHANGE;
		pMBs ++;
	 }
	 break;
	}

}

/*******************************************
 *  Measure complexity of VOP to be encoded
 *  David, Sigma Designs
 *  Apr.29, 2002
 *******************************************/
__inline int32_t Complexity_I(MACROBLOCK *pMBs, int32_t iHsize, int32_t iVsize)
{
	int32_t x, y;

	MACROBLOCK *pMB;

	int32_t complex = 0;
	int32_t cur_cmp;
	int32_t bright;
	int32_t mean_complex;
	int32_t mean_bright = 0;
	int32_t inverse_mean_bright;
	int32_t half_mean_bright;
	int32_t double_mean_bright;
	int32_t add_comp;
	int32_t num_mb = iVsize*iHsize;

	for(y=0; y<iVsize; y++)
	{
  	  pMB = pMBs+y*iHsize;

	  for(x=0; x<iHsize; x++)
	  {
		cur_cmp = pMB->dev16;
		mean_bright += pMB->mean16;

		pMB->mb_complex = cur_cmp;

		complex += cur_cmp;
		pMB++;
	  }
	}

	mean_complex = complex/num_mb;
	mean_bright = mean_bright / num_mb;
	inverse_mean_bright = (1<<16)/mean_bright+1;
	half_mean_bright = mean_bright >> 1;
	if(half_mean_bright < Dark_threshold)
		half_mean_bright = Dark_threshold;

	double_mean_bright = mean_bright << 1;
	if(double_mean_bright > Bright_threshold)
		double_mean_bright = Bright_threshold;

	for(y=0; y<iVsize; y++)
	{
  	  pMB = pMBs+y*iHsize;

	  for(x=0; x<iHsize; x++)
	  {
		bright = pMB->mean16;
		
		add_comp = 0;
		if(bright > Bright_threshold && bright > double_mean_bright)
			add_comp = ((bright-mean_bright)*mean_complex*inverse_mean_bright)>>16;

		if(bright < Dark_threshold&& bright < half_mean_bright)
			add_comp = ((mean_bright - bright)*mean_complex*inverse_mean_bright)>>16;
		
		pMB->mb_complex += add_comp;
		complex += add_comp;

		pMB++;
	  }
	}

	mean_complex = complex/num_mb;

	return mean_complex;
}

__inline int Complexity_P(MACROBLOCK *pMBs, int iHsize, int iVsize)
{
	int x, y;

	MACROBLOCK *pMB;

	int complex = 0;
	int mode;
	int cur_cmp;
	int mean_complex;
	int32_t mean_bright = 0;
	int32_t bright;
	int32_t inverse_mean_bright;
	int32_t half_mean_bright;
	int32_t double_mean_bright;
	int32_t add_comp;
	int32_t num_mb = iVsize*iHsize;

	for(y=0; y<iVsize; y++)
	{
  	  pMB = pMBs+y*iHsize;

	  for(x=0; x<iHsize; x++)
	  {
		mode = pMB->mode;
		mean_bright += pMB->mean16;

		if(mode == MODE_INTER || mode == MODE_INTER_Q)
			cur_cmp = pMB->sad16;
		else if(mode == MODE_INTER4V)
			cur_cmp = pMB->sad8_mb;
		else  //INTRA
		{
			cur_cmp = pMB->dev16;
		}

		cur_cmp ++;
		pMB->mb_complex += cur_cmp;
		complex += cur_cmp;
		pMB ++;
	  }
	}

	mean_complex = complex/num_mb;
	mean_bright = mean_bright/num_mb + 1;
	inverse_mean_bright = (1<<16)/mean_bright+1;
	half_mean_bright = mean_bright >> 1;
	if(half_mean_bright < Dark_threshold)
		half_mean_bright = Dark_threshold;

	double_mean_bright = mean_bright << 1;
	if(double_mean_bright > Bright_threshold)
		double_mean_bright = Bright_threshold;

	for(y=0; y<iVsize; y++)
	{
  	  pMB = pMBs+y*iHsize;

	  for(x=0; x<iHsize; x++)
	  {
		mode = pMB->mode;
		bright = pMB->mean16;
		add_comp = 0;

		if(mode != MODE_INTRA)
		{
		  if(bright > Bright_threshold && bright > double_mean_bright)
			add_comp = ((bright-mean_bright)*mean_complex*inverse_mean_bright)>>16;

		  if(bright < Dark_threshold&& bright < half_mean_bright)
			add_comp = ((mean_bright - bright)*mean_complex*inverse_mean_bright)>>16;

		  pMB->mb_complex += add_comp;

		  complex += add_comp;
		}

		pMB ++;
	  }
	}

	mean_complex = complex/num_mb;
	return mean_complex;
}

__inline int Complexity_B(MACROBLOCK *pMBs, int iHsize, int iVsize)
{
	int32_t x, y;

	MACROBLOCK *pMB;

	int32_t complex = 0;
	int32_t cur_cmp;
	int32_t mean_complex;

	int32_t mean_bright = 0;
	int32_t bright;
	int32_t inverse_mean_bright;
	int32_t half_mean_bright;
	int32_t double_mean_bright;
	int32_t add_comp;
	int32_t num_mb = iVsize*iHsize;

	for(y=0; y<iVsize; y++)
	{
	  pMB = pMBs+y*iHsize;
	  for(x=0; x<iHsize; x++)
	  {
		cur_cmp = pMB->sad16;
		mean_bright += pMB->mean16;

		cur_cmp ++;

		complex += cur_cmp;
		pMB->mb_complex += cur_cmp;

		pMB++;
	  }
	}

	mean_complex = complex/num_mb;
	mean_bright = mean_bright/num_mb+1;
	inverse_mean_bright = (1<<16)/mean_bright+1;

	half_mean_bright = mean_bright >> 1;
	if(half_mean_bright < Dark_threshold)
		half_mean_bright = Dark_threshold;

	double_mean_bright = mean_bright << 1;
	if(double_mean_bright > Bright_threshold)
		double_mean_bright = Bright_threshold;

	for(y=0; y<iVsize; y++)
	{
  	  pMB = pMBs+y*iHsize;

	  for(x=0; x<iHsize; x++)
	  {		
		bright = pMB->mean16;
		
	    if(bright > Bright_threshold && bright > half_mean_bright)
			add_comp = ((bright-mean_bright)*mean_complex*inverse_mean_bright)>>16;

		if(bright < Dark_threshold&& bright < double_mean_bright)
			add_comp = ((mean_bright - bright)*mean_complex*inverse_mean_bright)>>16;

		pMB->mb_complex += add_comp;
		complex += add_comp;

		pMB ++;
	  }
	}

	mean_complex = complex / num_mb;
	return mean_complex;
}


/*******************************************
 *  Measure Activity of Encoded Image
 *  For P-only or PB decision
 *  David, Sigma Designs
 *  Feb.21, 2002
 *******************************************/
__inline int measureActivity(MACROBLOCK *pMBs, int iHsize, int iVsize, int iQuant,
							 int32_t *iMvCurVOP, int32_t *iMvCount)
{
	int32_t x, y;

	MACROBLOCK *pMB;
	int32_t act = 0;
	int32_t mode;
	int32_t cur_act = 0; 

	*iMvCount = 0;
	*iMvCurVOP = 0;

	for(y=0; y<iVsize; y++)
	{
	  pMB = pMBs+y*iHsize;
	  for(x=0; x<iHsize; x++)
	  {		
		mode = pMB->mode;

		if(mode == MODE_INTER || mode == MODE_INTER_Q)
			cur_act = abs(pMB->mvs[0].x) + abs(pMB->mvs[0].y);
		else
		{
			if(mode == MODE_INTER4V)
				cur_act =  (abs(pMB->mvs[0].x) + abs(pMB->mvs[0].y) + 
						 abs(pMB->mvs[1].x) + abs(pMB->mvs[1].y) + 
						 abs(pMB->mvs[2].x) + abs(pMB->mvs[2].y) + 
						abs(pMB->mvs[3].x) + abs(pMB->mvs[3].y)
						)>>2;
			else
				cur_act = 0;
		}

		act += cur_act;
		pMB->mb_complex = cur_act*iQuant;

		if(cur_act)
		{
			(*iMvCurVOP) += cur_act;
			(*iMvCount) ++;
		}

		pMB++;
	  }
	}
#ifdef _STAT_
	printf("\niMVvop=%d, iMvcount=%d\n", *iMvCurVOP, *iMvCount);
#endif
	if(*iMvCount == 0)
		*iMvCount = 1;

	return (act/(iVsize*iHsize));
}

/*******************************************
 *  Measure Activity of Encoded Image
 *  For P-only or PB decision
 *  Measure the motion activity of BVOP
 *  David, Sigma Designs
 *  Feb.21, 2002
 *******************************************/
__inline int measureActivity_B(MACROBLOCK *pMBs, int iHsize, int iVsize, int iQuant)
{
	int x, y;

	MACROBLOCK *pMB;

	int act = 0;
	int act_for, act_back;
	int cur_act = 0;
	int mode;

	for(y=0; y<iVsize; y++)
	for(x=0; x<iHsize; x++)
	{
		pMB = pMBs+y*iHsize+x;
		mode = pMB->mode;

		if(mode == MBM_B_FWDFRM)
		  cur_act = abs(pMB->mvs[0].x) + abs(pMB->mvs[0].y);
		else
		{
			if(mode == MBM_B_BAKFRM)
			  cur_act = abs(pMB->mvs[1].x) + abs(pMB->mvs[1].y);
			else
			{
				if(mode == MBM_B_AVEFRM || mode == MBM_B_DIRECT)
				{
					act_for = abs(pMB->mvs[0].x) + abs(pMB->mvs[0].y);
					act_back = abs(pMB->mvs[1].x) + abs(pMB->mvs[1].y);

					if(act_for > act_back)
						cur_act = act_for;
					else
						cur_act = act_back;
				}
				else
					cur_act = 0;
			}
		}

		act += cur_act;
		pMB->mb_complex = cur_act;
	}

	return (act/(iVsize*iHsize));
}

static __inline uint8_t get_fcode(uint16_t sr)
{
    if (sr <= 16)
		return 1;

    else if (sr <= 32) 
		return 2;

    else if (sr <= 64)
		return 3;

    else if (sr <= 128)
		return 4;

    else if (sr <= 256)
		return 5;

    else if (sr <= 512)
		return 6;

    else if (sr <= 1024)
		return 7;

    else
		return 0;
}

__inline uint8_t * align_malloc(uint32_t size)
{
	uint8_t * mem, *mem_ptr;

	mem = (uint8_t *)malloc(size+32);

	mem_ptr = (uint8_t *)(((uint32_t)mem + 16)&(~15));
	
	*(mem_ptr-1) = mem_ptr - mem;

	return mem_ptr;
}

__inline void align_free(uint8_t *mem_ptr)
{
	uint8_t *mem = mem_ptr - *(mem_ptr-1);

	free(mem);
}

#define ENC_VALIDATE(X) if(!(X)) return MP4V_ERR_FORMAT

#endif /* _ENCODER_H_ */

⌨️ 快捷键说明

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