[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