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

📄 xvid_vbr.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 3 页
字号:
				{					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);	}	/* 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 = sstate;	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 {						switch(state->alt_curve_type) {						case VBR_ALT_CURVE_AGGRESIVE:							curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *									       sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff)));							break;						default:						case VBR_ALT_CURVE_LINEAR:							curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *									       (dbytes - state->average_frame) / state->alt_curve_high_diff);							break;						case VBR_ALT_CURVE_SOFT:							curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *									       (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff))));						}					}				}				else {					if (dbytes <= state->alt_curve_low)						curve_temp = dbytes;					else {						switch(state->alt_curve_type) {						case VBR_ALT_CURVE_AGGRESIVE:							curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *									       sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_low_diff)));							break;						default:						case VBR_ALT_CURVE_LINEAR:							curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *									       (dbytes - state->average_frame) / state->alt_curve_low_diff);							break;						case VBR_ALT_CURVE_SOFT:							curve_temp = dbytes * (state->alt_curve_mid_qual + state->alt_curve_qual_dev *									       (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / 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;	/* very 'simple' quant<->filesize relationship */	quant = state->pass1_quant * bytes1 / bytes2;	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;		}	}	return(quant);}static int vbr_getintra_2pass2(void *sstate){	int intra;	vbr_control_t *state = sstate;		/* Get next intra state (fetched by update) */	intra = state->pass1_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)		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;	/* 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;	vbr_control_t *state = sstate;	/*	 * 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;	/* Update next frame data */	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);	/* Save the last Keyframe pos */	if(intra)		state->last_keyframe = state->cur_frame;	/* Ok next frame */	state->cur_frame++;	   	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);	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);}static int vbr_getintra_fixedquant(void *state){	return(-1);}

⌨️ 快捷键说明

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