[Mplayer-cvslog] CVS: main/libmpcodecs ve_xvid4.c,1.8,1.9

Ivan Kalvachev CVS syncmail at mplayerhq.hu
Mon Oct 11 17:48:21 CEST 2004


CVS change done by Ivan Kalvachev CVS

Update of /cvsroot/mplayer/main/libmpcodecs
In directory mail:/var2/tmp/cvs-serv8231

Modified Files:
	ve_xvid4.c 
Log Message:
Sync with GomGom's patch-12 version.
  updated copyright
  bvhq options added (xvid 1.1+ api4.1)
  psnr handling moved in separate functions
  proper free() on uninit
  printf -> mp_msg
Changes by me (iive)
  support for flushing delayed frames at the end
  suppressed cosmetics and new aspect code changes


Index: ve_xvid4.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ve_xvid4.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ve_xvid4.c	13 Jul 2004 18:09:58 -0000	1.8
+++ ve_xvid4.c	11 Oct 2004 15:48:18 -0000	1.9
@@ -1,9 +1,9 @@
 /*****************************************************************************
  *
- *  - XviD 1.0 export module for mplayer/mencoder -
+ *  - XviD 1.x export module for mplayer/mencoder -
  *
- *  Copyright(C) 2003 Marco Belli <elcabesa at inwind.it>
- *               2003 Edouard Gomez <ed.gomez at free.fr>
+ *  Copyright(C) 2003      Marco Belli <elcabesa at inwind.it>
+ *               2003-2004 Edouard Gomez <ed.gomez at free.fr>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -63,7 +63,7 @@
 
 // Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation
 
-typedef struct XVIDRational{
+typedef struct xvid_rational_s{
     int num; 
     int den;
 } XVIDRational;
@@ -160,6 +160,7 @@
 static int xvidenc_chromame = 0;
 static int xvidenc_chroma_opt = 0;
 static int xvidenc_vhq = 0;
+static int xvidenc_bvhq = 0;
 static int xvidenc_motion = 6;
 static int xvidenc_turbo = 0;
 static int xvidenc_stats = 0;
@@ -213,6 +214,7 @@
 	{"chroma_me", &xvidenc_chromame, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 	{"chroma_opt", &xvidenc_chroma_opt, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 	{"vhq", &xvidenc_vhq, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL},
+	{"bvhq", &xvidenc_bvhq, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL},
 	{"max_bframes", &xvidenc_max_bframes, CONF_TYPE_INT, CONF_RANGE, 0, 20, NULL},
 	{"bquant_ratio", &xvidenc_bquant_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL},
 	{"bquant_offset", &xvidenc_bquant_offset, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL},
@@ -310,12 +312,20 @@
 	int max_framenum;
 	
 	int pixels;
-	int d_width, d_height;
+	
+	/* DAR/PAR and all that thingies */
+	int d_width;
+	int d_height;
+	FILE *fvstats;
 } xvid_mplayer_module_t;
 
 static void dispatch_settings(xvid_mplayer_module_t *mod);
 static int set_create_struct(xvid_mplayer_module_t *mod);
 static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi);
+static void update_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats);
+static void print_stats(xvid_mplayer_module_t *mod);
+static void flush_internal_buffers(xvid_mplayer_module_t *mod);
+static const char *par_string(int parcode);
 static const char *errorstring(int err);
 
 /*****************************************************************************
@@ -338,7 +348,7 @@
 	mod->mux->bih->biWidth = width;
 	mod->mux->bih->biHeight = height;
 	mod->mux->bih->biSizeImage = 
-		mod->mux->bih->biWidth * mod->mux->bih->biHeight * 3;
+		mod->mux->bih->biWidth * mod->mux->bih->biHeight * 3 / 2;
 	mod->mux->aspect = (float)d_width/d_height;
 
 	/* Message the FourCC type */
@@ -347,6 +357,9 @@
 	       width, height, mod->mux->bih->biCompression,
 	       (char *)&mod->mux->bih->biCompression);
 
+	/* Total number of pixels per frame required for PSNR */
+	mod->pixels = mod->mux->bih->biWidth*mod->mux->bih->biHeight;
+
 	/*--------------------------------------------------------------------
 	 * Dispatch all module settings to XviD structures
 	 *------------------------------------------------------------------*/
@@ -394,39 +407,27 @@
 	/* Destroy xvid instance */
 	xvid_encore(mod->instance, XVID_ENC_DESTROY, NULL, NULL);
 
-	/* Display stats */
-	if(mod->frames) {
-		mod->sse_y /= mod->frames;
-		mod->sse_u /= mod->frames;
-		mod->sse_v /= mod->frames;
+	/* Display stats (if any) */
+	print_stats(mod);
 
-#define SSE2PSNR(sse, nbpixels) \
-((!(sse)) ? 99.99f : 48.131f - 10*(double)log10((double)(sse)/(double)((nbpixels))))
-		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 dB, u : %.2f dB, v : %.2f dB, 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),
-		       mod->max_framenum);
-		mp_msg(MSGT_MENCODER, MSGL_INFO,
-		       "xvid: Average PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, for %d frames\n",
-		       SSE2PSNR(mod->sse_y, mod->pixels),
-		       SSE2PSNR(mod->sse_u, mod->pixels/4),
-		       SSE2PSNR(mod->sse_v, mod->pixels/4),
-		       mod->frames);
-		mp_msg(MSGT_MENCODER, MSGL_INFO,
-		       "xvid:     Max PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, 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),
-		       mod->min_framenum);
+	/* Close PSNR file if ever opened */
+	if (mod->fvstats) {
+		fclose(mod->fvstats);
+		mod->fvstats = NULL;
 	}
 
-	/* ToDo: free matrices, and some string settings (quant method, matrix
-	 * filenames...) */
+        /* Free allocated memory */
+	if(mod->frame.quant_intra_matrix)
+	    free(mod->frame.quant_intra_matrix);
+
+	if(mod->frame.quant_inter_matrix)
+	    free(mod->frame.quant_inter_matrix);
+
+	if(mod->mux->bih)
+	    free(mod->mux->bih);
+
+	free(vf->priv);
+	vf->priv=NULL;
 
 	return;
 }
@@ -438,6 +439,14 @@
 static int
 control(struct vf_instance_s* vf, int request, void* data)
 {
+xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv;
+
+	switch(request){
+	    case  VFCTRL_FLUSH_FRAMES:
+	    if(mod)/*paranoid*/
+                flush_internal_buffers(mod);
+	    break;
+	}
 	return(CONTROL_UNKNOWN);
 }
 
@@ -500,56 +509,9 @@
 	/* If size is == 0, we're done with that frame */
 	if(size == 0) return(FINE);
 
-	/* Did xvidcore returned stats about an encoded frame ? (asynchronous) */
-	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) {
-                    static FILE *fvstats = NULL;
-                    char filename[20];
-
-                    if (!fvstats) {
-                        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);
-                        fvstats = fopen (filename,"w");
-                        if (!fvstats) {
-                            perror ("fopen");
-                            xvidenc_psnr = 0; // disable block
-                        }
-                    }
-                    fprintf (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++;
-
-	}
-#undef SSE2PSNR
+	/* xvidcore returns stats about encoded frame in an asynchronous way
+	 * accumulate these stats */
+	update_stats(mod, &stats);
 
 	/* xvidcore outputed bitstream -- mux it */
 	muxer_write_chunk(mod->mux,
@@ -608,7 +570,7 @@
 	mod->mux->bih->biWidth = 0;
 	mod->mux->bih->biHeight = 0;
 	mod->mux->bih->biPlanes = 1;
-	mod->mux->bih->biBitCount = 24;
+	mod->mux->bih->biBitCount = 12;
 	mod->mux->bih->biCompression = mmioFOURCC('X','V','I','D');
 
 	/* Retrieve information about the host XviD library */
@@ -616,7 +578,7 @@
 	xvid_gbl_info.version = XVID_VERSION;
 
 	if (xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) {
-		mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: could not get information about the library\n");
+		mp_msg(MSGT_MENCODER,MSGL_WARN, "xvid: could not get information about the library\n");
 	} else {
 		mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n",
 		       XVID_VERSION_MAJOR(xvid_gbl_info.actual_version),
@@ -755,7 +717,7 @@
 	if(xvidenc_intra_matrix_file != NULL) {
 		frame->quant_intra_matrix = (unsigned char*)read_matrix(xvidenc_intra_matrix_file);
 		if(frame->quant_intra_matrix != NULL) {
-			fprintf(stderr, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n");
+			mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n");
 			if(xvidenc_quant_method) free(xvidenc_quant_method);
 			xvidenc_quant_method = strdup("mpeg");
 		}
@@ -763,7 +725,7 @@
 	if(xvidenc_inter_matrix_file != NULL) {
 		frame->quant_inter_matrix = read_matrix(xvidenc_inter_matrix_file);
 		if(frame->quant_inter_matrix) {
-			fprintf(stderr, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n");
+			mp_msg(MSGT_MENCODER, MSGL_INFO, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n");
 			if(xvidenc_quant_method) free(xvidenc_quant_method);
 			xvidenc_quant_method = strdup("mpeg");
 		}
@@ -814,6 +776,11 @@
 	if(xvidenc_vhq >= 4) {
 		frame->motion |= XVID_ME_EXTSEARCH_RD;
 	}
+	if(xvidenc_bvhq >= 1) {
+#if XVID_API >= XVID_MAKE_API(4,1)
+		frame->vop_flags |= XVID_VOP_RD_BVOP;
+#endif
+	}
 	if(xvidenc_turbo) {
 		frame->motion |= XVID_ME_FASTREFINE16;
 		frame->motion |= XVID_ME_FASTREFINE8;
@@ -857,9 +824,6 @@
 		    frame->par_height= ar.den;
 		}
 			
-		mp_msg(MSGT_MENCODER, MSGL_INFO, "XVID4_DAR: %d/%d code %d, Display frame: (%d, %d), original frame: (%d, %d)\n", 
-	    	    ar.num, ar.den, frame->par,
-		    mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight);
 	} else if(xvidenc_par != NULL) {
 		if(strcasecmp(xvidenc_par, "pal43") == 0)
 			frame->par = XVID_PAR_43_PAL;
@@ -884,6 +848,11 @@
 			frame->par_height = 1;
 	}
 	}
+
+	/* Display par information */
+	mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: par=%d/%d (%s), displayed=%dx%d, sampled=%dx%d\n", 
+			ar.num, ar.den, par_string(frame->par),
+			mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight);
 	return;
 }
 
@@ -900,9 +869,6 @@
 	create->width  = mod->mux->bih->biWidth;
 	create->height = mod->mux->bih->biHeight;
 
-	/* Pixels are needed for PSNR calculations */
-	mod->pixels = create->width * create->height;
-
 	/* FPS */
 	create->fincr = mod->mux->h.dwScale;
 	create->fbase = mod->mux->h.dwRate;
@@ -930,7 +896,7 @@
 	}
 
 	if(xvidenc_bitrate != 0 && xvidenc_pass == 1) {
-		mp_msg(MSGT_MENCODER, MSGL_ERR,
+		mp_msg(MSGT_MENCODER, MSGL_WARN,
 		       "xvid: bitrate setting is ignored during first pass\n");
 	}
 
@@ -1107,6 +1073,135 @@
 	return(FINE);
 }
 
+static void
+flush_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);
+		}
+	} while (size>0);
+}
+
+#define SSE2PSNR(sse, nbpixels) \
+		((!(sse)) ? 99.99f : 48.131f - 10*(double)log10((double)(sse)/(double)((nbpixels))))
+static void
+update_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 void
+print_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 dB, u : %.2f dB, v : %.2f dB, 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),
+				mod->max_framenum);
+		mp_msg(MSGT_MENCODER, MSGL_INFO,
+				"xvid: Average PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, for %d frames\n",
+				SSE2PSNR(mod->sse_y, mod->pixels),
+				SSE2PSNR(mod->sse_u, mod->pixels/4),
+				SSE2PSNR(mod->sse_v, mod->pixels/4),
+				mod->frames);
+		mp_msg(MSGT_MENCODER, MSGL_INFO,
+				"xvid:     Max PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, 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),
+				mod->min_framenum);
+	}
+}
+#undef SSE2PSNR
+
 static void *read_matrix(unsigned char *filename)
 {
 	int i;
@@ -1119,7 +1214,7 @@
 
 	/* Open the matrix file */
 	if((input = fopen(filename, "rb")) == NULL) {
-		fprintf(stderr,
+		mp_msg(MSGT_MENCODER, MSGL_ERR,
 			"xvid: Error opening the matrix file %s\n",
 			filename);
 		free(matrix);
@@ -1133,7 +1228,7 @@
 
 		/* If fscanf fails then get out of the loop */
 		if(fscanf(input, "%d", &value) != 1) {
-			fprintf(stderr,
+			mp_msg(MSGT_MENCODER, MSGL_ERR,
 				"xvid: Error reading the matrix file %s\n",
 				filename);
 			free(matrix);
@@ -1157,9 +1252,40 @@
 	
 }
 
+
+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)
 {
-	char *error;
+	const char *error;
 	switch(err) {
 	case XVID_ERR_FAIL:
 		error = "General fault";
@@ -1180,7 +1306,7 @@
 		error = "Unknown";
 	}
 
-	return((const char *)error);
+	return(error);
 }
 
 /*****************************************************************************




More information about the MPlayer-cvslog mailing list