[MPlayer-dev-eng] Re: OpenDML Read/Write support

Tobias Diedrich ranma at gmx.at
Mon Mar 22 16:41:13 CET 2004


Diego Biurrun wrote:

> NOTE: should be handled a bit differently in the man page so that it looks
> consistent.  Have a look at other NOTE: sections and just do copy + paste.

Fixed.
The attached patch also includes a -forceaviaspect option to be used
with -ovc copy.

-- 
Tobias						PGP: http://9ac7e0bc.2ya.com
Be vigilant!
-------------- next part --------------
? config
Index: cfg-mencoder.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mencoder.h,v
retrieving revision 1.81
diff -u -r1.81 cfg-mencoder.h
--- cfg-mencoder.h	22 Mar 2004 01:42:43 -0000	1.81
+++ cfg-mencoder.h	22 Mar 2004 15:37:39 -0000
@@ -160,6 +160,8 @@
 	{NULL, NULL, 0, 0, 0, 0, NULL}
 };
 
+extern float avi_aspect_override; /* defined in libmpdemux/muxer_avi.c */
+
 m_option_t mencoder_opts[]={
 	/* name, pointer, type, flags, min, max */
 
@@ -192,6 +194,9 @@
 	// override FOURCC in output file
 	{"ffourcc", &force_fourcc, CONF_TYPE_STRING, 0, 4, 4, NULL},
 
+	// override avi aspect autodetection
+	{"forceaviaspect", &avi_aspect_override, CONF_TYPE_FLOAT, CONF_RANGE, 0.2, 3.0, NULL},
+
 	{"pass", "The -pass option is obsolete. Use -lavcopts vpass=n or -divx4opts pass=n!\nRTFM!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 	{"passlogfile", &passtmpfile, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	
Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.237
diff -u -r1.237 mencoder.c
--- mencoder.c	17 Mar 2004 14:50:36 -0000	1.237
+++ mencoder.c	22 Mar 2004 15:37:40 -0000
@@ -663,12 +663,6 @@
 	mux_v->bih->biBitCount=24; // FIXME!!!
 	mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8);
     }
-    /*
-     * FIXME: with -ovc copy we don't get aspect ratio information
-     *        from the source stream.
-     */
-    if(movie_aspect>-1.0) sh_video->aspect = movie_aspect;
-
     printf("videocodec: framecopy (%dx%d %dbpp fourcc=%x)\n",
 	mux_v->bih->biWidth, mux_v->bih->biHeight,
 	mux_v->bih->biBitCount, mux_v->bih->biCompression);
Index: DOCS/man/en/mplayer.1
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/man/en/mplayer.1,v
retrieving revision 1.563
diff -u -r1.563 mplayer.1
--- DOCS/man/en/mplayer.1	22 Mar 2004 02:12:00 -0000	1.563
+++ DOCS/man/en/mplayer.1	22 Mar 2004 15:37:50 -0000
@@ -364,9 +364,11 @@
 Particularly useful on slow terminals or broken ones that do not properly
 handle carriage return (i.e. \\r).
 .TP
-.B \-useaviaspect
-With this option MPlayer and MEncoder will read and write the aspect
-setting from the OpenDML AVI Video Property Header.
+.B \-nouseaviaspect
+With this option MPlayer and MEncoder will
+.B not
+read and write the aspect setting from the OpenDML AVI Video Property
+Header.
 
 This is a different method than the "aspect=..." option of
 libavcodec or XviD, and is prioritized over it during playback,
@@ -377,10 +379,12 @@
 Some players can understand it, while they may not understand the
 aspect headers produced by the codec.
 
+See also \-forceaviaspect, \-vf dsize and \-lavcopts aspect.
+
 .I EXAMPLE:
 .PD 0
 .RSs
-.IPs "\-aspect 16:9 \-useaviaspect"
+.IPs "\-useaviaspect \-vf dsize=16/9"
 will add a header specifying 16:9 aspect ratio.
 .RE
 .PD 1
@@ -3795,6 +3799,10 @@
 .PD 1
 .
 .TP
+.B \-forceaviaspect <0.2\-3.0>
+Override the aspect stored in the AVI OpenDML vprp header.
+This can be used to change the aspect ratio with \-ovc copy.
+.TP
 .B \-info <option1:option2:...> (AVI only)
 Specify the info header of the resulting AVI file.
 .br
@@ -4360,6 +4368,13 @@
 Only MPlayer will play these files correctly, other players will display
 them with wrong aspect.
 The aspect parameter can be given as a ratio or a floating point number.
+.br
+.I NOTE:
+Unless you
+.B really
+know what you are doing, you should use \-vf dsize
+and \-lavcopts autoaspect instead, or the resulting file may contain
+inconsistent aspect ratio information.
 
 .RS
 .I EXAMPLE:
Index: libmpcodecs/vd.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vd.c,v
retrieving revision 1.75
diff -u -r1.75 vd.c
--- libmpcodecs/vd.c	23 Dec 2003 21:04:50 -0000	1.75
+++ libmpcodecs/vd.c	22 Mar 2004 15:37:55 -0000
@@ -307,6 +307,8 @@
                       fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3),
                       "MPlayer",out_fmt);
 
+    vf->d_width = screen_size_x;
+    vf->d_height = screen_size_y;
     if(vf->config(vf,sh->disp_w,sh->disp_h,
                       screen_size_x,screen_size_y,
                       fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3),
Index: libmpcodecs/ve_lavc.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ve_lavc.c,v
retrieving revision 1.92
diff -u -r1.92 ve_lavc.c
--- libmpcodecs/ve_lavc.c	7 Feb 2004 00:19:42 -0000	1.92
+++ libmpcodecs/ve_lavc.c	22 Mar 2004 15:37:56 -0000
@@ -501,6 +501,10 @@
     {
 	int par_width, par_height, e;
 	float ratio=0;
+
+	mp_msg(MSGT_MENCODER, MSGL_WARN,
+	       "!!! Using -lavcopts aspect is not recommended !!!\n"
+	       "Please use -vf dwidth and -lavcopts autoaspect instead.\n");
 	
 	e= sscanf (lavc_param_aspect, "%d/%d", &par_width, &par_height);
 	if(e==2){
Index: libmpcodecs/vf.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vf.c,v
retrieving revision 1.103
diff -u -r1.103 vf.c
--- libmpcodecs/vf.c	26 Feb 2004 14:41:42 -0000	1.103
+++ libmpcodecs/vf.c	22 Mar 2004 15:37:57 -0000
@@ -511,6 +511,8 @@
 	if(!vf2) return 0; // shouldn't happen!
 	vf->next=vf2;
     }
+    vf->next->d_width = d_width;
+    vf->next->d_height = d_height;
     return vf->next->config(vf->next,width,height,d_width,d_height,voflags,outfmt);
 }
 
Index: libmpcodecs/vf.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vf.h,v
retrieving revision 1.21
diff -u -r1.21 vf.h
--- libmpcodecs/vf.h	20 May 2003 17:42:33 -0000	1.21
+++ libmpcodecs/vf.h	22 Mar 2004 15:37:57 -0000
@@ -46,6 +46,7 @@
     struct vf_instance_s* next;
     mp_image_t *dmpi;
     struct vf_priv_s* priv;
+    int d_width, d_height;
 } vf_instance_t;
 
 // control codes:
Index: libmpdemux/aviheader.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/aviheader.c,v
retrieving revision 1.53
diff -u -r1.53 aviheader.c
--- libmpdemux/aviheader.c	22 Mar 2004 01:42:43 -0000	1.53
+++ libmpdemux/aviheader.c	22 Mar 2004 15:37:57 -0000
@@ -28,7 +28,7 @@
 extern void print_avistdindex_chunk(avistdindex_chunk *h);
 extern void print_avisuperindex_chunk(avisuperindex_chunk *h);
 
-int avi_use_vprp_aspect = 0;
+int avi_use_vprp_aspect = 1;
 
 static int odml_get_vstream_id(int id, unsigned char res[])
 {
Index: libmpdemux/muxer_avi.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/muxer_avi.c,v
retrieving revision 1.21
diff -u -r1.21 muxer_avi.c
--- libmpdemux/muxer_avi.c	22 Mar 2004 01:42:43 -0000	1.21
+++ libmpdemux/muxer_avi.c	22 Mar 2004 15:38:20 -0000
@@ -20,6 +20,8 @@
 #include "muxer.h"
 #include "aviheader.h"
 #include "mp_msg.h"
+#include "../libmpcodecs/mp_image.h"
+#include "../libmpcodecs/vf.h"
 
 extern char *info_name;
 extern char *info_artist;
@@ -35,6 +37,7 @@
 #define MOVIALIGN        0x00001000
 
 extern int avi_use_vprp_aspect;
+float avi_aspect_override = -1.0;
 
 struct avi_odmlidx_entry {
 	uint64_t ofs;
@@ -57,6 +60,63 @@
 	struct avi_odmlsuperidx_entry *superidx;
 };
 
+static void get_vf_aspect(vf_instance_t *vf, int *d_width, int *d_height)
+{
+    while (vf != NULL && vf->next != NULL) vf = vf->next;
+
+    if (vf == NULL) return;
+
+    *d_width = vf->d_width;
+    *d_height = vf->d_height;
+}
+
+static int gcd(int a, int b)
+{
+    int c = a;
+
+    if (a > b) return gcd(b, a);
+    if (a <= 0) return 1;
+
+    while (c != 0) {
+        a = b;
+        b = c;
+        c = a % b;
+    }
+    return b;
+}
+
+static unsigned int avi_aspect(sh_video_t *sh_video)
+{
+    int x;
+    int d_width = 0;
+    int d_height = 0;
+    float aspect = 0.0;
+
+    get_vf_aspect(sh_video->vfilter, &d_width, &d_height);
+
+    if (d_height > 0) aspect = (float)d_width / (float)d_height;
+
+    if (avi_aspect_override > 0.0) {
+        aspect = avi_aspect_override;
+	d_width = 16384;
+	d_height = (float)d_width / aspect;
+    }
+
+    while ((x = gcd(d_width, d_height)) > 1) {
+        d_width /= x;
+        d_height /= x;
+    }
+
+    if (aspect > 15.99/9.0 && aspect < 16.01/9.0) {
+        return MAKE_AVI_ASPECT(16, 9);
+    }
+    if (aspect > 3.99/3.0 && aspect < 4.01/3.0) {
+        return MAKE_AVI_ASPECT(4, 3);
+    }
+
+    return MAKE_AVI_ASPECT(d_width,d_height);
+}
+
 static muxer_stream_t* avifile_new_stream(muxer_t *muxer,int type){
     struct avi_stream_info *si;
     muxer_stream_t* s;
@@ -225,21 +285,6 @@
 
 #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(wf)->cbSize)
 
-static unsigned int avi_aspect(float aspect)
-{
-    if (aspect <= 0.0) {
-    	aspect = 4.0/3.0;
-    }
-    if (aspect >= 3.99/3.0 &&
-        aspect <= 4.01/3.0) return MAKE_AVI_ASPECT(4,3);
-    if (aspect >= 15.99/9.0 &&
-        aspect <= 16.01/9.0) return MAKE_AVI_ASPECT(16,9);
-    if (aspect >= 0.99 &&
-        aspect <= 1.01) return MAKE_AVI_ASPECT(1,1);
-    if (aspect<1.0) return MAKE_AVI_ASPECT((int)(aspect*8192),8192);
-    return MAKE_AVI_ASPECT(8192,(int)(8192/aspect));
-}
-
 static void avifile_write_header(muxer_t *muxer){
   uint32_t riff[3];
   unsigned int dmlh[1];
@@ -248,10 +293,18 @@
   muxer_info_t info[16];
   FILE *f = muxer->file;
   VideoPropHeader vprp;
-
+  uint32_t aspect = avi_aspect(muxer->def_v->source);
   off_t pos;
   int isodml = muxer->file_end > ODML_CHUNKLEN ? 1 : 0;
 
+  if (avi_use_vprp_aspect) {
+    if (aspect == 0) {
+      mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.\n");
+    } else {
+      mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: vprp aspect is %d:%d.\n", aspect >> 16, aspect & 0xffff);
+    }
+  }
+
   if (isodml) {
     for (pos = 0; pos < muxer->file_end; pos += ODML_CHUNKLEN) {
       unsigned int rifflen, movilen;
@@ -316,7 +369,7 @@
       switch(muxer->streams[i]->type){
       case MUXER_TYPE_VIDEO:
           hdrsize+=muxer->streams[i]->bih->biSize+8; // strf
-	  if (avi_use_vprp_aspect) {
+	  if (avi_use_vprp_aspect && aspect != 0) {
 	      hdrsize+=8+4*(9+8*1); // vprp
 	  }
 	  break;
@@ -351,14 +404,13 @@
           s->h.fccHandler = s->bih->biCompression;
           s->h.rcFrame.right = s->bih->biWidth;
           s->h.rcFrame.bottom = s->bih->biHeight;
-	  if (avi_use_vprp_aspect) {
-	      sh_video_t *sh_video = s->source;
+	  if (avi_use_vprp_aspect && aspect != 0) {
 	      // fill out vprp info
 	      memset(&vprp, 0, sizeof(vprp));
 	      vprp.dwVerticalRefreshRate = (s->h.dwRate+s->h.dwScale-1)/s->h.dwScale;
 	      vprp.dwHTotalInT = muxer->avih.dwWidth;
 	      vprp.dwVTotalInLines = muxer->avih.dwHeight;
-	      vprp.dwFrameAspectRatio = avi_aspect(sh_video->aspect);
+	      vprp.dwFrameAspectRatio = aspect;
 	      vprp.dwFrameWidthInPixels = muxer->avih.dwWidth;
 	      vprp.dwFrameHeightInLines = muxer->avih.dwHeight;
 	      vprp.nbFieldPerFrame = 1;
@@ -388,7 +440,7 @@
           write_avi_chunk(f,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */
           le2me_BITMAPINFOHEADER(s->bih);
 
-	  if (avi_use_vprp_aspect) {
+	  if (avi_use_vprp_aspect && aspect != 0) {
 	      int fields = vprp.nbFieldPerFrame;
 	      le2me_VideoPropHeader(&vprp);
 	      le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[0]);


More information about the MPlayer-dev-eng mailing list