[MPlayer-dev-eng] enhancement for yuv4mpeg output driver

Trent Piepho xyzzy at speakeasy.org
Wed Jan 19 08:42:08 CET 2005


I've tried to fix a two problems I found with mplayer yuv4mpeg output.  I
hope posting them to this list is the right thing to do.

The YUV4MPEG2 output format specifies the frame rate as a fraction, such as
25/1.  It seems that mplayer exports the frame rate to the vo device via a
floating point value (right?).  The yuv4mpeg driver turns this into x/1000000,
e.g. 23.98 fps becomes 23975999/1000000.  The problem is that some of the
mjpegtools programs that deal with yuv4mpeg streams expect NTSC framerates to
be _exactly_ 24000/1001 and 30000/1001, not just some fraction that is almost
the same.  I just check for frames rates that are +=.00005 fps of 24000/1001
and 30000/1001 and output them as exactly that.

The YUV4MPEG2 format also specifies the _pixel_ aspect ratio.  The current
code just leaves this as 0:0, which means unknown.  I try to guess it by using
d_width and d_height vs width and height.  This doesn't always give the
correct result.  Sometimes it's because d_width and d_height are rounded to
integers, causing the aspect ratio to be slightly off.  Sometimes it's because
mplayer has the wrong idea of the pixel aspect isself, for example, a 720x480
4:3 NTSC DVD should be scaled to 720x528, not 720x540.  So I added an 'aspect'
option to the yuv4mpeg output device to allow the user to override the guessed
value.


-------------- next part --------------
Index: libvo/vo_yuv4mpeg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_yuv4mpeg.c,v
retrieving revision 1.20
diff -u -r1.20 vo_yuv4mpeg.c
--- libvo/vo_yuv4mpeg.c	31 Dec 2004 14:54:58 -0000	1.20
+++ libvo/vo_yuv4mpeg.c	19 Jan 2005 07:40:23 -0000
@@ -66,6 +66,8 @@
 
 static char *yuv_filename = NULL;
 
+static int asp_x = 0, asp_y = 0; /* pixel aspect ratio */
+
 static int using_format = 0;
 static FILE *yuv_out;
 static int write_bytes;
@@ -158,9 +160,20 @@
 	// or otherwise unusual (the "Ip A0:0" part).
 
 	/* At least the interlacing is ok now */
-	fprintf(yuv_out, "YUV4MPEG2 W%d H%d F%ld:%ld I%c A0:0\n", 
-			image_width, image_height, (long)(image_fps * 1000000.0), 
-			(long)1000000, config_interlace);
+	fprintf(yuv_out, "YUV4MPEG2 W%d H%d ", image_width, image_height);
+	if(image_fps>23.975973976 && image_fps<23.976073976) 
+		fprintf(yuv_out, "F24000:1001 ");
+	else if(image_fps>29.96997997 && image_fps<29.97007997) 
+		fprintf(yuv_out, "F30000:1001 ");
+	else 
+		fprintf(yuv_out, "F%ld:1000000 ", (long)(image_fps*1000000.0));
+
+	fprintf(yuv_out, "I%c ", config_interlace);
+
+	if(asp_x || asp_y)
+		fprintf(yuv_out, "A%d:%d\n", asp_x, asp_y);
+	else
+		fprintf(yuv_out, "A%u:%u\n", d_width*height, d_height*width);
 
 	fflush(yuv_out);
 	return 0;
@@ -493,20 +506,31 @@
 {
 }
 
+static int ratio_p(strarg_t *norm) {
+	int foo;
+	if(sscanf(norm->str, "%d/%d",&foo,&foo)!=2) {
+		mp_msg(MSGT_VO, MSGL_ERR,
+		       "vo_yuv4mpeg: aspect argument must be a ratio of the form xxx/yyy\n");
+		return 0;
+	} else return 1;
+}
+
 static uint32_t preinit(const char *arg)
 {
   int il, il_bf;
-  strarg_t file;
+  strarg_t file, aspect;
   opt_t subopts[] = {
     {"interlaced",    OPT_ARG_BOOL, &il,    NULL},
     {"interlaced_bf", OPT_ARG_BOOL, &il_bf, NULL},
     {"file",          OPT_ARG_STR,  &file,  NULL},
+    {"aspect",        OPT_ARG_STR,  &aspect, (opt_test_f)ratio_p},
     {NULL}
   };
 
   il = 0;
   il_bf = 0;
   file.len = 0;
+  aspect.len = 0;
   if (subopt_parse(arg, subopts) != 0) {
     mp_msg(MSGT_VO, MSGL_FATAL, MSGTR_VO_YUV4MPEG_UnknownSubDev, arg); 
     return -1;
@@ -524,6 +548,12 @@
     yuv_filename[file.len] = 0;
   }
 
+  if (aspect.len > 0) {
+    if(sscanf(aspect.str, "%d/%d", &asp_x, &asp_y)!=2) {
+      /* some kind of error understanding the argument */
+    }
+  }
+
     /* Inform user which output mode is used */
     switch (config_interlace)
     {


More information about the MPlayer-dev-eng mailing list