[MPlayer-dev-eng] [Patch] Subtitles colors problem.
salvador
salvador at inti.gov.ar
Fri Apr 26 15:31:39 CEST 2002
Hi All!
This is a follow up for a thread I started in mplayer-users. I'm including
the description of the patch again.
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. Same for
the
new spudec_new_scaled_vobsub.
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 (?)
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 --------------
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 26 Apr 2002 13:30:30 -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.25
diff -u -r1.25 spudec.c
--- spudec.c 25 Apr 2002 18:46:44 -0000 1.25
+++ spudec.c 26 Apr 2002 13:30:31 -0000
@@ -65,6 +65,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];
@@ -191,6 +196,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 */
@@ -244,6 +286,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;
@@ -682,12 +725,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;
@@ -707,7 +761,10 @@
if (palette){
memcpy(this->global_palette, palette, sizeof(this->global_palette));
memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
+ auto_palette = 0;
}
+ else
+ auto_palette = 1;
//(fprintf(stderr,"VobSub Custom Palette: %d,%d,%d,%d", this->cuspal[0], this->cuspal[1], this->cuspal[2],this->cuspal[3]);
this->packet = NULL;
this->image = NULL;
@@ -715,6 +772,19 @@
this->orig_frame_width = frame_width;
this->orig_frame_height = frame_height;
this->custom = custom;
+ #if 0
+ /* SET: Shouldn't be like this? */
+ auto_palette = 1;
+ if (palette){
+ memcpy(this->global_palette, palette, sizeof(this->global_palette));
+ auto_palette = 0;
+ }
+ this->custom = custom;
+ if (custom) {
+ memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
+ auto_palette = 0;
+ }
+ #endif
}
else
perror("FATAL: spudec_init: calloc");
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 26 Apr 2002 13:30:33 -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-dev-eng
mailing list