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

📄 plugin_2pass2.c

📁 TMS320C6713Xvid视频压缩算法源代码.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* 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;	}	rc->overflow += (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++;			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;

⌨️ 快捷键说明

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