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

📄 plugin_2pass2.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (rc->param.vbv_size > 0)  {		const double fps = (double)create->fbase/(double)create->fincr;		int status = check_curve_for_vbv_compliancy(rc, fps);		if (status) {			DPRINTF(XVID_DEBUG_RC, "[xvid rc] Underflow detected - Scaling Curve for compliancy.\n");		}		status = scale_curve_for_vbv_compliancy(rc, fps);		if (status == 0) {			DPRINTF(XVID_DEBUG_RC, "[xvid rc] VBV compliant curve scaling done.\n");		} else {			DPRINTF(XVID_DEBUG_RC, "[xvid rc] VBV compliant curve scaling impossible.\n");		}	}	*handle = rc;	return(0);}/*---------------------------------------------------------------------------- *--------------------------------------------------------------------------*/static intrc_2pass2_destroy(rc_2pass2_t * rc, xvid_plg_destroy_t * destroy){	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- target_total:%lld desired_total:%.2f (%.2f%%) actual_total:%.2f (%.2f%%)\n",			rc->target,			rc->desired_total,			100*rc->desired_total/(double)rc->target,			rc->real_total,			100*rc->real_total/(double)rc->target);	free(rc->keyframe_locations);	free(rc->stats);	free(rc);	return(0);}/*---------------------------------------------------------------------------- *--------------------------------------------------------------------------*/static intrc_2pass2_before(rc_2pass2_t * rc, xvid_plg_data_t * data){	twopass_stat_t * s = &rc->stats[data->frame_num];	double dbytes;	double scaled_quant;	double overflow;	int capped_to_max_framesize = 0;	/* This function is quite long but easy to understand. In order to simplify	 * the code path (a bit), we treat 3 cases that can return immediatly. */	/* First case: Another plugin has already set a quantizer */	if (data->quant > 0)		return(0);	/* Second case: insufficent stats data	 * We can't guess much what we should do, let core decide all alone */	if (data->frame_num >= rc->num_frames) {		DPRINTF(XVID_DEBUG_RC,"[xvid rc] -- stats file too short (now processing frame %d)",			data->frame_num);		return(0);	}	/* Third case: We are in a Quant zone	 * Quant zones must just ensure we use the same settings as first pass	 * So set the quantizer and the type */	if (s->zone_mode == XVID_ZONE_QUANT) {		/* Quant stuff */		rc->fq_error += s->weight;		data->quant = (int)rc->fq_error;		rc->fq_error -= data->quant;		/* The type stuff */		data->type = s->type;		/* The only required data for AFTER step is this one for the overflow		 * control */		s->desired_length = s->length;		return(0);	}	/*************************************************************************/	/*************************************************************************/	/*************************************************************************/	/*-------------------------------------------------------------------------	 * Frame bit allocation first part	 *	 * First steps apply user settings, just like it is done in the theoritical	 * scaled_curve_apply_advanced_parameters	 *-----------------------------------------------------------------------*/	/* Set desired to what we are wanting to obtain for this frame */	dbytes = (double)s->scaled_length;	/* IFrame user settings*/	if (s->type == XVID_TYPE_IVOP) {		/* Keyframe boosting -- All keyframes benefit from it */		dbytes += dbytes*rc->param.keyframe_boost / 100;#if 0 /* ToDo: decide how to apply kfthresholding */#endif	} else {		/* P/S/B frames must reserve some bits for iframe boosting */		dbytes *= rc->pb_iboost_tax_ratio;		/* Apply assymetric curve compression */		if (rc->param.curve_compression_high || rc->param.curve_compression_low) {			double assymetric_delta;			/* Compute the assymetric delta, this is computed before applying			 * the tax, as done in the pre_process function */			if (dbytes > rc->avg_length[s->type-1])				assymetric_delta = (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_high / 100.0;			else				assymetric_delta = (rc->avg_length[s->type-1] - dbytes) * rc->param.curve_compression_low  / 100.0;			/* Now we must apply the assymetric tax, else our curve compression			 * would not give a theoritical target size equal to what it is			 * expected */			dbytes *= rc->assymetric_tax_ratio;			/* Now we can add the assymetric delta */			dbytes += assymetric_delta;		}	}	/* That is what we would like to have -- Don't put that chunk after	 * overflow control, otherwise, overflow is counted twice and you obtain	 * half sized bitrate sequences */	s->desired_length  = (int)dbytes;	rc->desired_total += dbytes;	/*------------------------------------------------------------------------	 * Frame bit allocation: overflow control part.	 *	 * Unlike the theoritical scaled_curve_apply_advanced_parameters, here	 * it's real encoding and we need to make sure we don't go so far from	 * what is our ideal scaled curve.	 *-----------------------------------------------------------------------*/	/* Compute the overflow we should compensate */	if (s->type != XVID_TYPE_IVOP || rc->overflow > 0) {		double frametype_factor;		double framesize_factor;		/* Take only the desired part of overflow */		overflow = rc->overflow;		/* Factor that will take care to decrease the overflow applied		 * according to the importance of this frame type in term of		 * overall size */		frametype_factor  = rc->count[XVID_TYPE_IVOP-1]*rc->avg_length[XVID_TYPE_IVOP-1];		frametype_factor += rc->count[XVID_TYPE_PVOP-1]*rc->avg_length[XVID_TYPE_PVOP-1];		frametype_factor += rc->count[XVID_TYPE_BVOP-1]*rc->avg_length[XVID_TYPE_BVOP-1];		frametype_factor /= rc->count[s->type-1]*rc->avg_length[s->type-1];		frametype_factor  = 1/frametype_factor;		/* Factor that will take care not to compensate too much for this frame		 * size */		framesize_factor  = dbytes;		framesize_factor /= rc->avg_length[s->type-1];		/* Treat only the overflow part concerned by this frame type and size */		overflow *= frametype_factor;#if 0		/* Leave this one alone, as it impacts badly on quality */		overflow *= framesize_factor;#endif		/* Apply the overflow strength imposed by the user */		overflow *= (rc->param.overflow_control_strength/100.0f);	} else {		/* no negative overflow applied in IFrames because:		 *  - their role is important as they're references for P/BFrames.		 *  - there aren't much in typical sequences, so if an IFrame overflows too		 *    much, this overflow may impact the next IFrame too much and generate		 *    a sequence of poor quality frames */		overflow = 0;	}	/* Make sure we are not trying to compensate more overflow than we even have */	if (fabs(overflow) > fabs(rc->overflow))		overflow = rc->overflow;	/* Make sure the overflow doesn't make the frame size to get out of the range	 * [-max_degradation..+max_improvment] */	if (overflow > dbytes*rc->param.max_overflow_improvement / 100) {		if(overflow <= dbytes)			dbytes += dbytes * rc->param.max_overflow_improvement / 100;		else			dbytes += overflow * rc->param.max_overflow_improvement / 100;	} else if (overflow < - dbytes * rc->param.max_overflow_degradation / 100) {		dbytes -= dbytes * rc->param.max_overflow_degradation / 100;	} else {		dbytes += overflow;	}	/*-------------------------------------------------------------------------	 * Frame bit allocation last part:	 *	 * Cap frame length so we don't reach neither bigger frame sizes than first	 * pass nor smaller than the allowed minimum.	 *-----------------------------------------------------------------------*/#ifdef PASS_SMALLER	if (dbytes > s->length) {		dbytes = s->length;	}#endif	/* Prevent stupid desired sizes under logical values */	if (dbytes < rc->min_length[s->type-1]) {		dbytes = rc->min_length[s->type-1];	}	/*------------------------------------------------------------------------	 * Desired frame length <-> quantizer mapping	 *-----------------------------------------------------------------------*/#ifdef BQUANT_PRESCALE	/* For bframes we prescale the quantizer to avoid too high quant scaling */	if(s->type == XVID_TYPE_BVOP) {		twopass_stat_t *b_ref = s;		/* Find the reference frame */		while(b_ref != &rc->stats[0] && b_ref->type == XVID_TYPE_BVOP)			b_ref--;		/* Compute the original quant */		s->quant  = 2*(100*s->quant - data->bquant_offset);		s->quant += data->bquant_ratio - 1; /* to avoid rounding issues */		s->quant  = s->quant/data->bquant_ratio - b_ref->quant;	}#endif	/* Don't laugh at this very 'simple' quant<->size relationship, it	 * proves to be acurate enough for our algorithm */	scaled_quant = (double)s->quant*(double)s->length/(double)dbytes;#ifdef COMPENSATE_FORMULA	/* We know xvidcore will apply the bframe formula again, so we compensate	 * it right now to make sure we would not apply it twice */	if(s->type == XVID_TYPE_BVOP) {		twopass_stat_t *b_ref = s;		/* Find the reference frame */		while(b_ref != &rc->stats[0] && b_ref->type == XVID_TYPE_BVOP)			b_ref--;		/* Compute the quant it would be if the core did not apply the bframe		 * formula */		scaled_quant  = 100*scaled_quant - data->bquant_offset;		scaled_quant += data->bquant_ratio - 1; /* to avoid rouding issues */		scaled_quant /= data->bquant_ratio;	}#endif	/* Quantizer has been scaled using floating point operations/results, we	 * must cast it to integer */	data->quant = (int)scaled_quant;	/* Let's clip the computed quantizer, if needed */	if (data->quant < 1) {		data->quant = 1;	} else if (data->quant > 31) {		data->quant = 31;	} else {		/* The frame quantizer has not been clipped, this appears to be a good		 * computed quantizer, do not loose quantizer decimal part that we		 * accumulate for later reuse when its sum represents a complete		 * unit. */		rc->quant_error[s->type-1][data->quant] += scaled_quant - (double)data->quant;		if (rc->quant_error[s->type-1][data->quant] >= 1.0) {			rc->quant_error[s->type-1][data->quant] -= 1.0;			data->quant++;		} else if (rc->quant_error[s->type-1][data->quant] <= -1.0) {			rc->quant_error[s->type-1][data->quant] += 1.0;			data->quant--;		}	}	/* Now we have a computed quant that is in the right quante range, with a	 * possible +1 correction due to cumulated error. We can now safely clip	 * the quantizer again with user's quant ranges. "Safely" means the Rate	 * Control could learn more about this quantizer, this knowledge is useful	 * for future frames even if it this quantizer won't be really used atm,	 * that's why we don't perform this clipping earlier. */	if (data->quant < data->min_quant[s->type-1]) {		data->quant = data->min_quant[s->type-1];	} else if (data->quant > data->max_quant[s->type-1]) {		data->quant = data->max_quant[s->type-1];	}	if (data->quant < rc->min_quant) data->quant = rc->min_quant;	/* To avoid big quality jumps from frame to frame, we apply a "security"	 * rule that makes |last_quant - new_quant| <= 2. This rule only applies	 * to predicted frames (P and B) */	if (s->type != XVID_TYPE_IVOP && rc->last_quant[s->type-1] && capped_to_max_framesize == 0) {		if (data->quant > rc->last_quant[s->type-1] + 2) {			data->quant = rc->last_quant[s->type-1] + 2;			DPRINTF(XVID_DEBUG_RC,					"[xvid rc] -- frame %d p/b-frame quantizer prevented from rising too steeply\n",					data->frame_num);		}		if (data->quant < rc->last_quant[s->type-1] - 2) {			data->quant = rc->last_quant[s->type-1] - 2;			DPRINTF(XVID_DEBUG_RC,					"[xvid rc] -- frame:%d p/b-frame quantizer prevented from falling too steeply\n",					data->frame_num);		}	}	/* We don't want to pollute the RC histerisis when our computed quant has	 * been computed from a capped frame size */	if (capped_to_max_framesize == 0)		rc->last_quant[s->type-1] = data->quant;	/* Don't forget to force 1st pass frame type ;-) */	data->type = s->type;	return 0;}/*---------------------------------------------------------------------------- *--------------------------------------------------------------------------*/static intrc_2pass2_after(rc_2pass2_t * rc, xvid_plg_data_t * data){	const char frame_type[4] = { 'i', 'p', 'b', 's'};	twopass_stat_t * s = &rc->stats[data->frame_num];	/* Insufficent stats data */	if (data->frame_num >= rc->num_frames)		return 0;	/* Update the quantizer counter */	rc->quant_count[s->type-1][data->quant]++;	/* Update the frame type overflow */	if (data->type == XVID_TYPE_IVOP) {		int kfdiff = 0;		if(rc->KF_idx != rc->num_frames -1) {			kfdiff  = rc->keyframe_locations[rc->KF_idx+1];			kfdiff -= rc->keyframe_locations[rc->KF_idx];		}		/* Flush Keyframe overflow accumulator */		rc->overflow += rc->KFoverflow;		/* Store the frame overflow to the keyframe accumulator */		rc->KFoverflow = s->desired_length - data->length;		if (kfdiff > 1) {			/* Non-consecutive keyframes case:			 * We can then divide this total keyframe overflow into equal parts			 * that we will distribute into regular overflow at each frame			 * between the sequence bounded by two IFrames */			rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1);		} else {			/* Consecutive keyframes case:			 * Flush immediatly the keyframe overflow and reset keyframe			 * overflow */			rc->overflow += rc->KFoverflow;			rc->KFoverflow = 0;			rc->KFoverflow_partial = 0;		}		rc->KF_idx++;	} else {		/* Accumulate the frame overflow */		rc->overflow += s->desired_length - data->length;		/* Distribute part of the keyframe overflow */		rc->overflow += rc->KFoverflow_partial;		/* Don't forget to substract that same amount from the total keyframe		 * overflow */		rc->KFoverflow -= rc->KFoverflow_partial;	}	s->error = s->desired_length - data->length;	rc->real_total += data->length;	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- frame:%d type:%c quant:%d stats:%d scaled:%d desired:%d actual:%d error:%d overflow:%.2f\n",			data->frame_num,			frame_type[data->type-1],			data->quant,			s->length,			s->scaled_length,			s->desired_length,			s->desired_length - s->error,			-s->error,			rc->overflow);	return(0);}/***************************************************************************** * Helper functions definition ****************************************************************************//* Default buffer size for reading lines */#define BUF_SZ   1024/* Helper functions for reading/parsing the stats file */static char *skipspaces(char *string);static int iscomment(char *string);static char *readline(FILE *f);/* This function counts the number of frame entries in the stats file * It also counts the number of I Frames */static intstatsfile_count_frames(rc_2pass2_t * rc, char * filename){	FILE * f;	char *line;	int lines;	rc->num_frames = 0;	rc->num_keyframes = 0;	if ((f = fopen(filename, "rb")) == NULL)		return(-1);	lines = 0;	while ((line = readline(f)) != NULL) {		char *ptr;		char type;		int fields;		lines++;		/* We skip spaces */		ptr = skipspaces(line);		/* Skip coment lines or empty lines */		if(iscomment(ptr) || *ptr == '\0') {			free(line);			continue;		}		/* Read the stat line from buffer */		fields = sscanf(ptr, "%c", &type);		/* Valid stats files have at least 7 fields */		if (fields == 1) {			switch(type) {			case 'i':			case 'I':				rc->num_keyframes++;

⌨️ 快捷键说明

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