ve_xvid4.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,533 行 · 第 1/4 页

C
1,533
字号
			       "xvid: 2Pass Rate Control -- 2nd pass -- bitrate=%dkbit/s\n",			       xvidenc_bitrate>16000?xvidenc_bitrate/1000:xvidenc_bitrate);		} else {			pass2->bitrate  = xvidenc_bitrate;			mp_msg(MSGT_MENCODER, MSGL_INFO,			       "xvid: 2Pass Rate Control -- 2nd pass -- total size=%dkB\n",			       -xvidenc_bitrate);		}		create->plugins[create->num_plugins].func  = xvid_plugin_2pass2;		create->plugins[create->num_plugins].param = pass2;		create->num_plugins++;		doZones = 1;	}	if(xvidenc_luminance_masking && (selected_profile->flags & PROFILE_ADAPTQUANT)) {		create->plugins[create->num_plugins].func = xvid_plugin_lumimasking;		create->plugins[create->num_plugins].param = NULL;		create->num_plugins++;	}	// parse zones	if (xvidenc_zones != NULL && doZones > 0) // do not apply zones in CQ, and first pass mode (xvid vfw doesn't allow them in those modes either)	{		void *p;		int i;		p = xvidenc_zones;		create->num_zones = 0; // set the number of zones back to zero, this overwrites the zone defined for CQ - desired because each zone has to be specified on the commandline even in cq mode		for(i = 0; p; i++)		{        		int start;        		int q;			double value;			char mode;        		int e = sscanf(p, "%d,%c,%lf", &start, &mode, &value); // start,mode(q = constant quant, w = weight),value        		if(e != 3)			{	    			mp_msg(MSGT_MENCODER,MSGL_ERR, "error parsing zones\n");            		return(BAD);        		}			q = (int)(value * 100);			if (mode == 'q')			{				if (q < 200 || q > 3100) // make sure that quantizer is in allowable range				{					mp_msg(MSGT_MENCODER, MSGL_ERR, "zone quantizer must be between 2 and 31\n");					return(BAD);				}				else				{					create->zones[create->num_zones].mode      = XVID_ZONE_QUANT;				}			}			if (mode == 'w')			{				if (q < 1 || q > 200)				{					mp_msg(MSGT_MENCODER, MSGL_ERR, "zone weight must be between 1 and 200\n");					return(BAD);				}				else				{					create->zones[create->num_zones].mode      = XVID_ZONE_WEIGHT;				}			}			create->zones[create->num_zones].frame     = start;			create->zones[create->num_zones].increment = q;			create->zones[create->num_zones].base      = 100; // increment is 100 times the actual value			create->num_zones++;			if (create->num_zones > MAX_ZONES) // show warning if we have too many zones			{				mp_msg(MSGT_MENCODER, MSGL_ERR, "too many zones, zones will be ignored\n");			}        		p = strchr(p, '/');        		if(p) p++;    		}	}	return(FINE);}static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi){	xvid_enc_frame_t *frame = &mod->frame;	/* Most of the initialization is done during dispatch_settings */	frame->version = XVID_VERSION;	/* Bind output buffer */	frame->bitstream = mod->mux->buffer;	frame->length    = -1;	/* Frame format */	switch(mpi->imgfmt) {	case IMGFMT_YV12:	case IMGFMT_IYUV:	case IMGFMT_I420:		frame->input.csp = XVID_CSP_USER;		break;	case IMGFMT_YUY2:		frame->input.csp = XVID_CSP_YUY2;		break;	case IMGFMT_UYVY:		frame->input.csp = XVID_CSP_UYVY;		break;	default:		mp_msg(MSGT_MENCODER, MSGL_ERR,		       "xvid: unsupported picture format (%s)!\n",		       vo_format_name(mpi->imgfmt));		return(BAD);	}	/* Bind source frame */	frame->input.plane[0]  = mpi->planes[0];	frame->input.plane[1]  = mpi->planes[1];	frame->input.plane[2]  = mpi->planes[2];	frame->input.stride[0] = mpi->stride[0];	frame->input.stride[1] = mpi->stride[1];	frame->input.stride[2] = mpi->stride[2];	/* Force the right quantizer -- It is internally managed by RC	 * plugins */	frame->quant = 0;	return(FINE);}static voidflush_internal_buffers(xvid_mplayer_module_t *mod)		{	int size;	xvid_enc_frame_t *frame = &mod->frame;	if (mod->instance == NULL)	    return;/*encoder not inited*/	/* Init a fake frame to force flushing */	frame->version = XVID_VERSION;	frame->bitstream = mod->mux->buffer;	frame->length    = -1;	frame->input.csp = XVID_CSP_NULL;	frame->input.plane[0] = NULL;	frame->input.plane[1] = NULL;	frame->input.plane[2] = NULL;	frame->input.stride[0] = 0;	frame->input.stride[1] = 0;	frame->input.stride[2] = 0;	frame->quant = 0;	/* Flush encoder buffers caused by bframes usage */	do {		xvid_enc_stats_t stats;		memset(&stats, 0, sizeof(xvid_enc_stats_t));		stats.version = XVID_VERSION;		/* Encode internal buffer */		size = xvid_encore(mod->instance, XVID_ENC_ENCODE, &mod->frame, &stats);		if (size>0) {			/* Update stats */			update_stats(mod, &stats);			/* xvidcore outputed bitstream -- mux it */			muxer_write_chunk(mod->mux, size,					(mod->frame.out_flags & XVID_KEYFRAME)?0x10:0, MP_NOPTS_VALUE, MP_NOPTS_VALUE);		}	} while (size>0);}#define SSE2PSNR(sse, nbpixels) \		((!(sse)) ? 99.99f : 48.131f - 10*(double)log10((double)(sse)/(double)((nbpixels))))static voidupdate_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats){	if(xvidenc_stats && stats->type > 0) {		mod->sse_y += stats->sse_y;		mod->sse_u += stats->sse_u;		mod->sse_v += stats->sse_v;		if(mod->min_sse_y > stats->sse_y) {			mod->min_sse_y = stats->sse_y;			mod->min_sse_u = stats->sse_u;			mod->min_sse_v = stats->sse_v;			mod->min_framenum = mod->frames;		}		if(mod->max_sse_y < stats->sse_y) {			mod->max_sse_y = stats->sse_y;			mod->max_sse_u = stats->sse_u;			mod->max_sse_v = stats->sse_v;			mod->max_framenum = mod->frames;		}				if (xvidenc_psnr) {			if (!mod->fvstats) {				char filename[20];				time_t today2;				struct tm *today;				today2 = time (NULL);				today = localtime (&today2);				sprintf (filename, "psnr_%02d%02d%02d.log", today->tm_hour, today->tm_min, today->tm_sec);				mod->fvstats = fopen (filename,"w");				if (!mod->fvstats) {					perror ("fopen");					/* Disable PSNR file output so we don't get here again */					xvidenc_psnr = 0;				}			}			fprintf (mod->fvstats, "%6d, %2d, %6d, %2.2f, %2.2f, %2.2f, %2.2f %c\n",					mod->frames,					stats->quant,					stats->length,					SSE2PSNR (stats->sse_y, mod->pixels),					SSE2PSNR (stats->sse_u, mod->pixels / 4),					SSE2PSNR (stats->sse_v, mod->pixels / 4),					SSE2PSNR (stats->sse_y + stats->sse_u + stats->sse_v,(double)mod->pixels * 1.5),					stats->type==1?'I':stats->type==2?'P':stats->type==3?'B':stats->type?'S':'?'				);		}		mod->frames++;	}}static voidprint_stats(xvid_mplayer_module_t *mod){	if (mod->frames) {		mod->sse_y /= mod->frames;		mod->sse_u /= mod->frames;		mod->sse_v /= mod->frames;		mp_msg(MSGT_MENCODER, MSGL_INFO,				"The value 99.99dB is a special value and represents "				"the upper range limit\n");		mp_msg(MSGT_MENCODER, MSGL_INFO,				"xvid:     Min PSNR Y:%.2f, Cb:%.2f, Cr:%.2f, All:%.2f in frame %d\n",				SSE2PSNR(mod->max_sse_y, mod->pixels),				SSE2PSNR(mod->max_sse_u, mod->pixels/4),				SSE2PSNR(mod->max_sse_v, mod->pixels/4),				SSE2PSNR(mod->max_sse_y + mod->max_sse_u + mod->max_sse_v, mod->pixels*1.5),				mod->max_framenum);		mp_msg(MSGT_MENCODER, MSGL_INFO,				"xvid: Average PSNR Y:%.2f, Cb:%.2f, Cr:%.2f, All:%.2f for %d frames\n",				SSE2PSNR(mod->sse_y, mod->pixels),				SSE2PSNR(mod->sse_u, mod->pixels/4),				SSE2PSNR(mod->sse_v, mod->pixels/4),				SSE2PSNR(mod->sse_y + mod->sse_u + mod->sse_v, mod->pixels*1.5),				mod->frames);		mp_msg(MSGT_MENCODER, MSGL_INFO,				"xvid:     Max PSNR Y:%.2f, Cb:%.2f, Cr:%.2f, All:%.2f in frame %d\n",				SSE2PSNR(mod->min_sse_y, mod->pixels),				SSE2PSNR(mod->min_sse_u, mod->pixels/4),				SSE2PSNR(mod->min_sse_v, mod->pixels/4),				SSE2PSNR(mod->min_sse_y + mod->min_sse_u + mod->min_sse_v, mod->pixels*1.5),				mod->min_framenum);	}}#undef SSE2PSNRstatic void *read_matrix(unsigned char *filename){	int i;	unsigned char *matrix;	FILE *input;		/* Allocate matrix space */	if((matrix = malloc(64*sizeof(unsigned char))) == NULL)	   return(NULL);	/* Open the matrix file */	if((input = fopen(filename, "rb")) == NULL) {		mp_msg(MSGT_MENCODER, MSGL_ERR,			"xvid: Error opening the matrix file %s\n",			filename);		free(matrix);		return(NULL);	}	/* Read the matrix */	for(i=0; i<64; i++) {		int value;		/* If fscanf fails then get out of the loop */		if(fscanf(input, "%d", &value) != 1) {			mp_msg(MSGT_MENCODER, MSGL_ERR,				"xvid: Error reading the matrix file %s\n",				filename);			free(matrix);			fclose(input);			return(NULL);		}		/* Clamp the value to safe range */		value     = (value<  1)?1  :value;		value     = (value>255)?255:value;		matrix[i] = value;	}	/* Fills the rest with 1 */	while(i<64) matrix[i++] = 1;	/* We're done */	fclose(input);	return(matrix);	}static const char *par_string(int parcode){	const char *par_string;	switch (parcode) {	case XVID_PAR_11_VGA:		par_string = "vga11";		break;	case XVID_PAR_43_PAL:		par_string = "pal43";		break;	case XVID_PAR_43_NTSC:		par_string = "ntsc43";		break;	case XVID_PAR_169_PAL:		par_string = "pal169";		break;	case XVID_PAR_169_NTSC:		par_string = "ntsc69";		break;	case XVID_PAR_EXT:		par_string = "ext";		break;	default:		par_string = "unknown";		break;	}	return (par_string);}static const char *errorstring(int err){	const char *error;	switch(err) {	case XVID_ERR_FAIL:		error = "General fault";		break;	case XVID_ERR_MEMORY:		error =  "Memory allocation error";		break;	case XVID_ERR_FORMAT:		error =  "File format error";		break;	case XVID_ERR_VERSION:		error =  "Structure version not supported";		break;	case XVID_ERR_END:		error =  "End of stream reached";		break;	default:		error = "Unknown";	}	return(error);}/***************************************************************************** * Module structure definition ****************************************************************************/vf_info_t ve_info_xvid = {	"XviD 1.0 encoder",	"xvid",	"Marco Belli <elcabesa@inwind.it>, Edouard Gomez <ed.gomez@free.fr>",	"No comment",	vf_open};/* Please do not change that tag comment. * arch-tag: 42ccc257-0548-4a3e-9617-2876c4e8ac88 mplayer xvid encoder module */

⌨️ 快捷键说明

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