[MPlayer-users] unicode subtitles
Georgi Georgiev
chutz at chubaka.homeip.net
Thu May 2 03:43:01 CEST 2002
First of all, congratulations on the good work. Don't know about all those people who have troubles with mplayer, but mplayer was the player that was easiest to compile and install.
I actually started this as a bug report, but I managed to solve the problem myself after hacking only a little bit in the source code, and I decided to share my experience with everyone who may find it useful.
My problem was in my inability to display subtitles that are using a double-byte encoding. At the end I figured that the problem of mplayer is:
1. TOOLS/subfont-c
The --unicode option to subfont creates a font.desc with the unicode indexes of the characters. However, in libvo/sub.c mplayer only checks if we are in unicode or utf8 mode after encountering a char >= 0x80. That is no problem if the subtitles are encoded with a double-byte encoding that was intended to be backward compatible with the standard ASCII (just about anything BUT unicode). This behavior is easily avoided by NOT using the --unicode switch when using subfont and creating a custom encoding beforehand.
2. .raw format
TOOLS/subfont-c/subfont.c and libvo/font_load.c write and read the width of the .raw image from two bytes in the header only. Two bytes are not enough if one creates a shift-jis (or euc-kr, which is supposed to work) font using subfont.c, because sometimes, the resulting .raw file can have a width of as much as 300,000 pixels (or even more).
3. TOOLS/font_load.h
typedef struct font_desc_t;
The member short start[65536] in particular overflows when the width of the .raw file is more than 65535.
I am attaching the small patch that can be applied against 0.90pre2. Here is what one needs to do after-wards to create a font for just about any language:
cd TOOLS/subfont-c
make
cd encodings
cat /usr/share/i18n/charmaps/[charmapname].gz | gunzip | ./charmap2enc > [charmapname]
cd ..
./subfont encodings/[charmapname] [fontsize] [fontname]
./subfont --append encodings/osd-mplayer [fontsize] osd/osd.pfb
cp font.desc *.raw ~/.mplayer/font
and then don't forget to use the -unicode switch to mplayer when playing.
It seems like the charmap files located in /usr/share/i18n/charmaps are specific for RedHat?? If someone lacks these, and or has trouble acquiring them - send me a mail.
Is int always 4 bytes on all systems?
--
Chutz <chutz at chubaka.homeip.net>
--------------------------------
"Have you lived here all your life?"
"Oh, twice that long."
-------------- next part --------------
--- MPlayer-0.90pre2-old/TOOLS/subfont-c/subfont.c Mon Mar 4 04:18:42 2002
+++ MPlayer-0.90pre2/TOOLS/subfont-c/subfont.c Thu May 2 09:11:42 2002
@@ -111,7 +111,15 @@
static unsigned char header[800] = "mhwanh";
int i;
header[7] = 4;
+ if (width < 0x10000) { // are two bytes enough for the width?
header[8] = width>>8; header[9] = (unsigned char)width;
+ } else { // store width using 4 bytes at the end of the header
+ header[8] = header[9] = 0;
+ header[28] = (width >> 030) & 0xFF;
+ header[29] = (width >> 020) & 0xFF;
+ header[30] = (width >> 010) & 0xFF;
+ header[31] = (width ) & 0xFF;
+ }
header[10] = height>>8; header[11] = (unsigned char)height;
header[12] = colors>>8; header[13] = (unsigned char)colors;
for (i = 32; i<800; ++i) header[i] = (i-32)/3;
--- MPlayer-0.90pre2-old/libvo/font_load.c Fri Oct 26 08:34:13 2001
+++ MPlayer-0.90pre2/libvo/font_load.c Thu May 2 09:13:40 2002
@@ -22,6 +22,8 @@
raw->w=head[8]*256+head[9];
raw->h=head[10]*256+head[11];
raw->c=head[12]*256+head[13];
+ if(raw->w == 0) // 2 bytes were not enough for the width... read 4 bytes from the end of the header
+ raw->w = ((head[28]*0x100 + head[29])*0x100 + head[30])*0x100 + head[31];
if(raw->c>256) return NULL; // too many colors!?
if(verbose) printf("RAW: %s %d x %d, %d colors\n",name,raw->w,raw->h,raw->c);
if(raw->c){
--- MPlayer-0.90pre2-old/libvo/font_load.h Sun Mar 24 09:32:13 2002
+++ MPlayer-0.90pre2/libvo/font_load.h Thu May 2 09:03:25 2002
@@ -16,7 +16,7 @@
raw_file* pic_a[16];
raw_file* pic_b[16];
short font[65536];
- short start[65536];
+ int start[65536]; // short is not enough for unicode fonts
short width[65536];
} font_desc_t;
More information about the MPlayer-users
mailing list