diff -wurB MPlayer-20050121-orig/mplayer.c MPlayer-20050121-clean/mplayer.c
--- MPlayer-20050121-orig/mplayer.c	2005-01-22 02:34:42.000000000 +0100
+++ MPlayer-20050121-clean/mplayer.c	2005-01-22 01:02:51.000000000 +0100
@@ -3314,6 +3314,7 @@
 	if(sub_pos >100) sub_pos=100;
 	if(sub_pos <0) sub_pos=0;
 	vo_osd_changed(OSDTYPE_SUBTITLE);
+	vo_osd_changed(OSDTYPE_SPU);
         osd_show_sub_pos = 9;
       }
 #endif
diff -wurB MPlayer-20050121-orig/spudec.c MPlayer-20050121-clean/spudec.c
--- MPlayer-20050121-orig/spudec.c	2005-01-08 22:06:04.000000000 +0100
+++ MPlayer-20050121-clean/spudec.c	2005-01-22 02:41:53.000000000 +0100
@@ -81,6 +81,7 @@
   unsigned char *aimage;	/* Alpha value */
   unsigned int scaled_frame_width, scaled_frame_height;
   unsigned int scaled_start_col, scaled_start_row;
+  unsigned int scalex, scaley;
   unsigned int scaled_width, scaled_height, scaled_stride;
   size_t scaled_image_size;
   unsigned char *scaled_image;
@@ -628,52 +629,75 @@
     }
 }
 
+static inline int spu_MAX(int A, int B) { return ((A)>(B))?(A):(B); }
+static inline int spu_MIN(int A, int B) { return ((A)<(B))?(A):(B); }
 /* calc the bbox for spudec subs */
 void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox)
 {
   spudec_handle_t *spu;
+  unsigned int scaled_start_col;
+  unsigned int scaled_end_col;
+  unsigned int scaled_start_row;
+  unsigned int scaled_end_row;
+  unsigned int scaled_sub_pos;
   spu = (spudec_handle_t *)me;
-  if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
-  || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) {
-    bbox[0] = spu->start_col;
-    bbox[1] = spu->start_col + spu->width;
-    bbox[2] = spu->start_row;
-    bbox[3] = spu->start_row + spu->height;
-  }
-  else if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) {
-    unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
-    unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
-    bbox[0] = spu->start_col * scalex / 0x100;
-    bbox[1] = spu->start_col * scalex / 0x100 + spu->width * scalex / 0x100;
+  if (spu->orig_frame_width != dxs || spu->orig_frame_height != dys) {
+    /* 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;
+    scaled_start_col = spu->start_col * spu->scalex / 0x100;
+    scaled_start_row = spu->start_row * spu->scaley / 0x100;
+  } else {
+    spu->scaled_width = spu->width;
+    spu->scaled_height = spu->height;
+    spu->scalex = 0x100;
+    spu->scaley = 0x100;
+    scaled_start_col = spu->start_col;
+    scaled_start_row = spu->start_row;
+  }
+  
+  /* X position: */
+  scaled_start_col = scaled_start_col;
+  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;
+  
+  /* Y position: */
+  scaled_sub_pos = dys * sub_pos / 100;
     switch (spu_alignment) {
     case 0:
-      bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x100;
-      if (bbox[3] > dys) bbox[3] = dys;
-      bbox[2] = bbox[3] - spu->height * scaley / 0x100;
+    scaled_end_row = spu_MIN(scaled_sub_pos + spu->scaled_height, dys);
+    spu->scaled_start_row = scaled_end_row - spu->scaled_height + 1;
       break;
     case 1:
       if (sub_pos < 50) {
-        bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x200;
-        if (bbox[2] < 0) bbox[2] = 0;
-        bbox[3] = bbox[2] + spu->height;
+      spu->scaled_start_row = spu_MAX(scaled_sub_pos - spu->scaled_height / 2, 0);
+      scaled_end_row = spu->scaled_start_row + spu->scaled_height - 1;
       } else {
-        bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x200;
-        if (bbox[3] > dys) bbox[3] = dys;
-        bbox[2] = bbox[3] - spu->height * scaley / 0x100;
+      scaled_end_row = spu_MIN(scaled_sub_pos + spu->scaled_height / 2, dys - 1);
+      spu->scaled_start_row = scaled_end_row - spu->scaled_height + 1;
       }
       break;
     case 2:
-      bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x100;
-      if (bbox[2] < 0) bbox[2] = 0;
-      bbox[3] = bbox[2] + spu->height;
+    spu->scaled_start_row = spu_MAX(scaled_sub_pos - spu->scaled_height, 0);
+    scaled_end_row = spu->scaled_start_row + spu->scaled_height - 1;
       break;
     default: /* -1 */
-      bbox[2] = spu->start_row * scaley / 0x100;
-      bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100;
+    scaled_start_row = scaled_start_row;
+    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;
     }
+  
+  bbox[0] = spu->scaled_start_col;
+  bbox[1] = scaled_end_col;
+  bbox[2] = spu->scaled_start_row;
+  bbox[3] = scaled_end_row;
   }
-}
+
 /* transform mplayer's alpha value into an opacity value that is linear */
 static inline int canon_alpha(int alpha)
 {
@@ -773,26 +797,14 @@
 	return;
     }
 
-    if (!(spu_aamode&16) && (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
-	|| (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
-      if (spu->image)
-      {
-	draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
-		   spu->image, spu->aimage, spu->stride);
-	spu->spu_changed = 0;
-      }
-    }
-    else {
       if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) {	/* Resizing is needed */
-	/* scaled_x = scalex * x / 0x100
-	   scaled_y = scaley * y / 0x100
-	   order of operations is important because of rounding. */
-	unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
-	unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
-	spu->scaled_start_col = spu->start_col * scalex / 0x100;
-	spu->scaled_start_row = spu->start_row * scaley / 0x100;
-	spu->scaled_width = spu->width * scalex / 0x100;
-	spu->scaled_height = spu->height * scaley / 0x100;
+      if (!(spu_aamode&16) && spu->orig_frame_width == dxs && spu->orig_frame_height == dys) {
+	spu->scaled_image = spu->image;
+	spu->scaled_aimage = spu->aimage;
+	spu->scaled_stride = spu->stride;
+	spu->scaled_frame_width = dxs;
+	spu->scaled_frame_height = dys;
+      } else {
 	/* Kludge: draw_alpha needs width multiple of 8 */
 	spu->scaled_stride = (spu->scaled_width + 7) & ~7;
 	if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) {
@@ -834,11 +846,11 @@
 	  case 0:
 	  /* no antialiasing */
 	  for (y = 0; y < spu->scaled_height; ++y) {
-	    int unscaled_y = y * 0x100 / scaley;
+	      int unscaled_y = y * 0x100 / spu->scaley;
 	    int strides = spu->stride * unscaled_y;
 	    int scaled_strides = spu->scaled_stride * y;
 	    for (x = 0; x < spu->scaled_width; ++x) {
-	      int unscaled_x = x * 0x100 / scalex;
+		int unscaled_x = x * 0x100 / spu->scalex;
 	      spu->scaled_image[scaled_strides + x] = spu->image[strides + unscaled_x];
 	      spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x];
 	    }
@@ -848,13 +860,14 @@
 	  {
 	    /* Intermediate antialiasing. */
 	    for (y = 0; y < spu->scaled_height; ++y) {
-	      const unsigned int unscaled_top = y * spu->orig_frame_height / dys;
-	      unsigned int unscaled_bottom = (y + 1) * spu->orig_frame_height / dys;
+		const unsigned int unscaled_top = y * 0x100 / spu->scaley;
+		unsigned int unscaled_bottom = (y + 1) * 0x100 / spu->scaley;
+
 	      if (unscaled_bottom >= spu->height)
 		unscaled_bottom = spu->height - 1;
 	      for (x = 0; x < spu->scaled_width; ++x) {
-		const unsigned int unscaled_left = x * spu->orig_frame_width / dxs;
-		unsigned int unscaled_right = (x + 1) * spu->orig_frame_width / dxs;
+		  const unsigned int unscaled_left = x * 0x100 / spu->scalex;
+		  unsigned int unscaled_right = (x + 1) * 0x100 / spu->scalex;
 		unsigned int color = 0;
 		unsigned int alpha = 0;
 		unsigned int walkx, walky;
@@ -924,8 +937,8 @@
 	       column between 2, 5, 8 and 3, 6, 9 is (unsigned
 	       int)unscaled_x_right.  The column right of 3, 6, 9 is
 	       unscaled_x_right. */
-	    const double inv_scalex = (double) 0x100 / scalex;
-	    const double inv_scaley = (double) 0x100 / scaley;
+	      const double inv_scalex = (double) 0x100 / spu->scalex;
+	      const double inv_scaley = (double) 0x100 / spu->scaley;
 	    for (y = 0; y < spu->scaled_height; ++y) {
 	      const double unscaled_y = y * inv_scaley;
 	      const double unscaled_y_bottom = unscaled_y + inv_scaley;
@@ -1041,7 +1054,7 @@
 		/* Finally mix these transparency and brightness information suitably */
 		base = spu->scaled_stride * y + x;
 		spu->scaled_image[base] = alpha > 0 ? color / alpha : 0;
-		spu->scaled_aimage[base] = alpha * scalex * scaley / 0x10000;
+		  spu->scaled_aimage[base] = alpha * spu->scalex * spu->scaley / 0x10000;
 		if (spu->scaled_aimage[base]) {
 		  spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base];
 		  if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255)
@@ -1062,33 +1075,11 @@
 	  spu->scaled_frame_height = dys;
 	}
       }
-      if (spu->scaled_image){
-        switch (spu_alignment) {
-        case 0:
-          spu->scaled_start_row = dys*sub_pos/100;
-	  if (spu->scaled_start_row + spu->scaled_height > dys)
-	    spu->scaled_start_row = dys - spu->scaled_height;
-	  break;
-	case 1:
-          spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height/2;
-          if (sub_pos < 50) {
-	    if (spu->scaled_start_row < 0) spu->scaled_start_row = 0;
-	  } else {
-	    if (spu->scaled_start_row + spu->scaled_height > dys)
-	      spu->scaled_start_row = dys - spu->scaled_height;
-	  }
-	  break;
-        case 2:
-          spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height;
-	  if (spu->scaled_start_row < 0) spu->scaled_start_row = 0;
-	  break;
 	}
 	draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
 		   spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
 	spu->spu_changed = 0;
       }
-    }
-  }
   else
   {
     mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPU not displayed: start_pts=%d  end_pts=%d  now_pts=%d\n",
@@ -1164,6 +1155,7 @@
       spudec_free_packet(spudec_dequeue_packet(spu));
     if (spu->packet)
       free(spu->packet);
+    if (spu->scaled_image == spu->image) spu->scaled_image = NULL;
     if (spu->scaled_image)
 	free(spu->scaled_image);
     if (spu->image)
