[MPlayer-users] [Patch] Subtitles colors problem.

salvador salvador at inti.gov.ar
Thu Apr 25 21:04:02 CEST 2002


Hi All!

The patch is attached please tell me if this list preffers inline patches,
the patch is attached as text and isn't strangely encoded.
Purpose of this patch: Make fonts visible when reading an MPEG stream and no
VOB is available to get the palette.

Long explanation:
After talking with Felix Buenemann about it I looked into spudec.c and found
the problem. As Felix told me the palette isn't in the stream and is
different for each DVD/MPEG2 stream. But the problem is that mplayer uses an
"old black palette" (memory allocated with calloc => all 0) and this will
generate a bad palette all the time, black subtitles are impossible to read
in most movies.
The fact is that subtitles uses 4 colors from a palette of 16 colors. One of
this colors usually (I think that's all the time but, who knows?) is a
transparent color (achieved using the alpha channel). The other 3 colors are
used to get a border and an "inside" part (sorry, I'm not good for english
;-). In many cases only 2 colors are really used (one repeated or made
transparent with the alpha channel).
What I did is the following:

1) In spudec_new_scaled when palette is NULL I enable a flag indicating we
don't have a palette and we must generate the colors on the fly.
2) When we get the alpha information (in all the cases I tested it comes
after the colors, should we assume that's the case for all?) I added: if
(auto_palette) compute_palette(this); This function counts the used colors
and assigns different gray levels to these colors so we get a good contrast.

With this we get visible fonts. We have 50% of probability to get black
fonts with white around and 50% to get the reverse. In any case the
subtitles are ok.

As a plus I added a function  to pass the "font factor" (-ffactor) value to
this routine so we can choose to get a very big contrast or just white
fonts.

If this patch is accepted I want to also add:

1) The possibility to specify a palette from the command line.
2) Some alpha channel control so we can make the subtitles translucent (?)

I also discusse a related topic in another mail because I think subtitles
shouldn't be only black & white (a lot of DVDs uses yellow and mplayer is
ignoring it).

SET


--
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Visit my home page: http://welcome.to/SetSoft or
http://www.geocities.com/SiliconValley/Vista/6552/
Alternative e-mail: set at computer.org set at ieee.org
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013


-------------- next part --------------
? .tcedit.dst
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.482
diff -u -r1.482 mplayer.c
--- mplayer.c	25 Apr 2002 13:27:15 -0000	1.482
+++ mplayer.c	25 Apr 2002 18:43:42 -0000
@@ -1152,6 +1152,7 @@
 if (vo_spudec==NULL) {
   current_module="spudec_init_normal";
   vo_spudec=spudec_new_scaled(NULL, sh_video->disp_w, sh_video->disp_h);
+  spudec_set_font_factor(font_factor);
 }
 
 if (vo_spudec!=NULL)
Index: spudec.c
===================================================================
RCS file: /cvsroot/mplayer/main/spudec.c,v
retrieving revision 1.24
diff -u -r1.24 spudec.c
--- spudec.c	15 Apr 2002 19:17:12 -0000	1.24
+++ spudec.c	25 Apr 2002 18:43:42 -0000
@@ -63,6 +63,11 @@
   unsigned char *scaled_aimage;
 } spudec_handle_t;
 
+/* 1 if we lack a palette and must use an heuristic. */
+static int auto_palette = 0;
+/* Darkest value used for the computed font */
+static int font_start_level = 0;
+
 static inline unsigned int get_be16(const unsigned char *p)
 {
   return (p[0] << 8) + p[1];
@@ -184,6 +189,43 @@
   }
 }
 
+
+/*
+  This function tries to create a usable palette.
+  Is searchs how many non-transparent colors are used and assigns different
+gray scale values to each color.
+  I tested it with four streams and even got something readable. Half of the
+times I got black characters with white around and half the reverse.
+*/
+static void compute_palette(spudec_handle_t *this)
+{
+  int used[16],i,cused,start,step,color;
+
+  memset(used, 0, sizeof(used));
+  for (i=0; i<4; i++)
+    if (this->alpha[i]) /* !Transparent? */
+       used[this->palette[i]] = 1;
+  for (cused=0, i=0; i<16; i++)
+    if (used[i]) cused++;
+  if (!cused) return;
+  if (cused == 1) {
+    start = 0x80;
+    step = 0;
+  } else {
+    start = font_start_level;
+    step = (0xF0-font_start_level)/(cused-1);
+  }
+  memset(used, 0, sizeof(used));
+  for (i=0; i<4; i++) {
+    color = this->palette[i];
+    if (this->alpha[i] && !used[color]) { /* not assigned? */
+       used[color] = 1;
+       this->global_palette[color] = start<<16;
+       start += step;
+    }
+  }
+}
+
 static void spudec_process_control(spudec_handle_t *this, unsigned int pts100)
 {
   int a,b; /* Temporary vars */
@@ -237,6 +279,7 @@
 	this->alpha[1] = this->packet[off] & 0xf;
 	this->alpha[2] = this->packet[off + 1] >> 4;
 	this->alpha[3] = this->packet[off + 1] & 0xf;
+	if (auto_palette) compute_palette(this);
 	mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Alpha %d, %d, %d, %d\n",
 	       this->alpha[0], this->alpha[1], this->alpha[2], this->alpha[3]);
 	off+=2;
@@ -675,12 +718,23 @@
     memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
 }
 
+void spudec_set_font_factor(double factor)
+{
+  font_start_level = (int)(0xF0-(0xE0*factor));
+}
+
 void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height)
 {
   spudec_handle_t *this = calloc(1, sizeof(spudec_handle_t));
   if (this) {
-    if (palette)
+    if (palette) {
       memcpy(this->global_palette, palette, sizeof(this->global_palette));
+      auto_palette = 0;
+    }
+    else {
+      /* No palette, compute one */
+      auto_palette = 1;
+    }
     this->packet = NULL;
     this->image = NULL;
     this->scaled_image = NULL;
Index: spudec.h
===================================================================
RCS file: /cvsroot/mplayer/main/spudec.h,v
retrieving revision 1.10
diff -u -r1.10 spudec.h
--- spudec.h	15 Apr 2002 19:17:12 -0000	1.10
+++ spudec.h	25 Apr 2002 18:43:42 -0000
@@ -11,6 +11,7 @@
 void spudec_free(void *this);
 void spudec_reset(void *this);	// called after seek
 int spudec_visible(void *this); // check if spu is visible
+void spudec_set_font_factor(double factor); // sets the equivalent to ffactor
 
 #endif
 


More information about the MPlayer-users mailing list