[Mplayer-cvslog] CVS: main cfg-common.h,1.80,1.81 spudec.c,1.37,1.38

Richard Felker CVS rfelker at mplayerhq.hu
Fri Jan 24 11:24:10 CET 2003


Update of /cvsroot/mplayer/main
In directory mail:/var/tmp.root/cvs-serv12561

Modified Files:
	cfg-common.h spudec.c 
Log Message:
Improvements to spudec (DVD/VobSub) subtitle code:
 - runtime selectable positioning, like with text subs
 - runtime selectable scaling/antialiasing algorithm
 - gaussian blur scaler (finally dvd/vobsub doesn't look like shit!)

Index: cfg-common.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-common.h,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- cfg-common.h	22 Jan 2003 23:50:46 -0000	1.80
+++ cfg-common.h	24 Jan 2003 10:24:07 -0000	1.81
@@ -192,6 +192,9 @@
  	{"subpos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
 	{"subalign", &sub_alignment, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
  	{"subwidth", &sub_width_p, CONF_TYPE_INT, CONF_RANGE, 10, 100, NULL},
+	{"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},
 #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},

Index: spudec.c
===================================================================
RCS file: /cvsroot/mplayer/main/spudec.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- spudec.c	8 Jan 2003 18:36:36 -0000	1.37
+++ spudec.c	24 Jan 2003 10:24:07 -0000	1.38
@@ -1,17 +1,3 @@
-/* Valid values for ANTIALIASING_ALGORITHM:
-  -1: bilinear (similiar to vobsub, fast and good quality)
-   0: none (fastest, most ugly)
-   1: approximate
-   2: full (slowest, best looking)
- */
-#define ANTIALIASING_ALGORITHM -1
-
-/* Valid values for SUBPOS:
-   0: leave the sub on it's original place
-   1: put the sub at the bottom of the picture
- */
-#define SUBPOS 0
-
 /* SPUdec.c
    Skeleton of function spudec_process_controll() is from xine sources.
    Further works:
@@ -34,14 +20,26 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#if ANTIALIASING_ALGORITHM == 2
 #include <math.h>
-#endif
 #include "libvo/video_out.h"
 #include "spudec.h"
+#include "postproc/swscale.h"
 
 #define MIN(a, b)	((a)<(b)?(a):(b))
 
+/* Valid values for spu_aamode:
+   0: none (fastest, most ugly)
+   1: approximate
+   2: full (slowest)
+   3: bilinear (similiar to vobsub, fast and not too bad)
+   4: uses swscaler gaussian (this is the only one that looks good)
+ */
+
+int spu_aamode = 3;
+int spu_alignment = -1;
+float spu_gaussvar = 1.0;
+extern int sub_pos;
+
 typedef struct packet_t packet_t;
 struct packet_t {
   unsigned char *data;
@@ -605,13 +603,33 @@
     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 SUBPOS == 0
-    bbox[2] = spu->start_row * scaley / 0x100;
-    bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100;
-#elif SUBPOS == 1
-    bbox[3] = dys -1;
-    bbox[2] = bbox[3] -spu->height * scaley / 0x100;
-#endif
+    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;
+      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;
+      } 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;
+      }
+      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;
+      break;
+    default: /* -1 */
+      bbox[2] = spu->start_row * scaley / 0x100;
+      bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100;
+      break;
+    }
   }
 }
 /* transform mplayer's alpha value into an opacity value that is linear */
@@ -627,7 +645,6 @@
 }scale_pixel;
 
 
-#if ANTIALIASING_ALGORITHM == -1
 static void scale_table(unsigned int start_src, unsigned int start_tar, unsigned int end_src, unsigned int end_tar, scale_pixel * table)
 {
   unsigned int t;
@@ -674,7 +691,32 @@
       spu->scaled_image[scaled] = 256 - spu->scaled_aimage[scaled];
   }
 }
-#endif
+
+void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, int ds,
+	unsigned char *s1, unsigned char *s2, int sw, int sh, int ss)
+{
+	SwsContext *ctx;
+	static SwsFilter filter;
+	static int firsttime = 1;
+	static float oldvar;
+	int i;
+
+	if (!firsttime && oldvar != spu_gaussvar) freeVec(filter.lumH);
+	if (firsttime) {
+		filter.lumH = filter.lumV =
+			filter.chrH = filter.chrV = getGaussianVec(spu_gaussvar, 3.0);
+		normalizeVec(filter.lumH, 1.0);
+		firsttime = 0;
+		oldvar = spu_gaussvar;
+	}
+	
+	ctx=getSwsContext(sw, sh, IMGFMT_Y800, dw, dh, IMGFMT_Y800, SWS_GAUSS, &filter, NULL);
+	ctx->swScale(ctx,&s1,&ss,0,sh,&d1,&ds);
+	for (i=ss*sh-1; i>=0; i--) if (!s2[i]) s2[i] = 255; //else s2[i] = 1;
+	ctx->swScale(ctx,&s2,&ss,0,sh,&d2,&ds);
+	for (i=ds*dh-1; i>=0; i--) if (d2[i]==0) d2[i] = 1; else if (d2[i]==255) d2[i] = 0;
+	freeSwsContext(ctx);
+}
 
 void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
 {
@@ -682,8 +724,8 @@
   scale_pixel *table_x;
   scale_pixel *table_y;
   if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts) {
-    if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
-	|| (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) {
+    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,
@@ -729,7 +771,13 @@
 	  if (spu->scaled_width <= 1 || spu->scaled_height <= 1) {
 	    goto nothing_to_do;
 	  }
-#if ANTIALIASING_ALGORITHM == -1
+	  switch(spu_aamode&15) {
+	  case 4:
+	  sws_spu_image(spu->scaled_image, spu->scaled_aimage,
+		  spu->scaled_width, spu->scaled_height, spu->scaled_stride,
+		  spu->image, spu->aimage, spu->width, spu->height, spu->stride);
+	  break;
+	  case 3:
 	  table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
 	  table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
 	  if (!table_x || !table_y) {
@@ -742,7 +790,8 @@
 	      scale_image(x, y, table_x, table_y, spu);
 	  free(table_x);
 	  free(table_y);
-#elif ANTIALIASING_ALGORITHM == 0
+	  break;
+	  case 0:
 	  /* no antialiasing */
 	  for (y = 0; y < spu->scaled_height; ++y) {
 	    int unscaled_y = y * 0x100 / scaley;
@@ -754,7 +803,8 @@
 	      spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x];
 	    }
 	  }
-#elif ANTIALIASING_ALGORITHM == 1
+	  break;
+	  case 1:
 	  {
 	    /* Intermediate antialiasing. */
 	    for (y = 0; y < spu->scaled_height; ++y) {
@@ -792,7 +842,8 @@
 	      }
 	    }
 	  }
-#else
+	  break;
+	  case 2:
 	  {
 	    /* Best antialiasing.  Very slow. */
 	    /* Any pixel (x, y) represents pixels from the original
@@ -959,17 +1010,33 @@
 	      }
 	    }
 	  }
-#endif
+	  }
 nothing_to_do:
 	  spu->scaled_frame_width = dxs;
 	  spu->scaled_frame_height = dys;
 	}
       }
       if (spu->scaled_image){
-#if SUBPOS == 1
-	/*set subs at the bottom, i don't like to put it at the very bottom, so -1 :)*/
-	spu->scaled_start_row = dys - spu->scaled_height - 1;
-#endif
+        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;



More information about the MPlayer-cvslog mailing list