aspect ratio in expand filter from MPlayer-1.0pre5
==================================================
by Rudo Thomas
You can always grab the latest version of the patch at http://rudo.matfyz.cz/ .
==
This patch adds another option (float "aspect") to the expand filter.
It is used when either both w and h are set to -1, or when one of them is -1
while the other one is less than -1. In other words, you can either leave the
computation on the filter, or specify to enlarge exactly one of the dimensions
by specified amount of pixels. The former setting ensures that the resulting
video has requested aspect ratio, the latter one does not. See below.
The easiest way to use the new feature is to specify the aspect ratio only:
Example 1:
mplayer -vf expand=aspect=1.25 foo.avi
This expands a 720x300 movie to 720x576. A 300x400 one would have been expanded
to 500x400.
Example 2:
mplayer -vf expand=w=-50:aspect=1.25 bar.avi
This adds 50 pixels to the movie width and calculates height for given aspect
ratio. A 450x300 file expands to 500x400. This usage may not yield requested
ratios, imagine movie sized 75x200. Resulting height would have to be 100, but
cropping the movie is not permitted.
Note that you can specify the aspect value as fraction (eg. 5/4).
Also note that you have to have monitor aspect ratio set correctly to
experience the full-screen effect I was targetting. As I have my desktop set at
1280x1024, I need to pass '-monitoraspect 1280/1024' arguments to MPlayer.
diff -urN -X /home/rudo/archiv/dontdiff-mplayer MPlayer-1.0pre5/libmpcodecs/vf_expand.c MPlayer-1.0pre5-modified/libmpcodecs/vf_expand.c
--- MPlayer-1.0pre5/libmpcodecs/vf_expand.c 2003-06-19 20:26:13.000000000 +0200
+++ MPlayer-1.0pre5-modified/libmpcodecs/vf_expand.c 2004-07-29 02:18:52.789251368 +0200
@@ -27,11 +27,13 @@
int exp_w,exp_h;
int exp_x,exp_y;
int osd;
+ float aspect;
unsigned char* fb_ptr;
} vf_priv_dflt = {
-1,-1,
-1,-1,
0,
+ 0.,
NULL
};
@@ -166,6 +168,63 @@
if(vf->priv->exp_wpriv->exp_w=width;
if(vf->priv->exp_hpriv->exp_h=height;
#else
+ if (vf->priv->aspect) {
+ /*
+ * Both h and w can be from 3 different ranges:
+ * - "negative": < -1
+ * - "default" : == -1
+ * - "positive": >= 0
+ * There are 6 different scenarios (the symmetric ones are counted as
+ * one):
+ * h\w - d +
+ * - A B D
+ * d B C E
+ * + D E F
+ * Only these scenarios make sense when aspect is specified:
+ * - B. one side is enlarged by specified amount, the other one is
+ * calculated
+ * - C. one of the sides is calculated (and enlarged)
+ * The other ones do not make sense with regard to the aspect setting:
+ * - A. enlarge both sides be fixed amount
+ * - D. one side is fixed length, the other one is enlarged by fixed
+ * amount
+ * - E. one side is fixed length
+ * if you want specific aspect ratio, fix length
+ * of the other side too (ie. use scenario F)
+ * - F. both sides are fixed length
+ *
+ * When one of the the non-sense scenarios are detected, the aspect
+ * setting is ignored.
+ *
+ * Note that C is guaranteed to give you requested results. B is not.
+ * Imagine a 100x100 movie and settings w=-50:aspect=2.
+ */
+ if (vf->priv->exp_w >= 0 || vf->priv->exp_h >= 0 ||
+ (vf->priv->exp_w < -1 && vf->priv->exp_h < -1)) {
+ mp_msg( MSGT_VFILTER, MSGL_INFO,
+ "Expand: aspect parameter is set but being ignored, given these w and h parameters.\n" );
+ }
+ else /* going to use aspect value; at most one of exp_w, exp_h is less than -1 */
+ if (vf->priv->exp_w < -1) {
+ vf->priv->exp_w = width - vf->priv->exp_w;
+ vf->priv->exp_h = (float)vf->priv->exp_w / vf->priv->aspect;
+ }
+ else if (vf->priv->exp_h < -1) {
+ vf->priv->exp_h = height - vf->priv->exp_h;
+ vf->priv->exp_w = (float)vf->priv->exp_h * vf->priv->aspect;
+ }
+ else /* exp_w == exp_h == -1 */
+ if (((float)width/(float)height) >= vf->priv->aspect) {
+ /* need to add height */
+ vf->priv->exp_w = width;
+ vf->priv->exp_h = (float)width / vf->priv->aspect;
+ } else {
+ /* need to add width */
+ vf->priv->exp_h = height;
+ vf->priv->exp_w = (float) height * vf->priv->aspect;
+ }
+ /* fall through, the code below checks for "underflows" */
+ }
if ( vf->priv->exp_w == -1 ) vf->priv->exp_w=width;
else if (vf->priv->exp_w < -1 ) vf->priv->exp_w=width - vf->priv->exp_w;
else if ( vf->priv->exp_wpriv->exp_w=width;
@@ -341,20 +400,24 @@
vf->priv->exp_w=
vf->priv->exp_h=-1;
vf->priv->osd=0;
+ vf->priv->aspect=0.;
// parse args ->
} // if(!vf->priv)
- if(args) sscanf(args, "%d:%d:%d:%d:%d",
+ if(args) sscanf(args, "%d:%d:%d:%d:%d:%f",
&vf->priv->exp_w,
&vf->priv->exp_h,
&vf->priv->exp_x,
&vf->priv->exp_y,
- &vf->priv->osd);
- mp_msg(MSGT_VFILTER, MSGL_INFO, "Expand: %d x %d, %d ; %d (-1=autodetect) osd: %d\n",
+ &vf->priv->osd,
+ &vf->priv->aspect);
+ mp_msg( MSGT_VFILTER, MSGL_INFO,
+ "Expand: %d x %d, %d ; %d (-1=autodetect) osd: %d aspect: %.4f\n",
vf->priv->exp_w,
vf->priv->exp_h,
vf->priv->exp_x,
vf->priv->exp_y,
- vf->priv->osd);
+ vf->priv->osd,
+ vf->priv->aspect);
return 1;
}
@@ -365,6 +428,7 @@
{"x", ST_OFF(exp_x), CONF_TYPE_INT, M_OPT_MIN, -1, 0, NULL},
{"y", ST_OFF(exp_y), CONF_TYPE_INT, M_OPT_MIN, -1, 0, NULL},
{"osd", ST_OFF(osd), CONF_TYPE_FLAG, 0 , 0, 1, NULL},
+ {"aspect", ST_OFF(aspect), CONF_TYPE_FLOAT, CONF_RANGE, 0.2, 3.0, NULL},
{ NULL, NULL, 0, 0, 0, 0, NULL }
};