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

Tobias Diedrich ranma at gmx.at
Mon Mar 22 15:23:18 CET 2004


I wrote:

> I'm going to grab something to eat now and write a patch after that.

And here it is.

It adds the proposed vf->d_width and vf->d_height fields, sets them in
vf.c and vd.c (vd.c for the first filter), adds a warning to ve_lavc.c
and the corresponding manpage paragraph, changes the muxer so that the
header is only written if we could grab d_width/d_height and makes it
enabled by default again.

Comments?

-- 
Tobias						PGP: http://9ac7e0bc.2ya.com
Be vigilant!
-------------- next part --------------
? config
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 14:13:30 -0000
@@ -4361,6 +4365,10 @@
 them with wrong aspect.
 The aspect parameter can be given as a ratio or a floating point number.
 
+Note:
+Unless you _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:
 .RE
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 14:13:31 -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 14:13:33 -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 14:13:34 -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 14:13:34 -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 14:13:37 -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 14:13:38 -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;
@@ -57,6 +59,57 @@
 	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);
+
+    while ((x = gcd(d_width, d_height)) > 1) {
+        d_width /= x;
+        d_height /= x;
+    }
+
+    if (d_height > 0) aspect = d_width / d_height;
+
+    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 +278,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 +286,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 +362,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 +397,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 +433,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