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

📄 plugin_2pass2.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
			case 'p':			case 'P':			case 'b':			case 'B':			case 's':			case 'S':				rc->num_frames++;				break;			default:				DPRINTF(XVID_DEBUG_RC,						"[xvid rc] -- WARNING: L%d unknown frame type used (%c).\n",						lines, type);			}		} else {				DPRINTF(XVID_DEBUG_RC,						"[xvid rc] -- WARNING: L%d misses some stat fields (%d).\n",						lines, 7-fields);		}		/* Free the line buffer */		free(line);	}	/* We are done with the file */	fclose(f);	return(0);}/* open stats file(s) and read into rc->stats array */static intstatsfile_load(rc_2pass2_t *rc, char * filename){	FILE * f;	int processed_entries;	/* Opens the file */	if ((f = fopen(filename, "rb"))==NULL)		return(-1);	processed_entries = 0;	while(processed_entries < rc->num_frames) {		char type;		int fields;		twopass_stat_t * s = &rc->stats[processed_entries];		char *line, *ptr;		/* Read the line from the file */		if((line = readline(f)) == NULL)			break;		/* We skip spaces */		ptr = skipspaces(line);		/* Skip comment lines or empty lines */		if(iscomment(ptr) || *ptr == '\0') {			free(line);			continue;		}		/* Reset this field that is optional */		s->scaled_length = 0;		/* Convert the fields */		fields = sscanf(ptr,						"%c %d %d %d %d %d %d %d\n",						&type,						&s->quant,						&s->blks[0], &s->blks[1], &s->blks[2],						&s->length, &s->invariant /* not really yet */,						&s->scaled_length);		/* Free line buffer, we don't need it anymore */		free(line);		/* Fail silently, this has probably been warned in		 * statsfile_count_frames */		if(fields != 7 && fields != 8)			continue;		/* Convert frame type and compute the invariant length part */		switch(type) {		case 'i':		case 'I':			s->type = XVID_TYPE_IVOP;			s->invariant /= INVARIANT_HEADER_PART_IVOP;			break;		case 'p':		case 'P':		case 's':		case 'S':			s->type = XVID_TYPE_PVOP;			s->invariant /= INVARIANT_HEADER_PART_PVOP;			break;		case 'b':		case 'B':			s->type = XVID_TYPE_BVOP;			s->invariant /= INVARIANT_HEADER_PART_BVOP;			break;		default:			/* Same as before, fail silently */			continue;		}		/* Ok it seems it's been processed correctly */		processed_entries++;	}	/* Close the file */	fclose(f);	return(0);}/* pre-process the statistics data * - for each type, count, tot_length, min_length, max_length * - set keyframes_locations, tot_prescaled */static voidfirst_pass_stats_prepare_data(rc_2pass2_t * rc){	int i,j;	/* *rc fields initialization	 * NB: INT_MAX and INT_MIN are used in order to be immediately replaced	 *     with real values of the 1pass */	for (i=0; i<3; i++) {		rc->count[i]=0;		rc->tot_length[i] = 0;		rc->tot_invariant[i] = 0;		rc->min_length[i] = INT_MAX;	}	rc->max_length = INT_MIN;	rc->tot_weighted = 0;	/* Loop through all frames and find/compute all the stuff this function	 * is supposed to do */	for (i=j=0; i<rc->num_frames; i++) {		twopass_stat_t * s = &rc->stats[i];		rc->count[s->type-1]++;		rc->tot_length[s->type-1] += s->length;		rc->tot_invariant[s->type-1] += s->invariant;		if (s->zone_mode != XVID_ZONE_QUANT)			rc->tot_weighted += (int)(s->weight*(s->length - s->invariant));		if (s->length < rc->min_length[s->type-1]) {			rc->min_length[s->type-1] = s->length;		}		if (s->length > rc->max_length) {			rc->max_length = s->length;		}		if (s->type == XVID_TYPE_IVOP) {			rc->keyframe_locations[j] = i;			j++;		}	}	/* NB:	 * The "per sequence" overflow system considers a natural sequence to be	 * formed by all frames between two iframes, so if we want to make sure	 * the system does not go nuts during last sequence, we force the last	 * frame to appear in the keyframe locations array. */	rc->keyframe_locations[j] = i;	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass IFrame length: %d\n", rc->min_length[0]);	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass PFrame length: %d\n", rc->min_length[1]);	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Min 1st pass BFrame length: %d\n", rc->min_length[2]);}/* calculate zone weight "center" */static voidzone_process(rc_2pass2_t *rc, const xvid_plg_create_t * create){	int i,j;	int n = 0;	rc->tot_quant = 0;	rc->tot_quant_invariant = 0;	if (create->num_zones == 0) {		for (j = 0; j < rc->num_frames; j++) {			rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;			rc->stats[j].weight = 1.0;		}		n += rc->num_frames;	}	for(i=0; i < create->num_zones; i++) {		int next = (i+1<create->num_zones) ? create->zones[i+1].frame : rc->num_frames;		/* Zero weight make no sense */		if (create->zones[i].increment == 0) create->zones[i].increment = 1;		/* And obviously an undetermined infinite makes even less sense */		if (create->zones[i].base == 0) create->zones[i].base = 1;		if (i==0 && create->zones[i].frame > 0) {			for (j = 0; j < create->zones[i].frame && j < rc->num_frames; j++) {				rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;				rc->stats[j].weight = 1.0;			}			n += create->zones[i].frame;		}		if (create->zones[i].mode == XVID_ZONE_WEIGHT) {			for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {				rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;				rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;			}			next -= create->zones[i].frame;			n += next;		} else{  /* XVID_ZONE_QUANT */			for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {				rc->stats[j].zone_mode = XVID_ZONE_QUANT;				rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;				rc->tot_quant += rc->stats[j].length;				rc->tot_quant_invariant += rc->stats[j].invariant;			}		}	}}/* scale the curve */static voidfirst_pass_scale_curve_internal(rc_2pass2_t *rc){	int64_t target;	int64_t total_invariant;	double scaler;	int i, num_MBs;	/* We only scale texture data ! */	total_invariant	 = rc->tot_invariant[XVID_TYPE_IVOP-1];	total_invariant += rc->tot_invariant[XVID_TYPE_PVOP-1];	total_invariant += rc->tot_invariant[XVID_TYPE_BVOP-1];	/* don't forget to substract header bytes used in quant zones, otherwise we	 * counting them twice */	total_invariant -= rc->tot_quant_invariant;	/* We remove the bytes used by the fixed quantizer zones during first pass	 * with the same quants, so we know very precisely how much that	 * represents */	target	= rc->target;	target -= rc->tot_quant;	/* Let's compute a linear scaler in order to perform curve scaling */	scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted);#ifdef SMART_OVERFLOW_SETTING	if (scaler > 0.9) {		rc->param.max_overflow_degradation *= 5;		rc->param.max_overflow_improvement *= 5;		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 */

⌨️ 快捷键说明

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