diff -wurB MPlayer-20050121-clean/cfg-common.h MPlayer-20050121-csk/cfg-common.h
--- MPlayer-20050121-clean/cfg-common.h	2005-01-22 00:56:28.000000000 +0100
+++ MPlayer-20050121-csk/cfg-common.h	2005-01-22 02:50:17.000000000 +0100
@@ -262,6 +262,7 @@
 	{"spualign", &spu_alignment, CONF_TYPE_INT, CONF_RANGE, -1, 2, NULL},
 	{"spuaa", &spu_aamode, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
 	{"spugauss", &spu_gaussvar, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 3.0, NULL},
+        {"spu-scale", &spu_scale_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0.1, 4.0, NULL},
 #ifdef HAVE_FREETYPE
 	{"subfont-encoding", &subtitle_font_encoding, CONF_TYPE_STRING, 0, 0, 0, NULL},
  	{"subfont-text-scale", &text_font_scale_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0, 100, NULL},
diff -wurB MPlayer-20050121-clean/DOCS/man/en/mplayer.1 MPlayer-20050121-csk/DOCS/man/en/mplayer.1
--- MPlayer-20050121-clean/DOCS/man/en/mplayer.1	2005-01-22 00:56:28.000000000 +0100
+++ MPlayer-20050121-csk/DOCS/man/en/mplayer.1	2005-01-22 02:52:44.000000000 +0100
@@ -1453,6 +1453,10 @@
 .PD 1
 .
 .TP
+.B \-spu-scale <0.1\-4.0> (OSD only)
+Sets the DVD/\:VOBsub subtitle scaling coefficient relative to the original size (default: 1.0).
+Note: the subtitles are never resized wider than the width specifyed with -subwidth.
+.TP
 .B \-spualign <-1\-2> (OSD only)
 Specify how SPU (DVD/\:VOBsub) subtitles should be aligned.
 .PD 0
diff -wurB MPlayer-20050121-clean/libvo/sub.h MPlayer-20050121-csk/libvo/sub.h
--- MPlayer-20050121-clean/libvo/sub.h	2005-01-22 00:56:28.000000000 +0100
+++ MPlayer-20050121-csk/libvo/sub.h	2005-01-22 02:27:33.000000000 +0100
@@ -106,6 +106,7 @@
 extern int spu_alignment;
 extern int spu_aamode;
 extern float spu_gaussvar;
+extern float spu_scale_factor;
 
 //extern void vo_draw_text_osd(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 //extern void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
diff -wurB MPlayer-20050121-clean/spudec.c MPlayer-20050121-csk/spudec.c
--- MPlayer-20050121-clean/spudec.c	2005-01-22 02:41:53.000000000 +0100
+++ MPlayer-20050121-csk/spudec.c	2005-01-22 02:27:48.000000000 +0100
@@ -24,6 +24,7 @@
 #include "libvo/video_out.h"
 #include "spudec.h"
 #include "postproc/swscale.h"
+#include "libvo/sub.h"
 
 #define MIN(a, b)	((a)<(b)?(a):(b))
 
@@ -39,6 +40,7 @@
 int spu_alignment = -1;
 float spu_gaussvar = 1.0;
 extern int sub_pos;
+float spu_scale_factor = 1;
 
 typedef struct packet_t packet_t;
 struct packet_t {
@@ -640,15 +642,25 @@
   unsigned int scaled_start_row;
   unsigned int scaled_end_row;
   unsigned int scaled_sub_pos;
+  float scale_factor = spu_scale_factor;
   spu = (spudec_handle_t *)me;
-  if (spu->orig_frame_width != dxs || spu->orig_frame_height != dys) {
+  if (spu->orig_frame_width != dxs || spu->orig_frame_height != dys || spu_scale_factor != 1) {
     /* scaled_x = scalex * x / 0x100
        scaled_y = scaley * y / 0x100
        order of operations is important because of rounding. */
-    spu->scalex = 0x100 * dxs / spu->orig_frame_width;
-    spu->scaley = 0x100 * dys / spu->orig_frame_height;
-    spu->scaled_width = spu->width * spu->scalex / 0x100;
-    spu->scaled_height = spu->height * spu->scaley / 0x100;
+    unsigned int xlimit = dxs * sub_width_p / 100;
+    spu->scalex = 0x100 * dxs * scale_factor / spu->orig_frame_width;
+    spu->scaley = 0x100 * dys * scale_factor / spu->orig_frame_height;
+    if ((spu->scaled_width = spu->width * spu->scalex / 0x100) > xlimit) {
+      scale_factor = (float)(spu->scaled_width = xlimit) * spu->orig_frame_width / (spu->width * dxs);
+      spu->scalex = 0x100 * spu->scaled_width / spu->width;
+      spu->scaley = 0x100 * dys * scale_factor / spu->orig_frame_height;
+    }
+    if ((spu->scaled_height = spu->height * spu->scaley / 0x100) > dys) {
+      scale_factor = (float)(spu->scaled_height = dys) * spu->orig_frame_height / (spu->height * dys);
+      spu->scaley = 0x100 * spu->scaled_height / spu->height;
+      spu->scalex = 0x100 * dxs * scale_factor / spu->orig_frame_width;
+    }
     scaled_start_col = spu->start_col * spu->scalex / 0x100;
     scaled_start_row = spu->start_row * spu->scaley / 0x100;
   } else {
@@ -661,7 +673,7 @@
   }
   
   /* X position: */
-  scaled_start_col = scaled_start_col;
+  scaled_start_col = (spu->start_col + spu->width / 2) * dxs / spu->orig_frame_width - spu->scaled_width / 2;
   spu->scaled_start_col = spu_MIN(spu_MAX(scaled_start_col, 0), dxs - spu->scaled_width + 1);
   scaled_end_col = spu->scaled_start_col + spu->scaled_width - 1;
   
@@ -686,7 +698,7 @@
     scaled_end_row = spu->scaled_start_row + spu->scaled_height - 1;
       break;
     default: /* -1 */
-    scaled_start_row = scaled_start_row;
+    scaled_start_row = (spu->start_row + spu->height / 2) * dys / spu->orig_frame_height - spu->scaled_height / 2;
     spu->scaled_start_row = spu_MIN(spu_MAX(scaled_start_row, 0), dys - spu->scaled_height + 1);
     scaled_end_row = spu->scaled_start_row + spu->scaled_height - 1;
       break;
@@ -798,7 +810,7 @@
     }
 
       if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) {	/* Resizing is needed */
-      if (!(spu_aamode&16) && spu->orig_frame_width == dxs && spu->orig_frame_height == dys) {
+      if (!(spu_aamode&16) && spu->orig_frame_width == dxs && spu->orig_frame_height == dys && spu_scale_factor == 1) {
 	spu->scaled_image = spu->image;
 	spu->scaled_aimage = spu->aimage;
 	spu->scaled_stride = spu->stride;
