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

📄 plugin_2pass2.c

📁 TMS320C6713Xvid视频压缩算法源代码.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
		rc->param.overflow_control_strength *= 3;	} else if (scaler > 0.6) {		rc->param.max_overflow_degradation *= 2;		rc->param.max_overflow_improvement *= 2;		rc->param.overflow_control_strength *= 2;	} else {		rc->min_quant = 2;	}#endif	/* Compute min frame lengths (for each frame type) according to the number	 * of MBs. We sum all block type counters of frame 0, this gives us the	 * number of MBs.	 *	 * We compare these hardcoded values with observed values in first pass	 * (determined in pre_process0).Then we keep the real minimum. */	/* Number of MBs */	num_MBs  = rc->stats[0].blks[0];	num_MBs += rc->stats[0].blks[1];	num_MBs += rc->stats[0].blks[2];	/* Minimum for I frames */	if(rc->min_length[XVID_TYPE_IVOP-1] > ((num_MBs*22) + 240) / 8)		rc->min_length[XVID_TYPE_IVOP-1] = ((num_MBs*22) + 240) / 8;	/* Minimum for P/S frames */	if(rc->min_length[XVID_TYPE_PVOP-1] > ((num_MBs) + 88)  / 8)		rc->min_length[XVID_TYPE_PVOP-1] = ((num_MBs) + 88)  / 8;	/* Minimum for B frames */	if(rc->min_length[XVID_TYPE_BVOP-1] > 8)		rc->min_length[XVID_TYPE_BVOP-1] = 8;	/* Perform an initial scale pass.	 *	 * If a frame size is scaled underneath our hardcoded minimums, then we	 * force the frame size to the minimum, and deduct the original & scaled	 * frame length from the original and target total lengths */	for (i=0; i<rc->num_frames; i++) {		twopass_stat_t * s = &rc->stats[i];		int len;		/* No need to scale frame length for which a specific quantizer is		 * specified thanks to zones */		if (s->zone_mode == XVID_ZONE_QUANT) {			s->scaled_length = s->length;			continue;		}		/* Compute the scaled length -- only non invariant data length is scaled */		len = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight);		/* Compare with the computed minimum */		if (len < rc->min_length[s->type-1]) {			/* This is a 'forced size' frame, set its frame size to the			 * computed minimum */			s->scaled_length = rc->min_length[s->type-1];			/* Remove both scaled and original size from their respective			 * total counters, as we prepare a second pass for 'regular'			 * frames */			target -= s->scaled_length;		} else {			/* Do nothing for now, we'll scale this later */			s->scaled_length = 0;		}	}	/* The first pass on data substracted all 'forced size' frames from the	 * total counters. Now, it's possible to scale the 'regular' frames. */	/* Scaling factor for 'regular' frames */	scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted);	/* Do another pass with the new scaler */	for (i=0; i<rc->num_frames; i++) {		twopass_stat_t * s = &rc->stats[i];		/* Ignore frame with forced frame sizes */		if (s->scaled_length == 0)			s->scaled_length = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight);	}	/* Job done */	return;}/* Apply all user settings to the scaled curve * This implies: *   keyframe boosting *   high/low compression */static voidscaled_curve_apply_advanced_parameters(rc_2pass2_t * rc){	int i;	int64_t ivop_boost_total;	/* Reset the rate controller (per frame type) total byte counters */	for (i=0; i<3; i++) rc->tot_scaled_length[i] = 0;	/* Compute total bytes for each frame type */	for (i=0; i<rc->num_frames;i++) {		twopass_stat_t *s = &rc->stats[i];		rc->tot_scaled_length[s->type-1] += s->scaled_length;	}	/* First we compute the total amount of bits needed, as being described by	 * the scaled distribution. During this pass over the complete stats data,	 * we see how much bits two user settings will get/give from/to p&b frames:	 *  - keyframe boosting	 *  - keyframe distance penalty */	rc->KF_idx = 0;	ivop_boost_total = 0;	for (i=0; i<rc->num_frames; i++) {		twopass_stat_t * s = &rc->stats[i];		/* Some more work is needed for I frames */		if (s->type == XVID_TYPE_IVOP) {			int ivop_boost;			/* Accumulate bytes needed for keyframe boosting */			ivop_boost = s->scaled_length*rc->param.keyframe_boost/100;#if 0 /* ToDo: decide how to apply kfthresholding */#endif			/* If the frame size drops under the minimum length, then cap ivop_boost */			if (ivop_boost + s->scaled_length < rc->min_length[XVID_TYPE_IVOP-1])				ivop_boost = rc->min_length[XVID_TYPE_IVOP-1] - s->scaled_length;			/* Accumulate the ivop boost */			ivop_boost_total += ivop_boost;			/* Don't forget to update the keyframe index */			rc->KF_idx++;		}	}	/* Initialize the IBoost tax ratio for P/S/B frames	 *	 * This ratio has to be applied to p/b/s frames in order to reserve	 * additional bits for keyframes (keyframe boosting) or if too much	 * keyframe distance is applied, bits retrieved from the keyframes.	 *	 * ie pb_length *= rc->pb_iboost_tax_ratio;	 *	 *    gives the ideal length of a p/b frame */	/* Compute the total length of p/b/s frames (temporary storage into	 * movie_curve) */	rc->pb_iboost_tax_ratio  = (double)rc->tot_scaled_length[XVID_TYPE_PVOP-1];	rc->pb_iboost_tax_ratio += (double)rc->tot_scaled_length[XVID_TYPE_BVOP-1];	/* Compute the ratio described above	 *     taxed_total = sum(0, n, tax*scaled_length)	 * <=> taxed_total = tax.sum(0, n, scaled_length)	 * <=> tax = taxed_total / original_total */	rc->pb_iboost_tax_ratio =		(rc->pb_iboost_tax_ratio - ivop_boost_total) /		rc->pb_iboost_tax_ratio;	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- IFrame boost tax ratio:%.2f\n",			rc->pb_iboost_tax_ratio);	/* Compute the average size of frames per frame type */	for(i=0; i<3; i++) {		/* Special case for missing type or weird case */		if (rc->count[i] == 0 || rc->pb_iboost_tax_ratio == 0) {			rc->avg_length[i] = 1;		} else {			rc->avg_length[i] = rc->tot_scaled_length[i];			if (i == (XVID_TYPE_IVOP-1)) {				/* I Frames total has to be added the boost total */				rc->avg_length[i] += ivop_boost_total;			} else {				/* P/B frames has to taxed */				rc->avg_length[i] *= rc->pb_iboost_tax_ratio;			}			/* Finally compute the average frame size */			rc->avg_length[i] /= (double)rc->count[i];		}	}	/* Assymetric curve compression */	if (rc->param.curve_compression_high || rc->param.curve_compression_low) {		double symetric_total;		double assymetric_delta_total;		/* Like I frame boosting, assymetric curve compression modifies the total		 * amount of needed bits, we must compute the ratio so we can prescale		 lengths */		symetric_total = 0;		assymetric_delta_total = 0;		for (i=0; i<rc->num_frames; i++) {			double assymetric_delta;			double dbytes;			twopass_stat_t * s = &rc->stats[i];			/* I Frames are not concerned by assymetric scaling */			if (s->type == XVID_TYPE_IVOP)				continue;			/* During the real run, we would have to apply the iboost tax */			dbytes = s->scaled_length * rc->pb_iboost_tax_ratio;			/* Update the symmetric curve compression total */			symetric_total += dbytes;			/* Apply assymetric curve compression */			if (dbytes > rc->avg_length[s->type-1])				assymetric_delta = (rc->avg_length[s->type-1] - dbytes) * (double)rc->param.curve_compression_high / 100.0f;			else				assymetric_delta = (rc->avg_length[s->type-1] - dbytes) * (double)rc->param.curve_compression_low  / 100.0f;			/* Cap to the minimum frame size if needed */			if (dbytes + assymetric_delta < rc->min_length[s->type-1])				assymetric_delta = rc->min_length[s->type-1] - dbytes;			/* Accumulate after assymetric curve compression */			assymetric_delta_total += assymetric_delta;		}		/* Compute the tax that all p/b frames have to pay in order to respect the		 * bit distribution changes that the assymetric compression curve imposes		 * We want assymetric_total = sum(0, n-1, tax.scaled_length)		 *      ie assymetric_total = ratio.sum(0, n-1, scaled_length)		 *         ratio = assymetric_total / symmetric_total */		rc->assymetric_tax_ratio = ((double)symetric_total - (double)assymetric_delta_total) / (double)symetric_total;	} else {		rc->assymetric_tax_ratio = 1.0f;	}	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Assymetric tax ratio:%.2f\n", rc->assymetric_tax_ratio);	/* Last bits that need to be reset */	rc->overflow = 0;	rc->KFoverflow = 0;	rc->KFoverflow_partial = 0;	rc->KF_idx = 0;	rc->desired_total = 0;	rc->real_total = 0;	/* Job done */	return;}/***************************************************************************** * Still more low level stuff (nothing to do with stats treatment) ****************************************************************************//* This function returns an allocated string containing a complete line read * from the file starting at the current position */static char *readline(FILE *f){	char *buffer = NULL;	int buffer_size = 0;	int pos = 0;	do {		int c;		/* Read a character from the stream */		c = fgetc(f);		/* Is that EOF or new line ? */		if(c == EOF || c == '\n')			break;		/* Do we have to update buffer ? */		if(pos >= buffer_size - 1) {			buffer_size += BUF_SZ;			buffer = (char*)realloc(buffer, buffer_size);			if (buffer == NULL)				return(NULL);		}		buffer[pos] = c;		pos++;	} while(1);	/* Read \n or EOF */	if (buffer == NULL) {		/* EOF, so we reached the end of the file, return NULL */		if(feof(f))			return(NULL);		/* Just an empty line with just a newline, allocate a 1 byte buffer to		 * store a zero length string */		buffer = (char*)malloc(1);		if(buffer == NULL)			return(NULL);	}	/* Zero terminated string */	buffer[pos] = '\0';	return(buffer);}/* This function returns a pointer to the first non space char in the given * string */static char *skipspaces(char *string){	const char spaces[] =		{			' ','\t','\0'		};	const char *spacechar = spaces;	if (string == NULL) return(NULL);	while (*string != '\0') {		/* Test against space chars */		while (*spacechar != '\0') {			if (*string == *spacechar) {				string++;				spacechar = spaces;				break;			}			spacechar++;		}		/* No space char */		if (*spacechar == '\0') return(string);	}	return(string);}/* This function returns a boolean that tells if the string is only a * comment */static intiscomment(char *string){	const char comments[] =		{			'#',';', '%', '\0'		};	const char *cmtchar = comments;	int iscomment = 0;	if (string == NULL) return(1);	string = skipspaces(string);	while(*cmtchar != '\0') {		if(*string == *cmtchar) {			iscomment = 1;			break;		}		cmtchar++;	}	return(iscomment);}#if 0static voidstats_print(rc_2pass2_t * rc){	int i;	const char frame_type[4] = { 'i', 'p', 'b', 's'};	for (i=0; i<rc->num_frames; i++) {		twopass_stat_t *s = &rc->stats[i];		DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- frame:%d type:%c quant:%d stats:%d scaled:%d desired:%d actual:%d overflow(%c):%.2f\n",				i, frame_type[s->type-1], -1, s->length, s->scaled_length,				s->desired_length, -1, frame_type[s->type-1], -1.0f);	}}#endif

⌨️ 快捷键说明

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