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

Steven M. Schultz sms at 2BSD.COM
Wed Jan 19 09:41:05 CET 2005


On Tue, 18 Jan 2005, Trent Piepho wrote:

> 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

	That's been a PITA for eons - getting F29969999:1000000 instead of
	30000/1001.

> 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'

	The scaled size isn't placed in the yuv4mpeg2 header so I think that's
	a different issue (when playing the movie on the computer for example)
	but you're right, the wrong thing is being done.

	The SAR (sample aspect ratio) placed in the yuv4mpeg2 header 
	should be 10:11 for "NTSC", and 59:54 for "PAL" (or 40:33 and 118:81
	for 16:9 movies in the two video systems).  Hmmm, but when you're
	decoding a SVCD the SAR is 15:11 and 59:36 respectively).  Does the
	yuv4mpeg module have sufficient knowledge to emit the correct 'A'
	tag?  If not then "0:0" is appropriate.

	On to the display scaling issue (which is separate from the yuv4mpeg
	output since the scaled sizes are not placed in the yuv4mpeg header).

	720/540 is a 4/3 display image using square pixels (which is what
	computer displays use) so that's correct.  Not sure how 528 was
	derived - how did you come up with 720x528 being a 4/3 display aspect?

	If you have a 704x480 DVD which is "legal" and is also the
	NTSC SD (standard definition) broadcast size using 10:11 pixels
	that is equivalent to 640x480 1:1 (computer) pixels.   What I find
	annoying is MPlayer's habit of scaling 704x480 to 704x528 instead
	of doing the 10:11 -> 1:1 pixel conversion by going to 640x480.  That's
	just as annoying as the 720x480 -> 720x540.

	So doing a 10:11 -> 1:1 pixel conversion of a 720x480 DVD should go to 
	654x480 instead of 720x540!!   Since when did NTSC become a 540 line
	video system (or a 528 line system for that matter)? :-)

	Increasing the number of vertical lines is done by interpolation
	isn't it and with interlaced material upscaling vertically is to
	be avoided.  A sight downsampling horizontally would be better for
	the quality (and the graphics card might even help out).

	Leave the vertical dimension alone would be A Real Good Thing.

	For PAL the conversion's the other way - pixels are 'fat'ter.  But
	that's left as an exercise for the reader ;)

	On the other hand HD (and perhaps DVB) broadcasts use 1:1 pixels so
	trying to guess at the 'A' tag to emit will be problematic.

	As long as there's an option to set the SAR that's fine - it'll
	save a step or two in the pipeline (mjpegtools has all the odds&ends 
	needed to deal with the 'F' and 'A' tag problems mentioned above) but
	that's all.

	Cheers,
	Steven Schultz
-------------- 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)
     {
-------------- next part --------------
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng at mplayerhq.hu
http://mplayerhq.hu/mailman/listinfo/mplayer-dev-eng


More information about the MPlayer-dev-eng mailing list