All: My shot at improving subtitle rendering in vlc. Now each vout uses a...

All: My shot at improving subtitle rendering in vlc. Now each vout uses a "text renderer" module to render text on the video when needed. I decieded to make this a module type, because other api's (win32 and macosx) is supposed to do better than freetype under some circumstances.

include/video_output.h: added some members needed by text renderer modules
src/video_output/video_output.c: load and unload text renderer module when needed
src/video_output/video_text.c: implemented some functions to show text on the video
include/osd.h: exported the functions to show text
modules/misc/Modules.am, module/misc/freetype.c: new text renderer module, largly based on the old osdtext module.
modules/video_filter/Modules.am, modules/video_filter/osd_text.c: removed the osdtext module
configure.ac: changes "osdtext" to "freetype" some places
modules/codec/spudec/*: when iconv is available, use it to convert textual subtitles from the encoding given by --sub-encoding to utf8. Use new code to render subtitles
modules/control/lirc/lirc.c: use new code to give feedback on buttons pressed. untested.
modules/demux/util/sub.c: remove all traces of the ugly old osdtext module
modules/misc/dummy/*: added a "text renderer" submodule in the dummy module
src/misc/modules.c: included osd.h as it seems to be needed to export symbols


final notes: you need to give a proper value to --freetype-font. This should be the path to a font file freetype2 can handle (almost any format afaik) with a unicode translation table in it. Windows ttf files will do. In linux at least openoffice distributes some fonts that work. I think macosx and beos also has useable fonts.
parent 371148d3
dnl Autoconf settings for vlc
dnl $Id: configure.ac,v 1.29 2003/07/14 16:10:20 gbazin Exp $
dnl $Id: configure.ac,v 1.30 2003/07/14 21:32:58 sigmunau Exp $
AC_INIT(vlc,0.6.0)
......@@ -2129,9 +2129,9 @@ then
if test "${FREETYPE_CONFIG}" != "no"
then
AX_ADD_PLUGINS([osdtext])
AX_ADD_CFLAGS([osdtext],[`${FREETYPE_CONFIG} --cflags`])
AX_ADD_LDFLAGS([osdtext],[`${FREETYPE_CONFIG} --libs`])
AX_ADD_PLUGINS([freetype])
AX_ADD_CFLAGS([freetype],[`${FREETYPE_CONFIG} --cflags`])
AX_ADD_LDFLAGS([freetype],[`${FREETYPE_CONFIG} --libs`])
CPPFLAGS="${CPPFLAGS_save} ${CFLAGS_freetype}"
elif test "${enable_freetype}" = "yes"
then
......
......@@ -2,7 +2,7 @@
* osd.h : Constants for use with osd modules
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: osd.h,v 1.1 2003/03/23 16:38:40 sigmunau Exp $
* $Id: osd.h,v 1.2 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
......@@ -25,3 +25,15 @@
#define OSD_ALIGN_RIGHT 0x1
#define OSD_ALIGN_TOP 0
#define OSD_ALIGN_BOTTOM 0x2
struct text_style_t
{
int i_size;
uint32_t i_color;
vlc_bool_t b_italic;
vlc_bool_t b_bold;
vlc_bool_t b_underline;
};
static const text_style_t default_text_style = { 22, 0xffffff, VLC_FALSE, VLC_FALSE, VLC_FALSE };
VLC_EXPORT( void, vout_ShowTextRelative, ( vout_thread_t *, char *, text_style_t *, int, int, int, mtime_t ) );
VLC_EXPORT( void, vout_ShowTextAbsolute, ( vout_thread_t *, char *, text_style_t *, int, int, int, mtime_t, mtime_t ) );
......@@ -5,7 +5,7 @@
* thread, and destroy a previously opened video output thread.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_output.h,v 1.95 2003/06/09 00:33:34 massiot Exp $
* $Id: video_output.h,v 1.96 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
......@@ -50,76 +50,91 @@ typedef struct vout_chroma_t
} vout_chroma_t;
/*****************************************************************************
* vout_thread_t: video output thread descriptor
*****************************************************************************
/**
* \brief video output thread descriptor
*
* Any independant video output device, such as an X11 window or a GGI device,
* is represented by a video output thread, and described using the following
* structure.
*****************************************************************************/
*/
struct vout_thread_t
{
VLC_COMMON_MEMBERS
/* Thread properties and lock */
vlc_mutex_t picture_lock; /* picture heap lock */
vlc_mutex_t subpicture_lock; /* subpicture heap lock */
vlc_mutex_t change_lock; /* thread change lock */
vout_sys_t * p_sys; /* system output method */
/* Current display properties */
uint16_t i_changes; /* changes made to the thread */
float f_gamma; /* gamma */
vlc_bool_t b_grayscale; /* color or grayscale display */
vlc_bool_t b_info; /* print additional information */
vlc_bool_t b_interface; /* render interface */
vlc_bool_t b_scale; /* allow picture scaling */
vlc_bool_t b_fullscreen; /* toogle fullscreen display */
vlc_bool_t b_override_aspect; /* aspect ratio overriden */
mtime_t render_time; /* last picture render time */
unsigned int i_window_width; /* video window width */
unsigned int i_window_height; /* video window height */
/* Plugin used and shortcuts to access its capabilities */
/** \name Thread properties and locks */
/**@{*/
vlc_mutex_t picture_lock; /**< picture heap lock */
vlc_mutex_t subpicture_lock; /**< subpicture heap lock */
vlc_mutex_t change_lock; /**< thread change lock */
vout_sys_t * p_sys; /**< system output method */
/**@}*/
/** \name Current display properties */
/**@{*/
uint16_t i_changes; /**< changes made to the thread */
float f_gamma; /**< gamma */
vlc_bool_t b_grayscale; /**< color or grayscale display */
vlc_bool_t b_info; /**< print additional information */
vlc_bool_t b_interface; /**< render interface */
vlc_bool_t b_scale; /**< allow picture scaling */
vlc_bool_t b_fullscreen; /**< toogle fullscreen display */
vlc_bool_t b_override_aspect; /**< aspect ratio overriden */
mtime_t render_time; /**< last picture render time */
unsigned int i_window_width; /**< video window width */
unsigned int i_window_height; /**< video window height */
/**@}*/
/** \name Plugin used and shortcuts to access its capabilities */
/**@{*/
module_t * p_module;
int ( *pf_init ) ( vout_thread_t * );
void ( *pf_end ) ( vout_thread_t * );
int ( *pf_manage ) ( vout_thread_t * );
void ( *pf_render ) ( vout_thread_t *, picture_t * );
void ( *pf_display ) ( vout_thread_t *, picture_t * );
/**@}*/
/* Statistics - these numbers are not supposed to be accurate, but are a
/** \name Statistics
* These numbers are not supposed to be accurate, but are a
* good indication of the thread status */
count_t c_fps_samples; /* picture counts */
mtime_t p_fps_sample[VOUT_FPS_SAMPLES]; /* FPS samples dates */
/* Video heap and translation tables */
int i_heap_size; /* heap size */
picture_heap_t render; /* rendered pictures */
picture_heap_t output; /* direct buffers */
vlc_bool_t b_direct; /* rendered are like direct ? */
vout_chroma_t chroma; /* translation tables */
/**@{*/
count_t c_fps_samples; /**< picture counts */
mtime_t p_fps_sample[VOUT_FPS_SAMPLES]; /**< FPS samples dates */
/**@}*/
/** \name Video heap and translation tables */
/**@{*/
int i_heap_size; /**< heap size */
picture_heap_t render; /**< rendered pictures */
picture_heap_t output; /**< direct buffers */
vlc_bool_t b_direct; /**< rendered are like direct ? */
vout_chroma_t chroma; /**< translation tables */
/**@}*/
/* Picture and subpicture heaps */
picture_t p_picture[2*VOUT_MAX_PICTURES]; /* pictures */
subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /* subpictures */
/* Bitmap fonts */
vout_font_t * p_default_font; /* default font */
vout_font_t * p_large_font; /* large font */
picture_t p_picture[2*VOUT_MAX_PICTURES]; /**< pictures */
subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /**< subpictures */
/* Statistics */
count_t c_loops;
count_t c_pictures, c_late_pictures;
mtime_t display_jitter; /* average deviation from the PTS */
count_t c_jitter_samples; /* number of samples used for the *
* calculation of the jitter */
/* delay created by internal caching */
count_t c_loops;
count_t c_pictures, c_late_pictures;
mtime_t display_jitter; /**< average deviation from the PTS */
count_t c_jitter_samples; /**< number of samples used
for the calculation of the
jitter */
/** delay created by internal caching */
int i_pts_delay;
/* Filter chain */
char *psz_filter_chain;
vlc_bool_t b_filter_change;
/* text renderer data */
text_renderer_sys_t * p_text_renderer_data; /**< private data for
the text renderer */
module_t * p_text_renderer_module; /**< text renderer module */
int ( *pf_add_string ) ( vout_thread_t *, char *, text_style_t *, int,
int, int, mtime_t, mtime_t ); /**< callback used when a new string needs to be shown on the vout */
};
#define I_OUTPUTPICTURES p_vout->output.i_pictures
......
......@@ -2,7 +2,7 @@
* spudec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: spudec.c,v 1.19 2003/06/12 22:27:35 massiot Exp $
* $Id: spudec.c,v 1.20 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -52,6 +52,9 @@ static vout_thread_t *FindVout( spudec_thread_t * );
#define DEFAULT_FONT "font-eutopiabold21.rle"
#define ENCODING_TEXT N_("subtitle text encoding")
#define ENCODING_LONGTEXT N_("change the encoding used in text subtitles")
vlc_module_begin();
add_category_hint( N_("subtitles"), NULL, VLC_TRUE );
#if defined(SYS_DARWIN) || defined(SYS_BEOS) \
......@@ -61,6 +64,10 @@ vlc_module_begin();
#else
add_file( "spudec-font", "share/" DEFAULT_FONT, NULL,
FONT_TEXT, FONT_LONGTEXT, VLC_TRUE );
#endif
#if defined(HAVE_ICONV)
add_string( "spudec-encoding", "ISO-8859-1", NULL, ENCODING_TEXT,
ENCODING_LONGTEXT, VLC_FALSE );
#endif
set_description( _("subtitles decoder") );
set_capability( "decoder", 50 );
......@@ -151,7 +158,13 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
p_spudec->p_fifo->b_error = VLC_TRUE;
}
#endif
#if defined(HAVE_ICONV)
p_spudec->iconv_handle = iconv_open( "UTF-8", config_GetPsz( p_spudec->p_fifo, "spudec-encoding" ) );
if( p_spudec->iconv_handle == (iconv_t)-1 )
{
msg_Warn( p_spudec->p_fifo, "Unable to do requested conversion" );
}
#endif
while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) )
{
/* Find/Wait for a video output */
......@@ -324,7 +337,12 @@ static void EndThread( spudec_thread_t *p_spudec )
}
}
}
#if defined(HAVE_ICONV)
if( p_spudec->iconv_handle != (iconv_t)-1 )
{
iconv_close( p_spudec->iconv_handle );
}
#endif
CloseBitstream( &p_spudec->bit_stream );
free( p_spudec );
}
/*****************************************************************************
* spudec.h : sub picture unit decoder thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: spudec.h,v 1.5 2002/12/06 16:34:05 sam Exp $
* $Id: spudec.h,v 1.6 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -21,6 +22,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#if defined(HAVE_ICONV)
#include <iconv.h>
#endif
typedef struct spudec_thread_t spudec_thread_t;
struct subpicture_sys_t
......@@ -83,6 +89,9 @@ struct spudec_thread_t
*/
unsigned int i_spu_size; /* size of current SPU packet */
unsigned int i_rle_size; /* size of the RLE part */
#if defined(HAVE_ICONV)
iconv_t iconv_handle; /* handle to iconv instance */
#endif
};
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* text.c: text subtitles parser
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: text.c,v 1.5 2003/05/11 14:33:32 sigmunau Exp $
* $Id: text.c,v 1.6 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -21,7 +21,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* define USE_FREETYPE here to disable the old style subtitles */
/*****************************************************************************
* Preamble
......@@ -32,6 +31,7 @@
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <osd.h>
#include "spudec.h"
......@@ -44,7 +44,6 @@
*****************************************************************************/
void E_(ParseText)( spudec_thread_t *p_spudec, subtitler_font_t *p_font )
{
#if !defined(USE_FREETYPE)
char * psz_subtitle;
mtime_t i_pts, i_dts;
/* We cannot display a subpicture with no date */
......@@ -74,17 +73,43 @@ void E_(ParseText)( spudec_thread_t *p_spudec, subtitler_font_t *p_font )
if( psz_subtitle[0] != '\0' )
{
#if defined(HAVE_ICONV)
char *psz_new_subtitle, *psz_convert_buffer_out, *psz_convert_buffer_in;
size_t ret, inbytes_left, outbytes_left;
psz_new_subtitle = malloc( 6 * strlen( psz_subtitle ) * sizeof(char) );
psz_convert_buffer_out = psz_new_subtitle;
psz_convert_buffer_in = psz_subtitle;
inbytes_left = strlen( psz_subtitle );
outbytes_left = 6 * inbytes_left;
ret = iconv( p_spudec->iconv_handle, &psz_convert_buffer_in, &inbytes_left, &psz_convert_buffer_out, &outbytes_left );
*psz_convert_buffer_out = '\0';
if( inbytes_left )
{
msg_Warn( p_spudec->p_fifo, "Something fishy happened during conversion" );
}
else
{
msg_Dbg( p_spudec->p_fifo, "reencoded \"%s\" into \"%s\"", psz_subtitle, psz_new_subtitle );
vout_ShowTextAbsolute( p_spudec->p_vout, psz_new_subtitle, NULL,
OSD_ALIGN_BOTTOM|OSD_ALIGN_LEFT, 20, 20,
i_pts, i_dts );
}
free( psz_new_subtitle );
#else
vout_ShowTextAbsolute( p_spudec->p_vout, psz_subtitle, NULL,
OSD_ALIGN_BOTTOM|OSD_ALIGN_LEFT, 20, 20,
i_pts, i_dts );
#endif
#if 0
subtitler_PlotSubtitle( p_spudec->p_vout,
psz_subtitle, p_font,
i_pts,
i_dts );
#endif
}
/* Prepare for next time. No need to check that
* p_spudec->bit_stream->p_data is valid since we check later on
* for b_die and b_error */
NextDataPacket( p_spudec->p_fifo, &p_spudec->bit_stream );
#else
msleep(10);
#endif
}
......@@ -2,7 +2,7 @@
* lirc.c : lirc plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: lirc.c,v 1.6 2003/03/30 18:14:37 gbazin Exp $
* $Id: lirc.c,v 1.7 2003/07/14 21:32:59 sigmunau Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
......@@ -370,25 +370,9 @@ static void Run( intf_thread_t *p_intf )
static void Feedback( intf_thread_t *p_intf, char *psz_string )
{
vlc_value_t val, lockval;
if ( p_intf->p_sys->p_vout
&& var_Get( p_intf->p_sys->p_vout, "lock", &lockval ) == VLC_SUCCESS )
if ( p_intf->p_sys->p_vout )
{
vlc_mutex_lock( lockval.p_address );
val.i_int = OSD_ALIGN_RIGHT|OSD_ALIGN_BOTTOM;
var_Set( p_intf->p_sys->p_vout, "flags", val );
val.i_int = 400000;
var_Set( p_intf->p_sys->p_vout, "duration", val );
val.i_int = 30;
var_Set( p_intf->p_sys->p_vout, "x-margin", val );
val.i_int = 20;
var_Set( p_intf->p_sys->p_vout, "y-margin", val );
val.psz_string = psz_string;
var_Set( p_intf->p_sys->p_vout, "string", val );
vlc_mutex_unlock( lockval.p_address );
}
else
{
msg_Dbg( p_intf, psz_string );
vout_ShowTextRelative( p_intf->p_sys->p_vout, psz_string, NULL,
OSD_ALIGN_TOP|OSD_ALIGN_RIGHT, 30,20,400000 );
}
}
......@@ -2,7 +2,7 @@
* sub.c
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: sub.c,v 1.16 2003/06/26 18:14:56 sam Exp $
* $Id: sub.c,v 1.17 2003/07/14 21:32:59 sigmunau Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -21,8 +21,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* define USE_FREETYPE to use freetype for subtitles */
/*****************************************************************************
* Preamble
*****************************************************************************/
......@@ -33,9 +31,6 @@
#include <vlc/vlc.h>
#include <vlc/input.h>
#if defined(USE_FREETYPE)
#include <osd.h>
#endif
#include "vlc_video.h"
#include "sub.h"
......@@ -447,9 +442,6 @@ static int sub_open ( subtitle_demux_t *p_sub,
*****************************************************************************/
static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
{
#if defined(USE_FREETYPE)
vlc_object_t *p_vout = NULL;
#endif
if( p_sub->p_es->p_decoder_fifo && !p_sub->i_previously_selected )
{
p_sub->i_previously_selected = 1;
......@@ -469,9 +461,6 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
data_packet_t *p_data;
int i_len;
#if defined(USE_FREETYPE)
p_vout = vlc_object_find( p_sub, VLC_OBJECT_VOUT, FIND_ANYWHERE );
#endif
i_len = strlen( p_sub->subtitle[p_sub->i_subtitle].psz_text ) + 1;
......@@ -514,35 +503,7 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
{
p_pes->i_dts = 0;
}
#if defined(USE_FREETYPE)
if( p_vout )
{
vlc_value_t val, lockval;
if( var_Get( p_vout, "lock", &lockval ) == VLC_SUCCESS )
{
int64_t i_tmp;
vlc_mutex_lock( lockval.p_address );
msg_Dbg( p_sub, "pts "I64Fd" dts " I64Fd, p_pes->i_pts,
p_pes->i_dts );
i_tmp = p_pes->i_dts - p_pes->i_pts;
val.i_int = OSD_ALIGN_LEFT|OSD_ALIGN_BOTTOM;
var_Set( p_vout, "flags", val );
val.time.i_low = (int)(p_pes->i_pts+p_sub->p_input->i_pts_delay);
val.time.i_high = (int)( p_pes->i_pts >> 32 );
var_Set( p_vout, "start-date", val );
val.time.i_low = (int)(p_pes->i_dts + p_sub->p_input->i_pts_delay);
val.time.i_high = (int)( p_pes->i_dts >> 32 );
var_Set( p_vout, "stop-date", val );
val.i_int = 20;
var_Set( p_vout, "x-margin", val );
val.i_int = 20;
var_Set( p_vout, "y-margin", val );
val.psz_string = p_sub->subtitle[p_sub->i_subtitle].psz_text;
var_Set( p_vout, "string", val );
vlc_mutex_unlock( lockval.p_address );
}
}
#endif
p_pes->i_nb_data = 1;
p_pes->p_first =
p_pes->p_last = p_data;
......@@ -563,12 +524,6 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
p_sub->i_subtitle++;
}
#if defined(USE_FREETYPE)
if ( p_vout )
{
vlc_object_release( p_vout );
}
#endif
return( 0 );
}
......
......@@ -5,4 +5,5 @@ SOURCES_gnome2_main = gtk_main.c
SOURCES_sap = sap.c
SOURCES_screensaver = screensaver.c
SOURCES_qte_main = qte_main.cpp
SOURCES_freetype = freetype.c
SOURCES_httpd = httpd.c
......@@ -6,5 +6,6 @@ SOURCES_dummy = \
interface.c \
input.c \
decoder.c \
renderer.c \
$(NULL)
......@@ -2,7 +2,7 @@
* dummy.c : dummy plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: dummy.c,v 1.8 2003/06/17 16:09:16 gbazin Exp $
* $Id: dummy.c,v 1.9 2003/07/14 21:32:59 sigmunau Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -80,5 +80,9 @@ vlc_module_begin();
set_callbacks( E_(OpenVideo), NULL );
add_category_hint( N_("Video"), NULL, VLC_FALSE );
add_string( "dummy-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, VLC_FALSE );
add_submodule();
set_description( _("dummy font renderer function") );
set_capability( "text renderer", 1 );
set_callbacks( E_(OpenRenderer), NULL );
vlc_module_end();
......@@ -2,7 +2,7 @@
* dummy.h : dummy plugin for vlc
*****************************************************************************
* Copyright (C) 2000, 2001, 2002 VideoLAN
* $Id: dummy.h,v 1.1 2002/08/04 17:23:43 sam Exp $
* $Id: dummy.h,v 1.2 2003/07/14 21:32:59 sigmunau Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -37,3 +37,4 @@ int E_(OpenAudio) ( vlc_object_t * );
int E_(OpenVideo) ( vlc_object_t * );
int E_(OpenRenderer) ( vlc_object_t * );
/*****************************************************************************
* osd_text.c : Filter to put text on the video, using freetype2
* freetype.c : Put text on the video, using freetype2
*****************************************************************************
* Copyright (C) 2002, 2003 VideoLAN
* $Id: osd_text.c,v 1.5 2003/06/11 20:36:22 gbazin Exp $
* $Id: freetype.c,v 1.1 2003/07/14 21:32:59 sigmunau Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
......@@ -32,8 +32,6 @@
#include <osd.h>
#include <math.h>
#include "filter_common.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
......@@ -46,17 +44,11 @@
static int Create ( vlc_object_t * );
static void Destroy ( vlc_object_t * );
static int Init ( vout_thread_t * );
static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int SetMargin ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int AddText ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static void Render ( vout_thread_t *, picture_t *,
const subpicture_t * );
static int AddText ( vout_thread_t *, byte_t *, text_style_t *, int,
int, int, mtime_t, mtime_t );
static int GetUnicodeCharFromUTF8( byte_t ** );
/*****************************************************************************
* Module descriptor
......@@ -67,11 +59,11 @@ static int AddText ( vlc_object_t *, char const *,
#define FONTSIZE_LONGTEXT N_("The size of the fonts used by the osd module" )
vlc_module_begin();
add_category_hint( N_("OSD"), NULL, VLC_FALSE );
add_file( "osd-font", "", NULL, FONT_TEXT, FONT_LONGTEXT, VLC_FALSE );
add_integer( "osd-fontsize", 16, NULL, FONTSIZE_TEXT, FONTSIZE_LONGTEXT, VLC_FALSE );
set_description( _("osd text filter") );
set_capability( "video filter", 0 );
add_category_hint( N_("Fonts"), NULL, VLC_FALSE );
add_file( "freetype-font", "", NULL, FONT_TEXT, FONT_LONGTEXT, VLC_FALSE );
add_integer( "freetype-fontsize", 16, NULL, FONTSIZE_TEXT, FONTSIZE_LONGTEXT, VLC_FALSE );
set_description( _("freetype2 font renderer") );
set_capability( "text renderer", 100 );
add_shortcut( "text" );
set_callbacks( Create, Destroy );
vlc_module_end();
......@@ -80,19 +72,18 @@ vlc_module_end();
Describes a string to be displayed on the video, or a linked list of
such
*/
typedef struct string_info_s string_info_t;
struct string_info_s
struct subpicture_sys_t
{
string_info_t *p_next;
int i_x_margin;
int i_y_margin;
int i_width;
int i_height;
int i_flags;
mtime_t i_start_date;
mtime_t i_end_date;
char *psz_text;
/** The string associated with this subpicture */
byte_t *psz_text;
/** NULL-terminated list of glyphs making the string */
FT_Glyph *pp_glyphs;
/** list of relative positions for the glyphs */
FT_Vector *p_glyph_pos;
};
......@@ -102,26 +93,17 @@ struct string_info_s
* This structure is part of the video output thread descriptor.
* It describes the osd-text specific properties of an output thread.
*****************************************************************************/
struct vout_sys_t
struct text_renderer_sys_t
{
int i_clones;
vout_thread_t *p_vout;
FT_Library p_library; /* handle to library */
FT_Face p_face; /* handle to face object */
string_info_t *p_strings;
int i_x_margin;
int i_y_margin;
int i_flags;
int i_duration;
mtime_t i_start_date;
mtime_t i_end_date;
vlc_mutex_t *lock;
vlc_bool_t i_use_kerning;
uint8_t pi_gamma[256];
};
/* more prototypes */
static void ComputeBoundingBox( string_info_t * );
static void FreeString( string_info_t * );
//static void ComputeBoundingBox( subpicture_sys_t * );
static void FreeString( subpicture_t * );
/*****************************************************************************
* Create: allocates osd-text video thread output method
......@@ -134,424 +116,253 @@ static int Create( vlc_object_t *p_this )
vout_thread_t *p_vout = (vout_thread_t *)p_this;
char *psz_fontfile;
int i, i_error;
vlc_value_t val;
double gamma_inv = 1.0f / gamma_value;
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
}
p_vout->p_sys->p_strings = NULL;
p_vout->p_sys->i_x_margin = 50;
p_vout->p_sys->i_y_margin = 50;
p_vout->p_sys->i_flags = 0;
p_vout->p_sys->i_duration = 2000000;
p_vout->p_sys->i_start_date = 0;
p_vout->p_sys->i_end_date = 0;
p_vout->p_sys->lock = malloc( sizeof(vlc_mutex_t));
if( p_vout->p_sys->lock == NULL )
p_vout->p_text_renderer_data = malloc( sizeof( text_renderer_sys_t ) );
if( p_vout->p_text_renderer_data == NULL )
{
msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
}
vlc_mutex_init( p_vout, p_vout->p_sys->lock);
for (i = 0; i < 256; i++) {
p_vout->p_sys->pi_gamma[i] =
p_vout->p_text_renderer_data->pi_gamma[i] =
(uint8_t)( pow( (double)i / 255.0f, gamma_inv) * 255.0f );
msg_Dbg( p_vout, "%d", p_vout->p_sys->pi_gamma[i]);
//msg_Dbg( p_vout, "%d", p_vout->p_text_renderer_data->pi_gamma[i]);
}
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = NULL;
p_vout->pf_render = Render;
p_vout->pf_display = NULL;
/* Look what method was requested */
psz_fontfile = config_GetPsz( p_vout, "osd-font" );
i_error = FT_Init_FreeType( &p_vout->p_sys->p_library );
psz_fontfile = config_GetPsz( p_vout, "freetype-font" );
i_error = FT_Init_FreeType( &p_vout->p_text_renderer_data->p_library );
if( i_error )
{
msg_Err( p_vout, "couldn't initialize freetype" );
free( p_vout->p_sys );
free( p_vout->p_text_renderer_data );
return VLC_EGENERIC;
}
i_error = FT_New_Face( p_vout->p_sys->p_library, psz_fontfile, 0,
&p_vout->p_sys->p_face );
i_error = FT_New_Face( p_vout->p_text_renderer_data->p_library,
psz_fontfile, 0,
&p_vout->p_text_renderer_data->p_face );
if( i_error == FT_Err_Unknown_File_Format )
{
msg_Err( p_vout, "file %s have unknown format", psz_fontfile );
free( p_vout->p_sys );
FT_Done_FreeType( p_vout->p_text_renderer_data->p_library );
free( p_vout->p_text_renderer_data );
return VLC_EGENERIC;
}
else if( i_error )
{
msg_Err( p_vout, "failed to load font file" );
free( p_vout->p_sys );
FT_Done_FreeType( p_vout->p_text_renderer_data->p_library );
free( p_vout->p_text_renderer_data );
return VLC_EGENERIC;
}
p_vout->p_sys->i_use_kerning = FT_HAS_KERNING(p_vout->p_sys->p_face);
i_error = FT_Select_Charmap( p_vout->p_text_renderer_data->p_face,
FT_ENCODING_UNICODE );
if ( i_error )
{
msg_Err( p_vout, "Font has no unicode translation table" );
FT_Done_Face( p_vout->p_text_renderer_data->p_face );
FT_Done_FreeType( p_vout->p_text_renderer_data->p_library );
free( p_vout->p_text_renderer_data );
return VLC_EGENERIC;
}
p_vout->p_text_renderer_data->i_use_kerning = FT_HAS_KERNING(p_vout->p_text_renderer_data->p_face);