fseek(state->pass1_file,0,SEEK_CUR);
static vbr_get_intra_function vbr_getintra_fixedquant;/* Sub vbrUpdate prototypes */static vbr_update_function vbr_update_dummy;static vbr_update_function vbr_update_2pass1;static vbr_update_function vbr_update_2pass2;/* Sub vbrFinish cases functions */static vbr_finish_function vbr_finish_dummy;static vbr_finish_function vbr_finish_2pass1;static vbr_finish_function vbr_finish_2pass2;/*------------MEANX------------------*//*	This table gives more strength to I frame	The average I frame should be around 10*/static int  vbr_make_variance(vbr_control_t *state, float compression,  int *variance,int *bitrate);static int vbr_getstuff(vbr_control_t *state, int dbytes,double diff);static int  vbr_make_clipping(vbr_control_t *state, float compression);static const int quant_I_modifier[32]={	2,	2,	2,	3,	//00--33	4,	5,	6,	6,	//4--7	7, 	7, 	8,	8,   	//8--11	9,	9, 	10,	10, 	//12--15	11,	12, 	12,	13,	//16--19	13,	14, 	14,	14,	//20--23	15,	15,	15, 	16,	//24--27	16,	16,	17,	17  //28--31};/*	That one gives less to B frame*/static const int quant_B_modifier[32]={	3,	3,	3,	3,	//00--33	5,	6,	8,	9,	//4--7	10, 	11, 	12,	13,   	//8--11	14,	16, 	17,	18, 	//12--15	20,	21, 	23,	24,	//16--19	25,	26, 	28,	29,	//20--23	30,	30,	31, 	31,	//24--27	31,	31,	31,	31  //28--31};/*------------MEANX------------------*//* Is the encoder in the credits */#define FRAME_TYPE_NORMAL_MOVIE     0x00#define FRAME_TYPE_STARTING_CREDITS 0x01#define FRAME_TYPE_ENDING_CREDITS   0x02/****************************************************************************** * Inline utility functions *****************************************************************************/static __inline int util_frametype(vbr_control_t *state){	if(state->credits_start) {		if(state->cur_frame >= state->credits_start_begin &&		   state->cur_frame < state->credits_start_end)			return(FRAME_TYPE_STARTING_CREDITS);	}	if(state->credits_end) {		if(state->cur_frame >= state->credits_end_begin &&		   state->cur_frame < state->credits_end_end)			return(FRAME_TYPE_STARTING_CREDITS);	}	return(FRAME_TYPE_NORMAL_MOVIE);}static __inline int util_creditsframes(vbr_control_t *state){	int frames = 0;	if(state->credits_start)		frames += state->credits_start_end - state->credits_start_begin;	if(state->credits_end)		frames += state->credits_end_end - state->credits_end_begin;	return(frames);}/****************************************************************************** * Functions *****************************************************************************//***************************************************************************** * Function description : * * This function initialiazes the vbr_control_t with safe defaults for all * modes. * * Return Values : *   = 0 ****************************************************************************/int vbrSetDefaults(vbr_control_t *state){	/* Set all the structure to zero */	memset(state, 0, sizeof(state));	/* Default mode is CBR */	state->mode = VBR_MODE_1PASS;	/* Default statistic filename */	state->filename = DEFAULT_XVID_STATS_FILE;	/*	 * Default is a 2hour movie on 700Mo CD-ROM + 128kbit sound track	 * This represents a target bitrate of 687kbit/s	 */	state->desired_size = DEFAULT_DESIRED_SIZE*1024*1024 -		DEFAULT_MOVIE_LENGTH*3600*DEFAULT_AUDIO_BITRATE*1000/8;	state->desired_bitrate = state->desired_size*8/(DEFAULT_MOVIE_LENGTH*3600);	/* Credits */	state->credits_mode = VBR_CREDITS_MODE_RATE;	state->credits_start = 0;	state->credits_start_begin = 0;	state->credits_start_end = 0;	state->credits_end = 0;	state->credits_end_begin = 0;	state->credits_end_end = 0;	state->credits_quant_ratio = 20;	state->credits_fixed_quant = 20;	state->credits_quant_i = 20;	state->credits_quant_p = 20;	state->credits_start_size = DEFAULT_CREDITS_SIZE*1024*1024;	state->credits_end_size = DEFAULT_CREDITS_SIZE*1024*1024;	/* Keyframe boost */	state->keyframe_boost = 0;	state->kftreshold = 10;	state->kfreduction = 30;	state->min_key_interval = 1;	state->max_key_interval = (int)DEFAULT_FPS*10;	/* Normal curve treatment */	state->curve_compression_high = 25;	state->curve_compression_low = 10;	/* Alt curve */	state->use_alt_curve = 1;	state->alt_curve_type = VBR_ALT_CURVE_LINEAR;	state->alt_curve_low_dist = 90;	state->alt_curve_high_dist = 500;	state->alt_curve_min_rel_qual = 50;	state->alt_curve_use_auto = 1;	state->alt_curve_auto_str = 30;	state->alt_curve_use_auto_bonus_bias = 1;	state->alt_curve_bonus_bias = 50;	state->bitrate_payback_method = VBR_PAYBACK_BIAS;	state->bitrate_payback_delay = 250;	state->twopass_max_bitrate = DEFAULT_TWOPASS_BOOST*state->desired_bitrate;	state->twopass_max_overflow_improvement = 60;	state->twopass_max_overflow_degradation = 60;	state->max_iquant = 31;	state->min_iquant = 2;	state->max_pquant = 31;	state->min_pquant = 2;	state->fixed_quant = 3;	state->max_framesize = (1.0/(float)DEFAULT_FPS) * state->twopass_max_bitrate / 8;	state->fps = (float)DEFAULT_FPS;	state->maxAllowedBitrate=0;	return(0);}/***************************************************************************** * Function description : * * This function initialiaze the vbr_control_t state passed in parameter. * * The initialization depends on state->mode, there are 4 modes allowed. * Each mode description is done in the README file shipped with the lib. * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrInit(vbr_control_t *state){	if(state == NULL) return(-1);	/* Function pointers safe initialization */	state->init     = NULL;	state->getquant = NULL;	state->getintra = NULL;	state->update   = NULL;	state->finish   = NULL;// MeanX	state->roundup=(int)floor(state->fps+0.99);	memset(state->b_per_sec,0,sizeof(int)*60);	state->size   = NULL;	state->kf   = NULL;	state->type   = NULL;	printf("\n Roundup : %d\n",state->roundup);// MeanX	if(state->debug) {		state->debug_file = fopen(DEFAULT_XVID_DBG_FILE, "w+");		if(state->debug_file == NULL)			return(-1);		fprintf(state->debug_file, "# XviD Debug output\n");		fprintf(state->debug_file, "# quant | intra | header bytes"			"| total bytes | kblocks | mblocks | ublocks"			"| vbr overflow | vbr kf overflow"			"| vbr kf partial overflow\n\n");	}	/* Function pointers sub case initialization */	switch(state->mode) {	case VBR_MODE_1PASS:		state->init     = vbr_init_dummy;		state->getquant = vbr_getquant_1pass;		state->getintra = vbr_getintra_1pass;		state->update   = vbr_update_dummy;		state->finish   = vbr_finish_dummy;		break;	case VBR_MODE_2PASS_1:		state->init     = vbr_init_2pass1;		state->getquant = vbr_getquant_2pass1;		state->getintra = vbr_getintra_2pass1;		state->update   = vbr_update_2pass1;		state->finish   = vbr_finish_2pass1;		break;	case VBR_MODE_FIXED_QUANT:		state->init     = vbr_init_fixedquant;		state->getquant = vbr_getquant_fixedquant;		state->getintra = vbr_getintra_fixedquant;		state->update   = vbr_update_dummy;		state->finish   = vbr_finish_dummy;		break;	case VBR_MODE_2PASS_2:		state->init     = vbr_init_2pass2;		state->getintra = vbr_getintra_2pass2;		state->getquant = vbr_getquant_2pass2;		state->update   = vbr_update_2pass2;		state->finish   = vbr_finish_2pass2;		break;	default:		return(-1);	}		return(state->init(state));}/****************************************************************************** * Function description : * * This function returns an adapted quantizer according to the current vbr * controler state * * Return values : *  the quantizer value (0 <= value <= 31) *  (0 is a special case, means : let XviD decide) * *****************************************************************************/int vbrGetQuant(vbr_control_t *state){	/* Returns Zero, so XviD decides alone */	if(state == NULL || state->getquant == NULL) return(0);	return(state->getquant(state));}/****************************************************************************** * Function description : * * This function returns the type of the frame to be encoded next (I or P/B) * * Return values : *  = -1 let the XviD encoder decide wether or not the next frame is I *  =  0 no I frame *  =  1 force keyframe * *****************************************************************************/int vbrGetIntra(vbr_control_t *state){	/* Returns -1, means let XviD decide */	if(state == NULL || state->getintra == NULL) return(-1);	return(state->getintra(state));}/****************************************************************************** * Function description : * * This function updates the vbr control state according to collected statistics * from XviD core * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrUpdate(vbr_control_t *state,	      int quant,	      int intra,	      int header_bytes,	      int total_bytes,	      int kblocks,	      int mblocks,	      int ublocks){	if(state == NULL || state->update == NULL) return(-1);	if(state->debug && state->debug_file != NULL) {		int idx;		fprintf(state->debug_file, "%d %d %d %d %d %d %d %d %d %d\n",			quant, intra, header_bytes, total_bytes, kblocks,			mblocks, ublocks, state->overflow, state->KFoverflow,			state->KFoverflow_partial);		idx = quant;		if(quant < 1)			idx = 1;		if(quant > 31)			idx = 31;		idx--;		state->debug_quant_count[idx]++;	}	return(state->update(state, quant, intra, header_bytes, total_bytes,			     kblocks, mblocks, ublocks));}/****************************************************************************** * Function description : * * This function stops the vbr controller * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrFinish(vbr_control_t *state){	if(state == NULL || state->finish == NULL) return(-1);	if(state->debug && state->debug_file != NULL) {		int i;		fprintf(state->debug_file, "\n\n");		for(i=0; i<79; i++)			fprintf(state->debug_file, "#");		fprintf(state->debug_file, "\n# Quantizer distribution :\n\n");		for(i=0;i<32; i++) {			fprintf(state->debug_file, "# quant %d : %d\n",				i+1,				state->debug_quant_count[i]);		}		fclose(state->debug_file);	}	return(state->finish(state));}/****************************************************************************** * Dummy functions - Used when a mode does not need such a function *****************************************************************************/static int vbr_init_dummy(void *sstate){	vbr_control_t *state = sstate;	state->cur_frame = 0;	return(0);}static int vbr_update_dummy(void *state,			    int quant,			    int intra,			    int header_bytes,			    int total_bytes,			    int kblocks,			    int mblocks,			    int ublocks){	quant=intra+header_bytes+total_bytes+kblocks+mblocks+ublocks; // MEANX : No warning	((vbr_control_t*)state)->cur_frame++;	return(0);}static int vbr_finish_dummy(void *state){	if(state)	{	}	return(0);}/****************************************************************************** * 1 pass mode - XviD will do its job alone. *****************************************************************************/static int vbr_getquant_1pass(void *state){if(state)	{	}	return(0);}static int vbr_getintra_1pass(void *state){if(state)	{	}	return(-1);}/****************************************************************************** * 2 pass mode - first pass functions *****************************************************************************/static int vbr_init_2pass1(void *sstate){	FILE *f;	vbr_control_t *state = sstate;	/* Check the filename */	if(state->filename == NULL || state->filename[0] == '\0')		return(-1);	printf("XvidVBR: initialized with file :%s, pass 1\n",state->filename);	/* Initialize safe defaults for 2pass 1 */ 	state->pass1_file = NULL;	state->nb_frames = 0;	state->nb_keyframes = 0;	state->cur_frame = 0;	/* Open the 1st pass file */	if((f = fopen(state->filename, "w+")) == NULL)		return(-1);	/*	 * The File Header	 *	 * The extra white spaces will be used during the vbrFinish to write	 * the resulting number of frames and keyframes (10 spaces == maximum	 * string length of an int on 32bit machines, i don't think anyone is	 * encoding more than 4 billion frames :-)	 */	fprintf(f, "# ASCII XviD vbr stat file version %d\n#\n", VBR_VERSION);	fprintf(f, "# frames    :           \n");	fprintf(f, "# keyframes :           \n");	fprintf(f, "#\n# quant | intra | header bytes | total bytes | kblocks |"		" mblocks | ublocks\n\n");	/* Save file pointer */	state->pass1_file   = f;	return(0);}static int vbr_getquant_2pass1(void *state){if(state){}	return(2);}static int vbr_getintra_2pass1(void *state){if(state){}	return(-1);}static int vbr_update_2pass1(void *sstate,			     int quant,			     int intra,			     int header_bytes,			     int total_bytes,			     int kblocks,			     int mblocks,			     int ublocks)			     {	vbr_control_t *state = sstate;	if(state->pass1_file == NULL)		return(-1);	/* Writes the resulting statistics */	fprintf(state->pass1_file, "%d %d %d %d %d %d %d\n",		quant,		intra,		header_bytes,		total_bytes,		kblocks,		mblocks,		ublocks);	/* Update vbr control state */	if(intra) state->nb_keyframes++;	state->nb_frames++;	state->cur_frame++;	return(0);	}static int vbr_finish_2pass1(void *sstate){	int c, i;	vbr_control_t *state = sstate;	if(state->pass1_file == NULL)		return(-1);	/* Goto to the file beginning */	fseek(state->pass1_file, 0, SEEK_SET);	/* Skip the version line  and the empty line */	c = i = 0;	do {		c = fgetc(state->pass1_file);		if(c == EOF) return(-1);		if(c == '\n') i++;	}while(i < 2);	/* Overwrite the frame field - safe as we have written extra spaces */	fprintf(state->pass1_file, "# frames    : %.10d\n", state->nb_frames);	/* Overwrite the keyframe field */	fprintf(state->pass1_file, "# keyframes : %.10d\n",		state->nb_keyframes);	/* Close the file */	if(fclose(state->pass1_file) != 0)		return(-1);	return(0);}/****************************************************************************** * 2 pass mode - 2nd pass functions (Need to be finished) *****************************************************************************/static int vbr_init_2pass2(void *sstate){	FILE *f;	int c, n, pos_firstframe, credits_frames;	long long credits1_bytes;	long long credits2_bytes;	long long desired;	long long total_bytes;	long long itotal_bytes;	long long start_curved;	long long end_curved;	double total1;	double total2;	int precalced=0;	vbr_control_t *state = sstate;	/* Check the filename */	if(state->filename == NULL || state->filename[0] == '\0')		return(-1);	/* Initialize safe defaults for 2pass 2 */ 	state->pass1_file = NULL;	state->nb_frames = 0;	state->nb_keyframes = 0;	/* Open the 1st pass file */	if((f = fopen(state->filename, "r")) == NULL)		return(-1);	printf("XvidVBR: initialized with file :%s, pass 2\n",state->filename);	state->pass1_file = f;	/* Get the file version and check against current version */	fscanf(state->pass1_file, "# ASCII XviD vbr stat file version %d\n", &n);	if(n != VBR_VERSION) {		fclose(state->pass1_file);		state->pass1_file = NULL;		return(-1);	}	/* Skip the blank commented line */	c = n = 0;	do {		c = fgetc(state->pass1_file);		if(c == EOF) {			fclose(state->pass1_file);			state->pass1_file = NULL;			return(-1);		}		if(c == '\n') n++;	}while(n < 1);	/* Get the number of frames */	fscanf(state->pass1_file, "# frames : %d\n", &state->nb_frames);	/* Compute the desired size */	state->desired_size = (long long)		(((long long)state->nb_frames * (long long)state->desired_bitrate) /		 (state->fps * 8.0));	/* Get the number of keyframes */	fscanf(state->pass1_file, "# keyframes : %d\n", &state->nb_keyframes);	/* Allocate memory space for the keyframe_location array */	if((state->keyframe_locations	    = (int*)malloc((state->nb_keyframes+1)*sizeof(int))) == NULL) {		fclose(state->pass1_file);		state->pass1_file = NULL;		return(-1);	}	/* Skip the blank commented line and the colum description */	c = n = 0;	do {		c = fgetc(state->pass1_file);		if(c == EOF) {			fclose(state->pass1_file);			state->pass1_file = NULL;			return(-1);		}		if(c == '\n') n++;	}while(n < 2);	/* Save position for future use */	pos_firstframe = ftell(state->pass1_file);_AGAIN_:	/* Read and initialize some variables */	credits1_bytes = credits2_bytes = 0;	total_bytes = itotal_bytes = 0;	start_curved = end_curved = 0;	credits_frames = 0;	// MeanX	//---------------------------------MeanX----------------------------------	if(!precalced)	{		printf("nb_frames : %d\n",state->nb_frames);		state->size=(int *)malloc(sizeof(int)*state->nb_frames);		state->kf=(int *)malloc(sizeof(int)*state->nb_frames);		state->type=(int *)malloc(sizeof(int)*state->nb_frames);	// 1 read the whole file in memory	//-----------------------------------------------------		for(state->cur_frame=0; state->cur_frame<state->nb_frames; state->cur_frame++)		{			int quant, keyframe, frame_hbytes, frame_bytes;			int kblocks, mblocks, ublocks;			fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",		       	&quant, &keyframe, &frame_hbytes, &frame_bytes,			       &kblocks, &mblocks, &ublocks);			//			// rescale			frame_bytes=(frame_bytes*quant)>>1;			// In case of max allowed byterate we caps the size to avoid			// having a ridiculously high ratio between in quant and out quant			// ublocks is the frame type : 1 -> I / 2-> P/ 3-> B			state->size[state->cur_frame]=frame_bytes;			state->type[state->cur_frame]=ublocks;			state->kf[state->cur_frame]=keyframe;		}	} // /precalced	// 2- compute size/*---------------------------------------------------------------------------------------------------------------------------*/	for(state->cur_frame = c = 0; state->cur_frame<state->nb_frames; state->cur_frame++)	{		int  keyframe,  frame_bytes;		keyframe=state->kf[state->cur_frame];		frame_bytes=state->size[state->cur_frame];		/* Is the frame in the beginning credits */		if(util_frametype(state) == FRAME_TYPE_STARTING_CREDITS) {			credits1_bytes += frame_bytes;			credits_frames++;			continue;		}		/* Is the frame in the eding credits */		if(util_frametype(state) == FRAME_TYPE_ENDING_CREDITS) {			credits2_bytes += frame_bytes;			credits_frames++;			continue;		}		//		//		/* We only care about Keyframes when not in credits */		if(keyframe) {			itotal_bytes +=	frame_bytes + frame_bytes *				state->keyframe_boost / 100;			total_bytes  += frame_bytes *				state->keyframe_boost / 100;			state->keyframe_locations[c++] = state->cur_frame;		}		total_bytes += frame_bytes;	}	/*-----------------------------------------------------------------------------------------*/		printf("__________________\n");		printf("desired size : %09lld\n",state->desired_size);		printf("pass1   size : %09lld\n",total_bytes);		printf("__________________\n");	// 3- lookup cap/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*//* Meanx*/	/* Here we check if there is a cap influence */#if 1	if(state->maxAllowedBitrate && !precalced) // maxAllowedBitrte is in BYTE/second not bit/s	{		float var;		int bitrate;		int out_bitrate[32];		int i;		int error,index;				printf("Desired bitrate : %d\n",state->desired_bitrate);				for(i=2;i<32;i++)		{				vbr_make_variance(state,i,&var,&bitrate);		out_bitrate[i]=bitrate;		printf("Qz : %d Size: %d Ratio:%f\n",i,out_bitrate[i],(float)out_bitrate[i]/(float)state->desired_bitrate);		}		// search best match		// 20% margin		index=0;		error=30*1000*1000;				for(i=2;i<32;i++)		{			if(abs(out_bitrate[i]-state->desired_bitrate)<error)			{				error=abs(out_bitrate[i]-state->desired_bitrate);				//printf("For quant : %d, error is %d\n",i,error);				index=i;			}			}		printf("Best match found : Quantizer scale = %d\n",index);		if(index)		{			vbr_make_clipping(state,index);		}		precalced=1;		goto _AGAIN_;			}		#endif	/*	 * Last frame is treated like an I Frame so we can dispatch overflow	 * all other the last film segment	 */	state->keyframe_locations[c] = state->cur_frame;	/* Compensate AVI overhead */	desired = state->desired_size -  state->nb_frames*24;	switch(state->credits_mode) {	case VBR_CREDITS_MODE_QUANT :		state->movie_curve = (double)			(total_bytes - credits1_bytes - credits2_bytes) /			(desired  - credits1_bytes - credits2_bytes);		start_curved = credits1_bytes;		end_curved   = credits2_bytes;		break;	case VBR_CREDITS_MODE_SIZE:		/* start curve = (start / start desired size) */		state->credits_start_curve = (double)			(credits1_bytes / state->credits_start_size);		/* end curve = (end / end desired size) */		state->credits_end_curve = (double)			(credits2_bytes / state->credits_end_size);		start_curved = (long long)			(credits1_bytes / state->credits_start_curve);		end_curved   = (long long)			(credits2_bytes / state->credits_end_curve);		/* movie curve=(total-credits)/(desired_size-curved credits) */		state->movie_curve = (double)			(total_bytes - credits1_bytes - credits2_bytes) /			(desired - start_curved - end_curved);		break;	case VBR_CREDITS_MODE_RATE:	default:		/* credits curve = (total/desired_size)*(100/credits_rate) */		state->credits_start_curve = state->credits_end_curve =			((double)total_bytes / desired) *			((double)100 / state->credits_quant_ratio);		start_curved =			(long long)(credits1_bytes/state->credits_start_curve);		end_curved   =			(long long)(credits2_bytes/state->credits_end_curve);		state->movie_curve = (double)			(total_bytes - credits1_bytes - credits2_bytes) /			(desired - start_curved - end_curved);		break;	}	/*	 * average frame size = (desired - curved credits - curved keyframes) /	 *                      (frames - credits frames - keyframes)	 */	state->average_frame = (double)		(desired - start_curved - end_curved -		 (itotal_bytes / state->movie_curve)) /		(state->nb_frames - util_creditsframes(state) -		 state->nb_keyframes);	/* Initialize alt curve parameters */	if (state->use_alt_curve) {		state->alt_curve_low =			state->average_frame - state->average_frame *			(double)(state->alt_curve_low_dist / 100.0);		state->alt_curve_low_diff =			state->average_frame - state->alt_curve_low;		state->alt_curve_high =			state->average_frame + state->average_frame *			(double)(state->alt_curve_high_dist / 100.0);		state->alt_curve_high_diff =			state->alt_curve_high - state->average_frame;		if (state->alt_curve_use_auto) {			if (state->movie_curve > 1.0)	{				state->alt_curve_min_rel_qual =					(int)(100.0 - (100.0 - 100.0 / state->movie_curve) *					      (double)state->alt_curve_auto_str / 100.0);				if (state->alt_curve_min_rel_qual < 20)					state->alt_curve_min_rel_qual = 20;			}			else {				state->alt_curve_min_rel_qual = 100;			}		}		state->alt_curve_mid_qual =		(1.0 + (double)state->alt_curve_min_rel_qual / 100.0) / 2.0;		state->alt_curve_qual_dev = 1.0 - state->alt_curve_mid_qual;		if (state->alt_curve_low_dist > 100) {			switch(state->alt_curve_type) {			case VBR_ALT_CURVE_AGGRESIVE:				/* Sine Curve (high aggressiveness) */				state->alt_curve_qual_dev *=					2.0 /					(1.0 +  sin(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff)));				state->alt_curve_mid_qual =					1.0 - state->alt_curve_qual_dev *					sin(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff));				break;			default:			case VBR_ALT_CURVE_LINEAR:				/* Linear (medium aggressiveness) */				state->alt_curve_qual_dev *=					2.0 /					(1.0 + state->average_frame / state->alt_curve_low_diff);				state->alt_curve_mid_qual =					1.0 - state->alt_curve_qual_dev *					state->average_frame / state->alt_curve_low_diff;				break;			case VBR_ALT_CURVE_SOFT:				/* Cosine Curve (low aggressiveness) */				state->alt_curve_qual_dev *=					2.0 /					(1.0 + (1.0 - cos(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff))));				state->alt_curve_mid_qual =					1.0 - state->alt_curve_qual_dev *					(1.0 - cos(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff)));				break;			}		}	}	/* Go to the first non credits frame stats line into file */	fseek(state->pass1_file, pos_firstframe, SEEK_SET);/*----------------------------------------------------------------------------------------------------------------------------------------------------*/	/* Perform prepass to compensate for over/undersizing */	total1 = total2 = 0.0;	for(state->cur_frame=0; state->cur_frame<state->nb_frames; state->cur_frame++)	{		int quant, keyframe, frame_hbytes, frame_bytes;		int kblocks, mblocks, ublocks;		fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",		       &quant, &keyframe, &frame_hbytes, &frame_bytes,		       &kblocks, &mblocks, &ublocks);		//		// rescale		frame_bytes=state->size[state->cur_frame];		keyframe=state->kf[state->cur_frame];		if(util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE)			continue;		if(!keyframe) {			double dbytes = frame_bytes / state->movie_curve;			total1 += dbytes;			if (state->use_alt_curve) {				if (dbytes > state->average_frame) {					if (dbytes >= state->alt_curve_high) {						total2 += dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev);					}					else {						total2+=vbr_getstuff(state,dbytes, state->alt_curve_high_diff);					}				}				else {					if (dbytes <= state->alt_curve_low) {						total2 += dbytes;					}					else {						total2+=vbr_getstuff(state,dbytes, state->alt_curve_high_diff);					}				}			}			else {				if (dbytes > state->average_frame) {					total2 +=						((double)dbytes +						 (state->average_frame - dbytes) *						 state->curve_compression_high / 100.0);				}				else {					total2 +=						((double)dbytes +						 (state->average_frame - dbytes) *						 state->curve_compression_low / 100.0);				}			}		}	}	state->curve_comp_scale= total1 / total2;	printf("Average comp ratio : %f\n",state->curve_comp_scale);	if (state->use_alt_curve) {		double curve_temp, dbytes;		int newquant, percent;		int oldquant = 1;		if (state->alt_curve_use_auto_bonus_bias)			state->alt_curve_bonus_bias = state->alt_curve_min_rel_qual;		state->curve_bias_bonus =			(total1 - total2) * (double)state->alt_curve_bonus_bias /			(100.0 * (double)(state->nb_frames - util_creditsframes(state) - state->nb_keyframes));		state->curve_comp_scale =			((total1 - total2) * (1.0 - (double)state->alt_curve_bonus_bias / 100.0) + total2) /			total2;		for (n=1; n <= (int)(state->alt_curve_high*2) + 1; n++) {			dbytes = n;			if (dbytes > state->average_frame)			{				if (dbytes >= state->alt_curve_high) {					curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev);				}				else {					curve_temp=vbr_getstuff(state,dbytes, state->alt_curve_high_diff);					}			}			else {				if (dbytes <= state->alt_curve_low) {					curve_temp = dbytes;				}				else {				curve_temp=vbr_getstuff(state,dbytes,state->alt_curve_low_diff);				}			}			if (state->movie_curve > 1.0)				dbytes *= state->movie_curve;			newquant = (int)(dbytes * 2.0 / (curve_temp * state->curve_comp_scale + state->curve_bias_bonus));			if (newquant > 1)			{				if (newquant != oldquant)				{					oldquant = newquant;					percent = (int)((n - state->average_frame) * 100.0 / state->average_frame);				}			}		}	}	state->overflow = 0;	state->KFoverflow = 0;	state->KFoverflow_partial = 0;	state->KF_idx = 1;	for (n=0 ; n < 32 ; n++) {		state->quant_error[n] = 0.0;		state->quant_count[n] = 0;	}	state->curve_comp_error = 0.0;	state->last_quant = 0;	/*	 * Above this frame size limit, normal vbr rules will not apply	 * This means :	 *      1 - Quant can de/increase more than -/+2 between 2 frames	 *      2 - Leads to artifacts because of 1	 */	state->max_framesize = state->twopass_max_bitrate/state->fps;	/* Get back to the beginning of frame statistics */	fseek(state->pass1_file, pos_firstframe, SEEK_SET);	/*	 * Small hack : We have to get next frame stats before the	 * getintra/quant calls	 * User clients update the data when they call vbrUpdate	 * we are just bypassing this because we don't have to update	 * the overflow and so on...	 */	{		/* Fake vars */		int next_hbytes, next_kblocks, next_mblocks, next_ublocks;		fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",		       &state->pass1_quant, &state->pass1_intra, &next_hbytes,		       &state->pass1_bytes, &next_kblocks, &next_mblocks,		       &next_ublocks);	}	/* MeanX same as before, scale it to 2 */		state->pass1_bytes=state->size[0];;		state->pass1_quant=2;	/* /MeanX*/	/* Initialize the frame counter */	state->cur_frame = 0;	state->last_keyframe = 0;	return(0);}static int vbr_getquant_2pass2(void *sstate){	int quant;	int intra;	int bytes1, bytes2;	int overflow;	int capped_to_max_framesize = 0;	int KFdistance, KF_min_size;	vbr_control_t *state;	int i;	int sum=0;	int ratio;	int target;	int projected ;	double r;	 state= (vbr_control_t	* )sstate;	 target=state->cur_frame%state->roundup;	bytes1 = state->pass1_bytes;	overflow = state->overflow / 8;	/* To shut up gcc warning */	bytes2 = bytes1;	if (state->pass1_intra)	{		overflow = 0;	}	if (util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE)	{		switch (state->credits_mode) {		case VBR_CREDITS_MODE_QUANT :			if (state->credits_quant_i != state->credits_quant_p) {				quant = state->pass1_intra ?					state->credits_quant_i:					state->credits_quant_p;			}			else {				quant = state->credits_quant_p;			}			state->bytes1 = bytes1;			state->bytes2 = bytes1;			state->desired_bytes2 = bytes1;			return(quant);		default:		case VBR_CREDITS_MODE_RATE :		case VBR_CREDITS_MODE_SIZE :			if(util_frametype(state) == FRAME_TYPE_STARTING_CREDITS)				bytes2 = (int)(bytes1 / state->credits_start_curve);			else				bytes2 = (int)(bytes1 / state->credits_end_curve);			break;		}	}	else {		/* Foxer: apply curve compression outside credits */		double dbytes, curve_temp;		bytes2 = bytes1;		if (state->pass1_intra)			dbytes = ((int)(bytes2 + bytes2 * state->keyframe_boost / 100)) /				state->movie_curve;		else			dbytes = bytes2 / state->movie_curve;		/* spread the compression error accross payback_delay frames */		if (state->bitrate_payback_method == VBR_PAYBACK_BIAS)	{			bytes2 = (int)(state->curve_comp_error / state->bitrate_payback_delay);		}		else {			bytes2 = (int)(state->curve_comp_error * dbytes /				state->average_frame / state->bitrate_payback_delay);			if (labs(bytes2) > fabs(state->curve_comp_error))				bytes2 = (int)state->curve_comp_error;		}		state->curve_comp_error -= bytes2;		if (state->use_alt_curve) {			if (!state->pass1_intra) {				if (dbytes > state->average_frame) {					if (dbytes >= state->alt_curve_high)						curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev);					else					{						curve_temp = vbr_getstuff(state,dbytes,state->alt_curve_high_diff);					}				}				else {					if (dbytes <= state->alt_curve_low)						curve_temp = dbytes;					else					{						curve_temp = vbr_getstuff(state,dbytes,state->alt_curve_low_diff);					}				}				curve_temp = curve_temp * state->curve_comp_scale + state->curve_bias_bonus;				bytes2 += ((int)curve_temp);				state->curve_comp_error += curve_temp - ((int)curve_temp);			}			else {				state->curve_comp_error += dbytes - ((int)dbytes);				bytes2 += ((int)dbytes);			}		}		else if ((state->curve_compression_high + state->curve_compression_low) &&			!state->pass1_intra) {			if (dbytes > state->average_frame) {				curve_temp = state->curve_comp_scale *					((double)dbytes + (state->average_frame - dbytes) *					state->curve_compression_high / 100.0);			}			else {				curve_temp = state->curve_comp_scale *					((double)dbytes + (state->average_frame - dbytes) *					state->curve_compression_low / 100.0);			}			bytes2 += ((int)curve_temp);			state->curve_comp_error += curve_temp - ((int)curve_temp);		}		else {			state->curve_comp_error += dbytes - ((int)dbytes);			bytes2 += ((int)dbytes);		}		/* cap bytes2 to first pass size, lowers number of quant=1 frames */		if (bytes2 > bytes1) {			state->curve_comp_error += bytes2 - bytes1;			bytes2 = bytes1;		}		else if (bytes2 < 1) {			state->curve_comp_error += --bytes2;			bytes2 = 1;		}	}	state->desired_bytes2 = bytes2;	/* Ugly dependance between getquant and getintra */	intra = state->getintra(state);	if(intra) {		KFdistance = state->keyframe_locations[state->KF_idx] -			state->keyframe_locations[state->KF_idx - 1];		if (KFdistance < state->kftreshold) {			KFdistance = KFdistance - state->min_key_interval;			if (KFdistance >= 0) {				KF_min_size = bytes2 * (100 - state->kfreduction) / 100;				if (KF_min_size < 1)					KF_min_size = 1;				bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance /					(state->kftreshold - state->min_key_interval);				if (bytes2 < 1)					bytes2 = 1;			}		}	}	/*	 * Foxer: scale overflow in relation to average size, so smaller frames don't get	 * too much/little bitrate	 */	overflow = (int)((double)overflow * bytes2 / state->average_frame);	/* Foxer: reign in overflow with huge frames */	if (labs(overflow) > labs(state->overflow)) {		overflow = state->overflow;	}	/* Foxer: make sure overflow doesn't run away */	if(overflow > bytes2 * state->twopass_max_overflow_improvement / 100) {		bytes2 += (overflow <= bytes2) ? bytes2 * state->twopass_max_overflow_improvement / 100 :			overflow * state->twopass_max_overflow_improvement / 100;	}	else if(overflow < bytes2 * state->twopass_max_overflow_degradation / -100) {		bytes2 += bytes2 * state->twopass_max_overflow_degradation / -100;	}	else {		bytes2 += overflow;	}	if(bytes2 > state->max_framesize) {		capped_to_max_framesize = 1;		bytes2 = state->max_framesize;	}	if(bytes2 < 1) {		bytes2 = 1;	}	state->bytes1 = bytes1;	state->bytes2 = bytes2;	/*printf("Pass 1 : %d \n",bytes1);	printf("Pass 2 : %d \n",bytes2);	printf("Quant1 : %d \n",state->pass1_quant);*/	/* very 'simple' quant<->filesize relationship */	quant = state->pass1_quant * bytes1 / bytes2;//	printf("Quant2 : %d \n",quant);	if(quant < 1)		quant = 1;	else if(quant > 31)		quant = 31;	else if(!state->pass1_intra) {		/* Foxer: aid desired quantizer precision by accumulating decision error */		state->quant_error[quant] += ((double)(state->pass1_quant * bytes1) / bytes2) - quant;		if (state->quant_error[quant] >= 1.0) {			state->quant_error[quant] -= 1.0;			quant++;		}	}	/* we're done with credits */	if(util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE) {		return(quant);	}	if(intra) {		if (quant < state->min_iquant)			quant = state->min_iquant;		if (quant > state->max_iquant)			quant = state->max_iquant;	}	else {		if(quant > state->max_pquant)			quant = state->max_pquant;		if(quant < state->min_pquant)			quant = state->min_pquant;		/* subsequent frame quants can only be +- 2 */		if(state->last_quant && capped_to_max_framesize == 0) {			if (quant > state->last_quant + 2)				quant = state->last_quant + 2;			if (quant < state->last_quant - 2)				quant = state->last_quant - 2;		}	}	// check that we are withing max Q	// meanX	state->underflow_warning=0;	for( i=0;i<state->roundup;i++)	{		if(i!=target)			sum+=state->b_per_sec[i];	}	// we make a rough estimation of the size this frame will be...	projected=state->size[state->cur_frame]*2/(state->qinc+quant);	sum+=projected;	state->avg_br=(sum*8)/1000;	//aprintf("avg_br: %d\n",state->avg_br);	if(state->maxAllowedBitrate)	{	if(state->cur_frame>15 && sum< state->thresh_underflow)	// If we are under THRESHOLD kbits we warn that we may reach underflow	{		state->underflow_warning=state->thresh_underflow-sum;		aprintf("Average bitrate underflow : bitrate lacks %d bytes\n",state->underflow_warning);	}	r=sum*10.;	r/=state->maxAllowedBitrate;	ratio=(int)floor(r);	if(ratio>9) ratio=9;	printf("Bitrate consumed : %d %%\n",ratio*10);	switch(ratio)	{		case 9: // between 90 and > 100 % bitrate used			aprintf("\n Max bitrate reached for frame %i \n",state->cur_frame );			aprintf(" Q %d Size : %d\n",quant, projected);			state->qinc+=LIMITER_MAX_INC;			if(state->qinc>20) state->qinc=20;   			aprintf("==> Qinc %d Size : %d\n",state->qinc, state->size[state->cur_frame]*2/(quant+state->qinc));			aprintf("==> %d versus max %d\n",sum,state->maxAllowedBitrate);			break;		case 8:				state->qinc=LIMITER_WARNING;				break;		case 7: // 70 % to				state->qinc=LIMITER_LOW_WARNING;				break;		default:				break;		}	// now we look ahead the 12 next frames assuming we will encode them	// with the same quantizer		if((state->qinc<2)&& (state->cur_frame < (state->nb_frames-13)))	{		int ahead[60];		int j,k,msum;		memcpy(ahead,state->b_per_sec,60*sizeof(int));		for(k=0;k<12;k++)		{			j=state->cur_frame+k;			ahead[ (j)% state->roundup]=(state->size[j]*2)/(state->qinc+quant);		}		msum=0;		for(k=0;k<state->roundup;k++)		{				msum+=ahead[k];		}		if(10*msum>9*state->maxAllowedBitrate)		{			// anticipating a future bitrate peak			aprintf("\n Frame %d : anticipating bitrate peak\n",state->cur_frame);			state->qinc=LIMITER_ANTICIPATING;			state->underflow_warning=0;		}	}	if(state->qinc)		{			quant+=state->qinc;			state->qinc--;			aprintf("Qinc: %d\n",state->qinc);			if(quant>31) quant=31;		}		// we now ponderate		if(quant>31) quant=31;		if(state->allow_quant_skew)		{			aprintf("Type %d , Initial quant : %d ---",state->type[state->cur_frame],quant);			switch(state->type[state->cur_frame])			{				case 3: // B break;					quant=quant_B_modifier[quant];					break;				case 1:case 2: // I & P				default:					assert(0);			}			aprintf("-> %d\n",quant);		}	} // maxAllowed	return(quant);}static int vbr_getintra_2pass2(void *sstate){	int intra=0;	vbr_control_t *state = sstate;	/* Get next intra state (fetched by update) */	intra = state->pass1_intra;	//printf("1st pass: %d \n",intra);	/* During credits, XviD will decide itself */	if(util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE) {		switch(state->credits_mode) {		default:		case VBR_CREDITS_MODE_RATE :		case VBR_CREDITS_MODE_SIZE :			intra = -1;			break;		case VBR_CREDITS_MODE_QUANT :			/* Except in this case */			if (state->credits_quant_i == state->credits_quant_p)				intra = -1;			break;		}	}	/* Force I Frame when max_key_interval is reached */	if((state->cur_frame - state->last_keyframe) > state->max_key_interval)	{	//	printf("Too far away -> intra cur : %d last : %d\n", 	//		state->cur_frame,state->last_keyframe);				intra = 1;	}	/*	 * Force P or B Frames for frames whose distance is less than the	 * requested minimum	 */	if((state->cur_frame - state->last_keyframe) < state->min_key_interval)	{		intra = 0;	}	//printf("cur : %d / last %d intra  : %d min: %d max: %d\n",state->cur_frame,state->last_keyframe,intra,	//		 state->min_key_interval, state->max_key_interval			);	/* Return the given intra mode except for first frame */	return((state->cur_frame==0)?1:intra);}static int vbr_update_2pass2(void *sstate,			     int quant,			     int intra,			     int header_bytes,			     int total_bytes,			     int kblocks,			     int mblocks,			     int ublocks){//	int next_hbytes, next_kblocks, next_mblocks, next_ublocks;	int tempdiv;	int target;	vbr_control_t *state = sstate;	header_bytes=total_bytes+kblocks+mblocks+ublocks; // MEAN: Remove warning	/*	 * We do not depend on getintra/quant because we have the real results	 * from the xvid core	 */	if (util_frametype(state) == FRAME_TYPE_NORMAL_MOVIE) {		state->quant_count[quant]++;		if (state->pass1_intra) {			state->overflow += state->KFoverflow;			state->KFoverflow = state->desired_bytes2 - total_bytes;			tempdiv = (state->keyframe_locations[state->KF_idx] -				   state->keyframe_locations[state->KF_idx - 1]);			/* redistribute correctly (by koepi) */			if (tempdiv > 1) {				/* non-consecutive keyframes */				state->KFoverflow_partial = state->KFoverflow /					(tempdiv - 1);			}			else {				state->overflow  += state->KFoverflow;				state->KFoverflow = 0;				state->KFoverflow_partial = 0;			}			state->KF_idx++;		}		else {			state->overflow += state->desired_bytes2 - total_bytes +				state->KFoverflow_partial;			state->KFoverflow -= state->KFoverflow_partial;		}	}	else {		state->overflow += state->desired_bytes2 - total_bytes;		state->overflow += state->KFoverflow;		state->KFoverflow = 0;		state->KFoverflow_partial = 0;	}	/* Save old quant */	state->last_quant = quant;	/* Save the last Keyframe pos */	if(intra)		state->last_keyframe = state->cur_frame;		target=state->cur_frame%state->roundup;		state->b_per_sec[target]=total_bytes;		if(ublocks!=state->type[state->cur_frame])		{				//aprintf("\n************************* GOP CHANGE******************\n");		}/* Ok next frame */		state->cur_frame++;		state->pass1_bytes=state->size[state->cur_frame];;		state->pass1_intra=state->kf[state->cur_frame];		state->pass1_quant=2;	return(0);}static int vbr_finish_2pass2(void *sstate){	vbr_control_t *state = sstate;	if(state->pass1_file == NULL)		return(-1);	/* Close the file */	if(fclose(state->pass1_file) != 0)		return(-1);	/* Free the memory */	if(state->keyframe_locations)		free(state->keyframe_locations);	{ // meanX		if(state->size)			{				free(state->size);				state->size=NULL;			}		if(state->kf)			{				free(state->kf);				state->kf=NULL;			}		if(state->type)			{				free(state->type);				state->type=NULL;			}	}	return(0);}/****************************************************************************** * Fixed quant mode - Most of the functions will be dummy functions *****************************************************************************/static int vbr_init_fixedquant(void *sstate){	vbr_control_t *state = sstate;	if(state->fixed_quant < 1)		state->fixed_quant = 1;	if(state->fixed_quant > 31)		state->fixed_quant = 31;	state->cur_frame = 0;	return(0);}static int vbr_getquant_fixedquant(void *sstate){	vbr_control_t *state = sstate;	/* Credits' frame ? */	if(util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE) {		int quant;		switch(state->credits_mode) {		case VBR_CREDITS_MODE_RATE:			quant = state->fixed_quant * state->credits_quant_ratio;			break;		case VBR_CREDITS_MODE_QUANT:			quant = state->credits_fixed_quant;			break;		default:			quant = state->fixed_quant;		}		return(quant);	}			/* No credit frame - return fixed quant */	return(state->fixed_quant);}/*	Return if next frame is intra*/int vbr_next_intra( void *sstate){	vbr_control_t *state = sstate;	if(state->cur_frame>state->nb_frames -2) return 0;	return state->kf[state->cur_frame+1];}static int vbr_getintra_fixedquant(void *state){	if(state)	{	}	return(-1);}