Commit cf3bb5c0 authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* ALL:

  - Removed all the RLE subtitle font code.
  - Removed the .rle and even older .psf font files.
  - Moved the filesubtitle code from spudec to subsdec.
  - spudec is again DVD only.
parent 1f4b5609
dnl Autoconf settings for vlc
dnl $Id: configure.ac,v 1.39 2003/07/21 17:48:31 gbazin Exp $
dnl $Id: configure.ac,v 1.40 2003/07/22 20:49:10 hartman Exp $
AC_INIT(vlc,0.6.1-test1)
......@@ -768,7 +768,7 @@ dnl
#AX_ADD_BUILTINS([mpeg_video_old idct idctclassic motion])
AX_ADD_PLUGINS([dummy rc logger gestures memcpy])
AX_ADD_PLUGINS([es audio m4v mpeg_system ps ts avi asf aac mp4 rawdv])
AX_ADD_PLUGINS([mpeg_audio lpcm a52 dts cinepak])
AX_ADD_PLUGINS([spudec mpeg_audio lpcm a52 dts cinepak])
AX_ADD_PLUGINS([deinterlace invert adjust wall transform distort clone crop motionblur])
AX_ADD_PLUGINS([float32tos16 float32tos8 float32tou16 float32tou8 a52tospdif dtstospdif fixed32tofloat32 fixed32tos16 s16tofixed32 s16tofloat32 s16tofloat32swab s8tofloat32 u8tofixed32 u8tofloat32])
AX_ADD_PLUGINS([trivial_resampler ugly_resampler linear_resampler bandlimited_resampler])
......@@ -1701,7 +1701,7 @@ then
AC_CHECK_HEADERS(QuickTime/QuickTime.h,
[ AX_ADD_BUILTINS([quicktime])
AX_ADD_LDFLAGS([quicktime],[-framework QuickTime -framework Carbon])
], [ AC_MSG_ERROR([cannot find CoreAudio headers]) ])
], [ AC_MSG_ERROR([cannot find QuickTime headers]) ])
fi
fi
......@@ -1951,11 +1951,11 @@ You also need to check that you have a libogg posterior to the 1.0 release.])],
fi
dnl
dnl spudec support
dnl subsdec support
dnl
AX_ADD_LDFLAGS([spudec],[${LIBICONV}])
AX_ADD_CPPFLAGS([spudec],[${INCICONV}])
AX_ADD_PLUGINS([spudec])
AX_ADD_LDFLAGS([subsdec],[${LIBICONV}])
AX_ADD_CPPFLAGS([subsdec],[${INCICONV}])
AX_ADD_PLUGINS([subsdec])
dnl
......@@ -3254,6 +3254,7 @@ AC_OUTPUT([
modules/codec/mpeg_video/idct/Makefile
modules/codec/mpeg_video/motion/Makefile
modules/codec/spudec/Makefile
modules/codec/subsdec/Makefile
modules/control/Makefile
modules/control/corba/Makefile
modules/control/lirc/Makefile
......
......@@ -2,7 +2,5 @@ SOURCES_spudec = \
spudec.c \
parse.c \
render.c \
text.c \
subtitler.c \
spudec.h \
$(NULL)
......@@ -2,7 +2,7 @@
* parse.c: SPU parser
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: parse.c,v 1.11 2003/03/09 19:25:08 gbazin Exp $
* $Id: parse.c,v 1.12 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -10,7 +10,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
......@@ -166,6 +166,7 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
vlc_mutex_lock( p_mutex );
UpdateSPU( p_spu, VLC_OBJECT(p_spu->p_sys->p_input) );
var_AddCallback( p_spu->p_sys->p_input,
"highlight", CropCallback, p_spu );
vlc_mutex_unlock( p_mutex );
......@@ -273,18 +274,18 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
/* Get the control sequence date */
date = (mtime_t)GetBits( &p_spudec->bit_stream, 16 ) * 11000
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
/* Next offset */
i_cur_seq = i_index;
i_next_seq = GetBits( &p_spudec->bit_stream, 16 );
/* Skip what we just read */
i_index += 4;
}
i_command = GetBits( &p_spudec->bit_stream, 8 );
i_index++;
switch( i_command )
{
case SPU_CMD_FORCE_DISPLAY: /* 00 (force displaying) */
......@@ -412,11 +413,11 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
msg_Err( p_spudec->p_fifo, "no `start display' command" );
}
if( p_spu->i_stop <= p_spu->i_start && !p_spu->b_ephemer )
if( !p_spu->i_stop <= p_spu->i_start && !p_spu->b_ephemer )
{
/* This subtitle will live for 5 seconds or until the next subtitle */
p_spu->i_stop = p_spu->i_start + (mtime_t)500 * 11000
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
p_spu->b_ephemer = VLC_TRUE;
}
......
......@@ -2,7 +2,7 @@
* render.c : SPU renderer
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: render.c,v 1.4 2002/11/06 21:48:24 gbazin Exp $
* $Id: render.c,v 1.5 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Rudolf Cornelissen <rag.cornelissen@inter.nl.net>
......
......@@ -2,7 +2,7 @@
* spudec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: spudec.c,v 1.23 2003/07/21 18:24:51 gbazin Exp $
* $Id: spudec.c,v 1.24 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -10,7 +10,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
......@@ -36,40 +36,17 @@
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( spudec_thread_t * );
static void EndThread ( spudec_thread_t * );
static vout_thread_t *FindVout( spudec_thread_t * );
static vout_thread_t *FindVout( spudec_thread_t *);
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
#define FONT_TEXT N_("Font used by the text subtitler")
#define FONT_LONGTEXT N_(\
"When the subtitles are coded in text form then, you can choose " \
"which font will be used to display them.")
#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) \
|| (defined(WIN32) && !defined(UNDER_CE))
add_file( "spudec-font", NULL, NULL,
FONT_TEXT, FONT_LONGTEXT, VLC_TRUE );
#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_description( _("DVD subtitles decoder") );
set_capability( "decoder", 50 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
......@@ -77,7 +54,7 @@ vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
......@@ -85,12 +62,11 @@ static int OpenDecoder( vlc_object_t *p_this )
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ')
&& p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b')
&& p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
{
&& p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
......@@ -102,11 +78,6 @@ static int OpenDecoder( vlc_object_t *p_this )
static int RunDecoder( decoder_fifo_t * p_fifo )
{
spudec_thread_t * p_spudec;
subtitler_font_t * p_font = NULL;
char * psz_font;
#if 0
vout_thread_t * p_vout_backup = NULL;
#endif
/* Allocate the memory needed to store the thread's structure */
p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) );
......@@ -117,16 +88,13 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
DecoderError( p_fifo );
return( -1 );
}
/*
* Initialize the thread properties
*/
p_spudec->p_vout = NULL;
p_spudec->p_fifo = p_fifo;
#if defined(HAVE_ICONV)
p_spudec->iconv_handle = (iconv_t)-1;
#endif
/*
* Initialize thread and free configuration
*/
......@@ -136,106 +104,19 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
* Main loop - it is not executed if an error occured during
* initialization
*/
if( p_fifo->i_fourcc == VLC_FOURCC('s','u','b','t') )
while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) )
{
/* Here we are dealing with text subtitles */
#if defined(SYS_DARWIN) || defined(SYS_BEOS)
if ( (psz_font = config_GetPsz( p_fifo, "spudec-font" )) == NULL )
{
char * psz_vlcpath = p_fifo->p_libvlc->psz_vlcpath;
psz_font = malloc( strlen(psz_vlcpath) + strlen("/share/")
+ strlen(DEFAULT_FONT) + 1 );
sprintf(psz_font, "%s/share/" DEFAULT_FONT, psz_vlcpath);
}
#elif defined(WIN32) && !defined(UNDER_CE)
if ( (psz_font = config_GetPsz( p_fifo, "spudec-font" )) == NULL )
{
char * psz_vlcpath = p_fifo->p_libvlc->psz_vlcpath;
psz_font = malloc( strlen(psz_vlcpath) + strlen("\\share\\")
+ strlen(DEFAULT_FONT) + 1 );
sprintf(psz_font, "%s\\share\\" DEFAULT_FONT, psz_vlcpath);
}
#else
if( (psz_font = config_GetPsz( p_fifo, "spudec-font" )) == NULL )
{
msg_Err( p_fifo, "no default font selected" );
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 */
p_spudec->p_vout = FindVout( p_spudec );
if( p_spudec->p_vout )
{
#if 0
if( p_spudec->p_vout != p_vout_backup )
{
/* The vout has changed, we need to reload the fonts */
p_vout_backup = p_spudec->p_vout;
p_font = E_(subtitler_LoadFont)( p_spudec->p_vout,
psz_font );
if( p_font == NULL )
{
msg_Err( p_fifo, "unable to load font: %s", psz_font );
p_spudec->p_fifo->b_error = VLC_TRUE;
vlc_object_release( p_spudec->p_vout );
break;
}
}
#endif
E_(ParseText)( p_spudec, p_font );
vlc_object_release( p_spudec->p_vout );
}
}
if( psz_font ) free( psz_font );
if( p_font )
if( E_(SyncPacket)( p_spudec ) )
{
/* Find/Wait for a video output */
p_spudec->p_vout = FindVout( p_spudec );
if( p_spudec->p_vout )
{
E_(subtitler_UnloadFont)( p_spudec->p_vout, p_font );
vlc_object_release( p_spudec->p_vout );
}
continue;
}
}
else
{
/* Here we are dealing with sub-pictures subtitles*/
while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) )
/* Find/Wait for a video output */
p_spudec->p_vout = FindVout( p_spudec );
if( p_spudec->p_vout)
{
if( E_(SyncPacket)( p_spudec ) )
{
continue;
}
/* Find/Wait for a video output */
p_spudec->p_vout = FindVout( p_spudec );
if( p_spudec->p_vout )
{
E_(ParsePacket)( p_spudec );
vlc_object_release( p_spudec->p_vout );
}
E_(ParsePacket)( p_spudec );
vlc_object_release( p_spudec->p_vout );
}
}
......@@ -268,24 +149,24 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
static int InitThread( spudec_thread_t *p_spudec )
{
int i_ret;
/* Call InitBitstream anyway so p_spudec->bit_stream is in a known
* state before calling CloseBitstream */
i_ret = InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo,
NULL, NULL );
NULL, NULL );
/* Check for a video output */
p_spudec->p_vout = FindVout( p_spudec );
if( !p_spudec->p_vout )
{
return -1;
}
/* It was just a check */
vlc_object_release( p_spudec->p_vout );
p_spudec->p_vout = NULL;
return i_ret;
}
......@@ -295,7 +176,7 @@ static int InitThread( spudec_thread_t *p_spudec )
static vout_thread_t *FindVout( spudec_thread_t *p_spudec )
{
vout_thread_t *p_vout = NULL;
/* Find an available video output */
do
{
......@@ -305,7 +186,7 @@ static vout_thread_t *FindVout( spudec_thread_t *p_spudec )
}
p_vout = vlc_object_find( p_spudec->p_fifo, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
FIND_ANYWHERE );
if( p_vout )
{
......@@ -327,12 +208,12 @@ static vout_thread_t *FindVout( spudec_thread_t *p_spudec )
*****************************************************************************/
static void EndThread( spudec_thread_t *p_spudec )
{
if( p_spudec->p_vout != NULL
if( p_spudec->p_vout != NULL
&& p_spudec->p_vout->p_subpicture != NULL )
{
subpicture_t * p_subpic;
int i_subpic;
for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
{
p_subpic = &p_spudec->p_vout->p_subpicture[i_subpic];
......@@ -345,12 +226,8 @@ 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.6 2003/07/14 21:32:58 sigmunau Exp $
* $Id: spudec.h,v 1.7 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -11,7 +10,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
......@@ -22,11 +21,6 @@
* 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
......@@ -50,18 +44,6 @@ struct subpicture_sys_t
unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
};
/*****************************************************************************
* subtitler_font_t : proportional font
*****************************************************************************/
typedef struct subtitler_font_s
{
unsigned int i_height; /* character height in pixels */
unsigned int i_width[256]; /* character widths in pixels */
unsigned int i_memory[256]; /* amount of memory used by character */
unsigned int * p_length[256]; /* line byte widths */
uint16_t ** p_offset[256]; /* pointer to RLE data */
} subtitler_font_t;
/*****************************************************************************
* spudec_thread_t : sub picture unit decoder thread descriptor
*****************************************************************************/
......@@ -89,9 +71,6 @@ 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
};
/*****************************************************************************
......@@ -120,9 +99,3 @@ void E_(ParsePacket) ( spudec_thread_t * );
void E_(RenderSPU) ( vout_thread_t *, picture_t *,
const subpicture_t * );
void E_(ParseText) ( spudec_thread_t *, subtitler_font_t * );
subtitler_font_t *E_(subtitler_LoadFont) ( vout_thread_t *, const char * );
void E_(subtitler_UnloadFont) ( vout_thread_t *, subtitler_font_t * );
void E_(subtitler_PlotSubtitle) ( vout_thread_t *, char *, subtitler_font_t *,
mtime_t, mtime_t );
/*****************************************************************************
* subtitler.c : subtitler font routines
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors: Andrew Flintham <amf@cus.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memcpy(), memset() */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <ctype.h> /* toascii() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* read(), close() */
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include "spudec.h"
/*****************************************************************************
* subtitler_line : internal structure for an individual line in a subtitle
*****************************************************************************/
typedef struct subtitler_line_s
{
struct subtitler_line_s * p_next;
char * p_text;
} subtitler_line_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static uint16_t *PlotSubtitleLine( char *, subtitler_font_t *, unsigned int,
uint16_t * );
static void DestroySPU ( subpicture_t * );
/*****************************************************************************
* subtitler_LoadFont: load a run-length encoded font file into memory
*****************************************************************************
* RLE font files have the following format:
*
* 2 bytes : magic number: 0x36 0x05
* 1 byte : font height in rows
*
* then, per character:
* 1 byte : character
* 1 byte : character width in pixels
*
* then, per row:
* 1 byte : length of row, in entries
*
* then, per entry
* 1 byte : colour
* 1 byte : number of pixels of that colour
*
* to end:
* 1 byte : 0xff
*****************************************************************************/
subtitler_font_t* E_(subtitler_LoadFont)( vout_thread_t * p_vout,
const char * psz_name )
{
subtitler_font_t * p_font;
unsigned int i;
unsigned int i_char;
unsigned int i_length;
unsigned int i_line;
unsigned int i_total_length;
int i_file;
byte_t pi_buffer[512]; /* file buffer */
msg_Dbg( p_vout, "loading font '%s'", psz_name );
i_file = open( psz_name, O_RDONLY );
if( i_file == -1 )
{
msg_Err( p_vout, "can't open font file '%s' (%s)", psz_name,
strerror(errno) );
return( NULL );
}
/* Read magick number */
if( read( i_file, pi_buffer, 2 ) != 2 )
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name );
close( i_file );
return( NULL );
}
if( pi_buffer[0] != 0x36 || pi_buffer[1] != 0x05 )
{
msg_Err( p_vout, "file '%s' is not a font file", psz_name );
close( i_file );
return( NULL );
}
p_font = malloc( sizeof( subtitler_font_t ) );
if( p_font == NULL )
{
msg_Err( p_vout, "out of memory" );
close( i_file );
return NULL;
}
/* Read font height */
if( read( i_file, pi_buffer, 1 ) != 1 )
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name );
free( p_font );
close( i_file );
return( NULL );
}
p_font->i_height = pi_buffer[0];
/* Initialise font character data */
for( i = 0; i < 256; i++ )
{
p_font->i_width[i] = 0;
p_font->i_memory[i] = 0;
p_font->p_offset[i] = NULL;
p_font->p_length[i] = NULL;
}
while(1)
{
/* Read character number */
if( read( i_file, pi_buffer, 1 ) != 1)
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name );
close( i_file );
E_(subtitler_UnloadFont)( p_vout, p_font );
return( NULL );
}
i_char = pi_buffer[0];
/* Character 255 signals the end of the font file */
if(i_char == 255)
{
break;
}
/* Read character width */
if( read( i_file, pi_buffer, 1 ) != 1 )
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name );
close( i_file );
E_(subtitler_UnloadFont)( p_vout, p_font );
return( NULL );
}
p_font->i_width[ i_char ] = pi_buffer[0];
p_font->p_length[ i_char ] = (int *) malloc(
sizeof(int) * p_font->i_height );
p_font->p_offset[ i_char ] = (uint16_t **) malloc(
sizeof(uint16_t *) * p_font->i_height);
if( p_font->p_length[ i_char] == NULL ||
p_font->p_offset[ i_char ] == NULL )
{
msg_Err( p_vout, "out of memory" );
close( i_file );
E_(subtitler_UnloadFont)( p_vout, p_font );
return NULL;
}
for( i_line=0; i_line < p_font->i_height; i_line ++ )
{
p_font->p_offset[ i_char ][ i_line ] = NULL;
}
i_total_length=0;
for( i_line = 0; i_line < p_font->i_height; i_line ++ )
{
/* Read line length */
if( read( i_file, pi_buffer, 1 ) != 1)
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name);
E_(subtitler_UnloadFont)( p_vout, p_font );
close( i_file );
return( NULL );
}
i_length = pi_buffer[0];
p_font->p_length[ i_char ][ i_line ] = i_length;
i_total_length += i_length;
/* Read line RLE data */
if( read( i_file, pi_buffer, i_length*2 ) != (int)i_length*2)
{
msg_Err( p_vout, "unexpected end of font file '%s'", psz_name);
E_(subtitler_UnloadFont)( p_vout, p_font );
close( i_file );
return( NULL );
}
p_font->p_offset[ i_char ][ i_line ] =
(uint16_t *) malloc( sizeof( uint16_t ) * i_length );
if( p_font->p_offset[ i_char ][ i_line ] == NULL )
{
msg_Err( p_vout, "out of memory" );
close( i_file );
E_(subtitler_UnloadFont)( p_vout, p_font );
return NULL;
}
for( i = 0; i < i_length; i++ )
{
*( p_font->p_offset[ i_char ][ i_line ] + i ) =
(uint16_t) ( pi_buffer[ i * 2 ] +
( pi_buffer[ i * 2 + 1 ] << 2 ) );
}
}
/* Set total memory size of character */
p_font->i_memory[ i_char ] = i_total_length;
}
close(i_file);
return p_font;
}
/*****************************************************************************
* subtitler_UnloadFont: unload a run-length encoded font file from memory
*****************************************************************************/
void E_(subtitler_UnloadFont)( vout_thread_t * p_vout,
subtitler_font_t * p_font )
{
unsigned int i_char;
unsigned int i_line;
msg_Dbg( p_vout, "unloading font" );
if( p_font == NULL )
{
return;
}
for( i_char = 0; i_char < 256; i_char ++ )
{
if( p_font->p_offset[ i_char ] != NULL )
{
for( i_line = 0; i_line < p_font->i_height; i_line++ )
{
if( p_font->p_offset[ i_char ][ i_line ] != NULL )
{
free( p_font->p_offset[ i_char ][ i_line ] );
}
}
free( p_font->p_offset[ i_char ] );
}
if( p_font->p_length[ i_char ] != NULL )
{
free( p_font->p_length[ i_char ] );
}
}
free( p_font );
}
/*****************************************************************************
* subtitler_PlotSubtitle: create a subpicture containing the subtitle
*****************************************************************************/
void subtitler_PlotSubtitle ( vout_thread_t *p_vout , char *psz_subtitle,
subtitler_font_t *p_font, mtime_t i_start,
mtime_t i_stop )
{
subpicture_t * p_spu;
unsigned int i_x;
unsigned int i_width;
unsigned int i_lines;
unsigned int i_longest_width;
unsigned int i_total_length;
unsigned int i_char;
uint16_t * p_data;
char * p_line_start;
char * p_word_start;
char * p_char;
subtitler_line_t * p_first_line;
subtitler_line_t * p_previous_line;
subtitler_line_t * p_line;
if( p_font == NULL )
{
msg_Err( p_vout, "attempt to use NULL font in subtitle" );
return;
}
p_first_line = NULL;
p_previous_line = NULL;
p_line_start = psz_subtitle;
while( *p_line_start != 0 )
{
i_width = 0;
p_word_start = p_line_start;
p_char = p_line_start;
while( *p_char != '\n' && *p_char != 0 )
{
i_width += p_font->i_width[ toascii( *p_char ) ];
if( i_width > p_vout->output.i_width )
{
/* If the line has more than one word, break at the end of
the previous one. If the line is one very long word,
display as much as we can of it */
if( p_word_start != p_line_start )
{
p_char=p_word_start;
}
break;
}
if( *p_char == ' ' )
{
p_word_start = p_char+1;
}
p_char++;
}
p_line = malloc(sizeof(subtitler_line_t));
if( p_line == NULL )
{
msg_Err( p_vout, "out of memory" );
return;
}
if( p_first_line == NULL )
{
p_first_line = p_line;
}
if( p_previous_line != NULL )
{
p_previous_line->p_next = p_line;
}
p_previous_line = p_line;
p_line->p_next = NULL;
p_line->p_text = malloc(( p_char - p_line_start ) +1 );
if( p_line == NULL )
{
msg_Err( p_vout, "out of memory" );
return;
}
/* Copy only the part of the text that is in this line */
strncpy( p_line->p_text , p_line_start , p_char - p_line_start );
*( p_line->p_text + ( p_char - p_line_start )) = 0;
/* If we had to break a line because it was too long, ensure that
no characters are lost */
if( *p_char != '\n' && *p_char != 0 )
{
p_char--;
}
p_line_start = p_char;
if( *p_line_start != 0 )
{
p_line_start ++;
}
}
i_lines = 0;
i_longest_width = 0;
i_total_length = 0;
p_line = p_first_line;
/* Find the width of the longest line, count the total number of lines,
and calculate the amount of memory we need to allocate for the RLE
data */
while( p_line != NULL )
{
i_lines++;
i_width = 0;
for( i_x = 0; i_x < strlen( p_line->p_text ); i_x++ )
{
i_char = toascii(*(( p_line->p_text )+ i_x ));
i_width += p_font->i_width[ i_char ];
i_total_length += p_font->i_memory[ i_char ];
}
if(i_width > i_longest_width)
{
i_longest_width = i_width;
}
p_line = p_line->p_next;
}
/* Allow space for the padding bytes at either edge */
i_total_length += p_font->i_height * 2 * i_lines;
/* Allocate the subpicture internal data. */
p_spu = vout_CreateSubPicture( p_vout, MEMORY_SUBPICTURE );
if( p_spu == NULL )
{
return;
}
/* Rationale for the "p_spudec->i_rle_size * 4": we are going to
* expand the RLE stuff so that we won't need to read nibbles later
* on. This will speed things up a lot. Plus, we'll only need to do
* this stupid interlacing stuff once. */
p_spu->p_sys = malloc( sizeof( subpicture_sys_t )
+ i_total_length * sizeof(uint16_t) );
if( p_spu->p_sys == NULL )
{
vout_DestroySubPicture( p_vout, p_spu );
return;
}
/* Fill the p_spu structure */
p_spu->pf_render = E_(RenderSPU);
p_spu->pf_destroy = DestroySPU;
p_spu->p_sys->p_data = (uint8_t *)p_spu->p_sys + sizeof(subpicture_sys_t);
p_spu->i_start = i_start;
p_spu->i_stop = i_stop;
p_spu->b_ephemer = i_stop ? VLC_FALSE : VLC_TRUE;
/* FIXME: Do we need these two? */
p_spu->p_sys->pi_offset[0] = 0;
p_spu->p_sys->pi_offset[1] = 0;
p_spu->p_sys->b_palette = 1;
/* Colour 0 is transparent */
p_spu->p_sys->pi_yuv[0][0] = 0xff;
p_spu->p_sys->pi_yuv[0][1] = 0x80;
p_spu->p_sys->pi_yuv[0][2] = 0x80;
p_spu->p_sys->pi_yuv[0][3] = 0x80;
p_spu->p_sys->pi_alpha[0] = 0x0;
/* Colour 1 is grey */
p_spu->p_sys->pi_yuv[1][0] = 0x80;
p_spu->p_sys->pi_yuv[1][1] = 0x80;
p_spu->p_sys->pi_yuv[1][2] = 0x80;
p_spu->p_sys->pi_yuv[1][3] = 0x80;
p_spu->p_sys->pi_alpha[1] = 0xf;
/* Colour 2 is white */
p_spu->p_sys->pi_yuv[2][0] = 0xff;
p_spu->p_sys->pi_yuv[2][1] = 0xff;
p_spu->p_sys->pi_yuv[2][2] = 0xff;
p_spu->p_sys->pi_yuv[2][3] = 0xff;
p_spu->p_sys->pi_alpha[2] = 0xf;
/* Colour 3 is black */
p_spu->p_sys->pi_yuv[3][0] = 0x00;
p_spu->p_sys->pi_yuv[3][1] = 0x00;
p_spu->p_sys->pi_yuv[3][2] = 0x00;
p_spu->p_sys->pi_yuv[3][3] = 0x00;
p_spu->p_sys->pi_alpha[3] = 0xf;
p_spu->p_sys->b_crop = VLC_FALSE;
p_spu->i_x = (p_vout->output.i_width - i_longest_width) / 2;
p_spu->i_y = p_vout->output.i_height - (p_font->i_height * i_lines);
p_spu->i_width = i_longest_width;
p_spu->i_height = p_font->i_height*i_lines;
p_data = (uint16_t *)(p_spu->p_sys->p_data);
p_line = p_first_line;
while( p_line != NULL )
{
p_data = PlotSubtitleLine( p_line->p_text,
p_font, i_longest_width, p_data );
p_previous_line = p_line;
p_line = p_line->p_next;
free( p_previous_line->p_text );
free( p_previous_line );
}
/* SPU is finished - we can ask the video output to display it */
vout_DisplaySubPicture( p_vout, p_spu );
}
/*****************************************************************************
* PlotSubtitleLine: plot a single line of a subtitle
*****************************************************************************/
static uint16_t * PlotSubtitleLine ( char *psz_line, subtitler_font_t *p_font,
unsigned int i_total_width,
uint16_t *p_data )
{
unsigned int i_x;
unsigned int i_y;
unsigned int i_length;
unsigned int i_line_width;
unsigned int i_char;
uint16_t * p_rle;
i_line_width = 0;
for( i_x = 0; i_x< strlen( psz_line ); i_x++ )
{
i_line_width += p_font->i_width[ toascii( *( psz_line+i_x ) ) ]; }
for( i_y = 0; i_y < p_font->i_height; i_y++ )
{
/* Pad line to fit box */
if( i_line_width < i_total_width )
{
*p_data++ = ((( i_total_width - i_line_width)/2) << 2 );
}
for(i_x = 0; i_x < strlen(psz_line); i_x ++)
{
i_char = toascii( *(psz_line + i_x) );
if( p_font->i_width[ i_char ] != 0 )
{
p_rle = p_font->p_offset[ i_char ][ i_y ];
i_length = p_font->p_length[ i_char ][ i_y ];
if(p_rle != NULL )
{
memcpy(p_data, p_rle, i_length * sizeof(uint16_t) );
p_data+=i_length;
}
}
}
/* Pad line to fit box */
if( i_line_width < i_total_width )
{
*p_data++ = ((( i_total_width - i_line_width)
- (( i_total_width - i_line_width)/2)) << 2 );
}
}
return p_data;
}
/*****************************************************************************
* DestroySPU: subpicture destructor
*****************************************************************************/
static void DestroySPU( subpicture_t *p_spu )
{
free( p_spu->p_sys );
}
/*****************************************************************************
* text.c: text subtitles parser
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: text.c,v 1.6 2003/07/14 21:32:58 sigmunau Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <osd.h>
#include "spudec.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
/*****************************************************************************
* ParseText: parse an text subtitle packet and send it to the video output
*****************************************************************************/
void E_(ParseText)( spudec_thread_t *p_spudec, subtitler_font_t *p_font )
{
char * psz_subtitle;
mtime_t i_pts, i_dts;
/* We cannot display a subpicture with no date */
i_pts = p_spudec->bit_stream.p_pes->i_pts;
i_dts = p_spudec->bit_stream.p_pes->i_dts;
if( i_pts == 0 )
{
/* Dump the packet */
NextDataPacket( p_spudec->p_fifo, &p_spudec->bit_stream );
msg_Warn( p_spudec->p_fifo, "subtitle without a date" );
return;
}
/* Check validity of packet data */
if( (p_spudec->bit_stream.p_data->p_payload_end
- p_spudec->bit_stream.p_data->p_payload_start) <= 0
|| (strlen(p_spudec->bit_stream.p_data->p_payload_start)
> (size_t)(p_spudec->bit_stream.p_data->p_payload_end
- p_spudec->bit_stream.p_data->p_payload_start)) )
{
/* Dump the packet */
NextDataPacket( p_spudec->p_fifo, &p_spudec->bit_stream );
msg_Warn( p_spudec->p_fifo, "invalid subtitle" );
return;
}
psz_subtitle = p_spudec->bit_stream.p_data->p_payload_start;
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 );
}
.deps
.dirstamp
*.lo
*.la
*.dll
*.dylib
*.sl
*.so
Makefile.am
Makefile.in
Makefile
SOURCES_subsdec = \
subsdec.c \
subsdec.h \
$(NULL)
/*****************************************************************************
* subsdec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: subsdec.c,v 1.1 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <osd.h>
#include "subsdec.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( subsdec_thread_t * );
static void EndThread ( subsdec_thread_t * );
static vout_thread_t *FindVout( subsdec_thread_t * );
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
static char *ppsz_encodings[] = { "ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3",
"ISO-8859-4", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8",
"ISO-8859-9", "ISO-8859-10", "ISO-8859-13", "ISO-8859-14", "ISO-8859-15",
"ISO-8859-16", "ISO-2022-JP", "ISO-2022-JP-1", "ISO-2022-JP-2", "ISO-2022-CN",
"ISO-2022-CN-EXT", "ISO-2022-KR",
"CP850", "CP862", "CP866", "CP874", "CP932", "CP949", "CP950", "CP1133",
"CP1250", "CP1251", "CP1252", "CP1253", "CP1254", "CP1255", "CP1256", "CP1257", "CP1258",
"MacRoman", "MacCentralEurope", "MacIceland", "MacCroatian", "MacRomania",
"MacCyrillic", "MacUkraine", "MacGreek", "MacTurkish", "MacHebrew", "MacArabic",
"MacThai", "Macintosh",
"UTF-7", "UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE", "UTF-32", "UTF-32BE", "UTF-32LE",
"C99", "JAVA", "UCS-2", "UCS-2BE", "UCS-2LE", "UCS-4", "UCS-4BE", "UCS-4LE",
"KOI8-R", "KOI8-U", "KOI8-RU", "KOI8-T",
"EUC-JP", "EUC-CN", "EUC-KR", "EUC-TW",
"SHIFT_JIS", "HZ", "GBK", "GB18030", "BIG5", "BIG5-HKSCS", "JOHAB", "ARMSCII-8",
"Georgian-Academy", "Georgian-PS", "TIS-620", "MuleLao-1", "VISCII", "TCVN",
"HPROMAN8", "NEXTSTEP", NULL };
#define ENCODING_TEXT N_("subtitle text encoding")
#define ENCODING_LONGTEXT N_("change the encoding used in text subtitles")
vlc_module_begin();
set_description( _("file subtitles decoder") );
set_capability( "decoder", 50 );
set_callbacks( OpenDecoder, NULL );
#if defined(HAVE_ICONV)
add_string_from_list( "subsdec-encoding", "ISO-8859-1", ppsz_encodings, NULL,
ENCODING_TEXT, ENCODING_LONGTEXT, VLC_FALSE );
#endif
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
*****************************************************************************/
static int RunDecoder( decoder_fifo_t * p_fifo )
{
subsdec_thread_t * p_subsdec;
vout_thread_t * p_vout_backup = NULL;
/* Allocate the memory needed to store the thread's structure */
p_subsdec = (subsdec_thread_t *)malloc( sizeof(subsdec_thread_t) );
if ( p_subsdec == NULL )
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
/*
* Initialize the thread properties
*/
p_subsdec->p_vout = NULL;
p_subsdec->p_fifo = p_fifo;
#if defined(HAVE_ICONV)
p_subsdec->iconv_handle = (iconv_t)-1;
#endif
/*
* Initialize thread and free configuration
*/
p_subsdec->p_fifo->b_error = InitThread( p_subsdec );
/*
* Main loop - it is not executed if an error occured during
* initialization
*/
if( p_fifo->i_fourcc == VLC_FOURCC('s','u','b','t') )
{
/* Here we are dealing with text subtitles */
#if defined(HAVE_ICONV)
p_subsdec->iconv_handle = iconv_open( "UTF-8",
config_GetPsz( p_subsdec->p_fifo, "subsdec-encoding" ) );
if( p_subsdec->iconv_handle == (iconv_t)-1 )
{
msg_Warn( p_subsdec->p_fifo, "Unable to do requested conversion" );
}
#endif
while( (!p_subsdec->p_fifo->b_die) && (!p_subsdec->p_fifo->b_error) )
{
/* Find/Wait for a video output */
p_subsdec->p_vout = FindVout( p_subsdec );
if( p_subsdec->p_vout )
{
E_(ParseText)( p_subsdec );
vlc_object_release( p_subsdec->p_vout );
}
}
}
/*
* Error loop
*/
if( p_subsdec->p_fifo->b_error )
{
DecoderError( p_subsdec->p_fifo );
/* End of thread */
EndThread( p_subsdec );
return -1;
}
/* End of thread */
EndThread( p_subsdec );
return 0;
}
/* following functions are local */
/*****************************************************************************
* InitThread: initialize spu decoder thread
*****************************************************************************
* This function is called from RunThread and performs the second step of the
* initialization. It returns 0 on success. Note that the thread's flag are not
* modified inside this function.
*****************************************************************************/
static int InitThread( subsdec_thread_t *p_subsdec )
{
int i_ret;
/* Call InitBitstream anyway so p_subsdec->bit_stream is in a known
* state before calling CloseBitstream */
i_ret = InitBitstream( &p_subsdec->bit_stream, p_subsdec->p_fifo,
NULL, NULL );
/* Check for a video output */
p_subsdec->p_vout = FindVout( p_subsdec );
if( !p_subsdec->p_vout )
{
return -1;
}
/* It was just a check */
vlc_object_release( p_subsdec->p_vout );
p_subsdec->p_vout = NULL;
return i_ret;
}
/*****************************************************************************
* FindVout: Find a vout or wait for one to be created.
*****************************************************************************/
static vout_thread_t *FindVout( subsdec_thread_t *p_subsdec )
{
vout_thread_t *p_vout = NULL;
/* Find an available video output */
do
{
if( p_subsdec->p_fifo->b_die || p_subsdec->p_fifo->b_error )
{
break;
}
p_vout = vlc_object_find( p_subsdec->p_fifo, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout )
{
break;
}
msleep( VOUT_OUTMEM_SLEEP );
}
while( 1 );
return p_vout;
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
* This function is called when the thread ends after a sucessful
* initialization.
*****************************************************************************/
static void EndThread( subsdec_thread_t *p_subsdec )
{
if( p_subsdec->p_vout != NULL
&& p_subsdec->p_vout->p_subpicture != NULL )
{
subpicture_t * p_subpic;
int i_subpic;
for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
{
p_subpic = &p_subsdec->p_vout->p_subpicture[i_subpic];
if( p_subpic != NULL &&
( ( p_subpic->i_status == RESERVED_SUBPICTURE )
|| ( p_subpic->i_status == READY_SUBPICTURE ) ) )
{
vout_DestroySubPicture( p_subsdec->p_vout, p_subpic );
}
}
}
#if defined(HAVE_ICONV)
if( p_subsdec->iconv_handle != (iconv_t)-1 )
{
iconv_close( p_subsdec->iconv_handle );
}
#endif
CloseBitstream( &p_subsdec->bit_stream );
free( p_subsdec );
}
/*****************************************************************************
* ParseText: parse an text subtitle packet and send it to the video output
*****************************************************************************/
void E_(ParseText)( subsdec_thread_t *p_subsdec )
{
char * psz_subtitle;
mtime_t i_pts, i_dts;
/* We cannot display a subpicture with no date */
i_pts = p_subsdec->bit_stream.p_pes->i_pts;
i_dts = p_subsdec->bit_stream.p_pes->i_dts;
if( i_pts == 0 )
{
/* Dump the packet */
NextDataPacket( p_subsdec->p_fifo, &p_subsdec->bit_stream );
msg_Warn( p_subsdec->p_fifo, "subtitle without a date" );
return;
}
/* Check validity of packet data */
if( (p_subsdec->bit_stream.p_data->p_payload_end
- p_subsdec->bit_stream.p_data->p_payload_start) <= 0
|| (strlen(p_subsdec->bit_stream.p_data->p_payload_start)
> (size_t)(p_subsdec->bit_stream.p_data->p_payload_end
- p_subsdec->bit_stream.p_data->p_payload_start)) )
{
/* Dump the packet */
NextDataPacket( p_subsdec->p_fifo, &p_subsdec->bit_stream );
msg_Warn( p_subsdec->p_fifo, "invalid subtitle" );
return;
}
psz_subtitle = p_subsdec->bit_stream.p_data->p_payload_start;
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_subsdec->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_subsdec->p_fifo, "Something fishy happened during conversion" );
}
else
{
msg_Dbg( p_subsdec->p_fifo, "reencoded \"%s\" into \"%s\"", psz_subtitle, psz_new_subtitle );
vout_ShowTextAbsolute( p_subsdec->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_subsdec->p_vout, psz_subtitle, NULL,
OSD_ALIGN_BOTTOM|OSD_ALIGN_LEFT, 20, 20,
i_pts, i_dts );
#endif
}
/* Prepare for next time. No need to check that
* p_subsdec->bit_stream->p_data is valid since we check later on
* for b_die and b_error */
NextDataPacket( p_subsdec->p_fifo, &p_subsdec->bit_stream );
}
/*****************************************************************************
* subsdec.h : sub picture unit decoder thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: subsdec.h,v 1.1 2003/07/22 20:49:10 hartman Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#if defined(HAVE_ICONV)
#include <iconv.h>
#endif
typedef struct subsdec_thread_t subsdec_thread_t;
/*****************************************************************************
* subsdec_thread_t : sub picture unit decoder thread descriptor
*****************************************************************************/
struct subsdec_thread_t
{
/*
* Thread properties and locks
*/
vlc_thread_t thread_id; /* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/*
* Output properties
*/
vout_thread_t * p_vout; /* needed to create the spu objects */
/*
* Private properties
*/
#if defined(HAVE_ICONV)
iconv_t iconv_handle; /* handle to iconv instance */
#endif
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
int E_(SyncPacket) ( subsdec_thread_t * );
void E_(ParsePacket) ( subsdec_thread_t * );
void E_(ParseText) ( subsdec_thread_t * );
<html>
<head>
<title>VLC Media Player - Informations</title>
<title>VLC Media Player</title>
<vlc id="if" param1="url_param"/>
<meta http-equiv="refresh" content="0;URL=/" />
<vlc id="end" />
<vlc id="control" param1="stop,pause,previous,next,add,sout,play" />
<vlc id="set" param1="sout" param2="string" />
</head>
<body>
<h2><center><a href="http://www.videolan.org">VLC Media Player <vlc id="value" param1="version" /></a></center></h2>
<h2><center><a href="http://www.videolan.org">VLC Media Player <vlc id="value" param1="version" /></a> (http interface)</center></h2>
<hr/>
<td>
<form method="get" action="">
<input type="submit" name="control" value="stop" />
<input type="submit" name="control" value="pause" />
<input type="submit" name="control" value="previous" />
<input type="submit" name="control" value="next" />
<a href="info.html">infos</a>
</form>
</td>
<br />
<td>
<form method="get" action="" enctype="text/plain" >
<input type="text" name="mrl" size="40" />
<input type="submit" name="control" value="add" />
</form>
</td>
<td>
<form method="get" action="" enctype="text/plain" >
<input type="text" name="sout" size="30" value="<vlc id="get" param1="sout" param2="string" />" />
<input type="submit" name="control" value="sout" />
</form>
</td>
<hr/>
<vlc id="foreach" param1="cat" param2="informations" />
<p> <vlc id="value" param1="cat.name" />
<ul>
<vlc id="foreach" param1="info" param2="cat.info" />
<li> <vlc id="value" param1="info.name" /> : <vlc id="value" param1="info.value" /> </li>
<p>
<vlc id="foreach" param1="pl" param2="playlist" />
<vlc id="if" param1="pl.current" />
<b>
<vlc id="end" />
<a href=?control=play&item=<vlc id="value" param1="pl.index" />><vlc id="value" param1="pl.index" /> - <vlc id="value" param1="pl.name" /></a> <br />
<vlc id="if" param1="pl.current" />
</b>
<vlc id="end" />
<vlc id="end" />
</ul>
<vlc id="end" />
</p>
<hr/>
<p><vlc id="value" param1="copyright" /> </p>
<p> <vlc id="value" param1="copyright" /> </p>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment