mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-03 01:31:53 +02:00
* modules/codec/subsdec.c: cleaned up and ported the text subtitles decoder to the new decoder api.
This commit is contained in:
parent
2f72e38f4f
commit
91f6deaecd
@ -1,5 +1,5 @@
|
||||
dnl Autoconf settings for vlc
|
||||
dnl $Id: configure.ac,v 1.78 2003/09/27 10:09:57 gbazin Exp $
|
||||
dnl $Id: configure.ac,v 1.79 2003/10/01 22:19:57 gbazin Exp $
|
||||
|
||||
AC_INIT(vlc,0.6.3-cvs)
|
||||
|
||||
@ -3320,7 +3320,6 @@ 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
|
||||
|
@ -14,3 +14,4 @@ SOURCES_mpeg_audio = mpeg_audio.c
|
||||
SOURCES_libmpeg2 = libmpeg2.c
|
||||
SOURCES_rawvideo = rawvideo.c
|
||||
SOURCES_quicktime = quicktime.c
|
||||
SOURCES_subsdec = subsdec.c
|
||||
|
304
modules/codec/subsdec.c
Normal file
304
modules/codec/subsdec.c
Normal file
@ -0,0 +1,304 @@
|
||||
/*****************************************************************************
|
||||
* subsdec.c : text subtitles decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000-2001 VideoLAN
|
||||
* $Id: subsdec.c,v 1.1 2003/10/01 22:19:57 gbazin 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>
|
||||
|
||||
#if defined(HAVE_ICONV)
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include "charset.h"
|
||||
|
||||
#undef HAVE_ICONV
|
||||
/*****************************************************************************
|
||||
* decoder_sys_t : decoder descriptor
|
||||
*****************************************************************************/
|
||||
struct decoder_sys_t
|
||||
{
|
||||
int i_align; /* Subtitles alignment on the vout */
|
||||
|
||||
#if defined(HAVE_ICONV)
|
||||
iconv_t iconv_handle; /* handle to iconv instance */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
static int OpenDecoder ( vlc_object_t * );
|
||||
|
||||
static int InitDecoder ( decoder_t * );
|
||||
static int RunDecoder ( decoder_t *, block_t * );
|
||||
static int EndDecoder ( decoder_t * );
|
||||
|
||||
static void ParseText ( decoder_t *, block_t *, vout_thread_t * );
|
||||
|
||||
#define DEFAULT_NAME "System Default"
|
||||
|
||||
/*****************************************************************************
|
||||
* Module descriptor.
|
||||
*****************************************************************************/
|
||||
#if defined(HAVE_ICONV)
|
||||
static char *ppsz_encodings[] = { DEFAULT_NAME, "ASCII", "UTF-8", "",
|
||||
"ISO-8859-1", "CP1252", "MacRoman", "MacIceland","ISO-8859-15", "",
|
||||
"ISO-8859-2", "CP1250", "MacCentralEurope", "MacCroatian", "MacRomania", "",
|
||||
"ISO-8859-5", "CP1251", "MacCyrillic", "MacUkraine", "KOI8-R", "KOI8-U", "KOI8-RU", "",
|
||||
"ISO-8859-6", "CP1256", "MacArabic", "",
|
||||
"ISO-8859-7", "CP1253", "MacGreek", "",
|
||||
"ISO-8859-8", "CP1255", "MacHebrew", "",
|
||||
"ISO-8859-9", "CP1254", "MacTurkish", "",
|
||||
"ISO-8859-13", "CP1257", "",
|
||||
"ISO-2022-JP", "ISO-2022-JP-1", "ISO-2022-JP-2", "EUC-JP", "SHIFT_JIS", "",
|
||||
"ISO-2022-CN", "ISO-2022-CN-EXT", "EUC-CN", "EUC-TW", "BIG5", "BIG5-HKSCS", "",
|
||||
"ISO-2022-KR", "EUC-KR", "",
|
||||
"MacThai", "KOI8-T", "",
|
||||
"ISO-8859-3", "ISO-8859-4", "ISO-8859-10", "ISO-8859-14", "ISO-8859-16", "",
|
||||
"CP850", "CP862", "CP866", "CP874", "CP932", "CP949", "CP950", "CP1133", "CP1258", "",
|
||||
"Macintosh", "",
|
||||
"UTF-7", "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", "",
|
||||
"HZ", "GBK", "GB18030", "JOHAB", "ARMSCII-8",
|
||||
"Georgian-Academy", "Georgian-PS", "TIS-620", "MuleLao-1", "VISCII", "TCVN",
|
||||
"HPROMAN8", "NEXTSTEP", NULL };
|
||||
#endif
|
||||
|
||||
#define ENCODING_TEXT N_("Subtitles text encoding")
|
||||
#define ENCODING_LONGTEXT N_("Change the encoding used in text subtitles")
|
||||
#define ALIGN_TEXT N_("Subtitles justification")
|
||||
#define ALIGN_LONGTEXT N_("Change the justification of substitles (0=center, 1=left, 2=right)")
|
||||
|
||||
vlc_module_begin();
|
||||
set_description( _("text subtitles decoder") );
|
||||
set_capability( "decoder", 50 );
|
||||
set_callbacks( OpenDecoder, NULL );
|
||||
|
||||
add_category_hint( N_("Subtitles"), NULL, VLC_FALSE );
|
||||
add_integer( "subsdec-align", 0, NULL, ALIGN_TEXT, ALIGN_LONGTEXT, VLC_TRUE );
|
||||
#if defined(HAVE_ICONV)
|
||||
add_string_from_list( "subsdec-encoding", DEFAULT_NAME, 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_t *p_dec = (decoder_t*)p_this;
|
||||
|
||||
if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
|
||||
{
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
p_dec->pf_init = InitDecoder;
|
||||
p_dec->pf_decode = RunDecoder;
|
||||
p_dec->pf_end = EndDecoder;
|
||||
|
||||
/* Allocate the memory needed to store the decoder's structure */
|
||||
if( ( p_dec->p_sys =
|
||||
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
|
||||
{
|
||||
msg_Err( p_dec, "out of memory" );
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* InitDecoder: Initalize the decoder
|
||||
*****************************************************************************/
|
||||
static int InitDecoder( decoder_t *p_dec )
|
||||
{
|
||||
decoder_sys_t *p_sys = p_dec->p_sys;
|
||||
vlc_value_t val;
|
||||
|
||||
var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
||||
var_Get( p_dec, "subsdec-align", &val );
|
||||
p_sys->i_align = val.i_int;
|
||||
|
||||
#if defined(HAVE_ICONV)
|
||||
var_Create( p_dec, "subsdec-encoding",
|
||||
VLC_VAR_STRING | VLC_VAR_DOINHERIT );
|
||||
var_Get( p_dec, "subsdec-encoding", &val );
|
||||
if( !strcmp( val.psz_string, DEFAULT_NAME ) )
|
||||
{
|
||||
char *psz_charset =(char*)malloc( 100 );
|
||||
vlc_current_charset( &psz_charset );
|
||||
p_sys->iconv_handle = iconv_open( "UTF-8", psz_charset );
|
||||
free( psz_charset );
|
||||
}
|
||||
else
|
||||
{
|
||||
p_sys->iconv_handle = iconv_open( "UTF-8", val.psz_string );
|
||||
}
|
||||
|
||||
if( p_sys->iconv_handle == (iconv_t)-1 )
|
||||
{
|
||||
msg_Warn( p_dec, "Unable to do requested conversion" );
|
||||
}
|
||||
|
||||
if( val.psz_string ) free( val.psz_string );
|
||||
#endif
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RunDecoder: the whole thing
|
||||
****************************************************************************
|
||||
* This function must be fed with complete subtitles units.
|
||||
****************************************************************************/
|
||||
static int RunDecoder( decoder_t *p_dec, block_t *p_block )
|
||||
{
|
||||
vout_thread_t *p_vout;
|
||||
|
||||
/* Here we are dealing with text subtitles */
|
||||
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
|
||||
if( !p_vout )
|
||||
{
|
||||
msg_Warn( p_dec, "couldn't find a video output, trashing subtitle" );
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
ParseText( p_dec, p_block, p_vout );
|
||||
vlc_object_release( p_vout );
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndDecoder: clean up the decoder
|
||||
*****************************************************************************/
|
||||
static int EndDecoder( decoder_t *p_dec )
|
||||
{
|
||||
decoder_sys_t *p_sys = p_dec->p_sys;
|
||||
vout_thread_t *p_vout;
|
||||
|
||||
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
|
||||
if( p_vout != NULL && 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_vout->p_subpicture[i_subpic];
|
||||
|
||||
if( p_subpic != NULL &&
|
||||
( p_subpic->i_status == RESERVED_SUBPICTURE
|
||||
|| p_subpic->i_status == READY_SUBPICTURE ) )
|
||||
{
|
||||
vout_DestroySubPicture( p_vout, p_subpic );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( p_vout ) vlc_object_release( p_vout );
|
||||
|
||||
#if defined(HAVE_ICONV)
|
||||
if( p_sys->iconv_handle != (iconv_t)-1 )
|
||||
{
|
||||
iconv_close( p_sys->iconv_handle );
|
||||
}
|
||||
#endif
|
||||
|
||||
free( p_sys );
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ParseText: parse an text subtitle packet and send it to the video output
|
||||
*****************************************************************************/
|
||||
static void ParseText( decoder_t *p_dec, block_t *p_block,
|
||||
vout_thread_t *p_vout )
|
||||
{
|
||||
decoder_sys_t *p_sys = p_dec->p_sys;
|
||||
char *psz_subtitle;
|
||||
|
||||
/* We cannot display a subpicture with no date */
|
||||
if( p_block->i_pts == 0 )
|
||||
{
|
||||
msg_Warn( p_dec, "subtitle without a date" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check validity of packet data */
|
||||
if( p_block->i_buffer <= 1 || p_block->p_buffer[0] == '\0' )
|
||||
{
|
||||
msg_Warn( p_dec, "empty subtitle" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Should be resiliant against bad subtitles */
|
||||
psz_subtitle = strndup( p_block->p_buffer, p_block->i_buffer );
|
||||
|
||||
#if defined(HAVE_ICONV)
|
||||
if( p_sys->iconv_handle != (iconv_t)-1 )
|
||||
{
|
||||
char *psz_new_subtitle;
|
||||
char *psz_convert_buffer_out, *psz_convert_buffer_in;
|
||||
size_t ret, inbytes_left, outbytes_left;
|
||||
|
||||
psz_new_subtitle = malloc( 6 * strlen( psz_subtitle ) );
|
||||
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_sys->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_dec, "Something fishy happened during conversion" );
|
||||
}
|
||||
else
|
||||
{
|
||||
free( psz_subtitle );
|
||||
psz_subtitle = psz_new_subtitle;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vout_ShowTextAbsolute( p_vout, psz_subtitle, NULL,
|
||||
OSD_ALIGN_BOTTOM | p_sys->i_align,
|
||||
p_sys->i_align ? 20 : 0, 10,
|
||||
p_block->i_pts, p_block->i_dts );
|
||||
|
||||
free( psz_subtitle );
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
.deps
|
||||
.dirstamp
|
||||
*.lo
|
||||
*.la
|
||||
*.dll
|
||||
*.dylib
|
||||
*.sl
|
||||
*.so
|
||||
Makefile.am
|
||||
Makefile.in
|
||||
Makefile
|
@ -1,4 +0,0 @@
|
||||
SOURCES_subsdec = \
|
||||
subsdec.c \
|
||||
subsdec.h \
|
||||
$(NULL)
|
@ -1,371 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* subsdec.c : SPU decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000-2001 VideoLAN
|
||||
* $Id: subsdec.c,v 1.10 2003/09/10 15:03:49 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"
|
||||
#include "charset.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[] = { N_("System Default"), "ASCII", "UTF-8", "",
|
||||
"ISO-8859-1", "CP1252", "MacRoman", "MacIceland","ISO-8859-15", "",
|
||||
"ISO-8859-2", "CP1250", "MacCentralEurope", "MacCroatian", "MacRomania", "",
|
||||
"ISO-8859-5", "CP1251", "MacCyrillic", "MacUkraine", "KOI8-R", "KOI8-U", "KOI8-RU", "",
|
||||
"ISO-8859-6", "CP1256", "MacArabic", "",
|
||||
"ISO-8859-7", "CP1253", "MacGreek", "",
|
||||
"ISO-8859-8", "CP1255", "MacHebrew", "",
|
||||
"ISO-8859-9", "CP1254", "MacTurkish", "",
|
||||
"ISO-8859-13", "CP1257", "",
|
||||
"ISO-2022-JP", "ISO-2022-JP-1", "ISO-2022-JP-2", "EUC-JP", "SHIFT_JIS", "",
|
||||
"ISO-2022-CN", "ISO-2022-CN-EXT", "EUC-CN", "EUC-TW", "BIG5", "BIG5-HKSCS", "",
|
||||
"ISO-2022-KR", "EUC-KR", "",
|
||||
"MacThai", "KOI8-T", "",
|
||||
"ISO-8859-3", "ISO-8859-4", "ISO-8859-10", "ISO-8859-14", "ISO-8859-16", "",
|
||||
"CP850", "CP862", "CP866", "CP874", "CP932", "CP949", "CP950", "CP1133", "CP1258", "",
|
||||
"Macintosh", "",
|
||||
"UTF-7", "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", "",
|
||||
"HZ", "GBK", "GB18030", "JOHAB", "ARMSCII-8",
|
||||
"Georgian-Academy", "Georgian-PS", "TIS-620", "MuleLao-1", "VISCII", "TCVN",
|
||||
"HPROMAN8", "NEXTSTEP", NULL };
|
||||
|
||||
#define ENCODING_TEXT N_("Subtitles text encoding")
|
||||
#define ENCODING_LONGTEXT N_("Change the encoding used in text subtitles")
|
||||
#define ALIGN_TEXT N_("Subtitles justification")
|
||||
#define ALIGN_LONGTEXT N_("Change the justification of substitles (0=center, 1=left, 2=right)")
|
||||
|
||||
vlc_module_begin();
|
||||
set_description( _("file subtitles decoder") );
|
||||
set_capability( "decoder", 50 );
|
||||
set_callbacks( OpenDecoder, NULL );
|
||||
add_category_hint( N_("Subtitles"), NULL, VLC_FALSE );
|
||||
|
||||
add_integer( "subsdec-align", 0, NULL, ALIGN_TEXT, ALIGN_LONGTEXT, VLC_TRUE );
|
||||
#if defined(HAVE_ICONV)
|
||||
add_string_from_list( "subsdec-encoding", N_("System Default"), 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_t *p_dec = (decoder_t*)p_this;
|
||||
|
||||
if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') )
|
||||
{
|
||||
return VLC_EGENERIC;
|
||||
}
|
||||
|
||||
p_dec->pf_run = RunDecoder;
|
||||
|
||||
var_Create( p_dec->p_fifo, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
||||
#if defined(HAVE_ICONV)
|
||||
var_Create( p_dec->p_fifo, "subsdec-encoding", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
|
||||
#endif
|
||||
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;
|
||||
vlc_value_t val;
|
||||
|
||||
/* 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
|
||||
var_Get( p_subsdec->p_fifo, "subsdec-align", &val );
|
||||
p_subsdec->i_align = val.i_int;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
var_Get( p_subsdec->p_fifo, "subsdec-encoding", &val );
|
||||
if( strcmp( val.psz_string, N_("System Default") ) == 0 )
|
||||
{
|
||||
char *psz_charset =(char*)malloc( 100 );
|
||||
vlc_current_charset(&psz_charset);
|
||||
p_subsdec->iconv_handle = iconv_open( "UTF-8", psz_charset );
|
||||
}
|
||||
else
|
||||
{
|
||||
p_subsdec->iconv_handle = iconv_open( "UTF-8", val.psz_string );
|
||||
}
|
||||
if( p_subsdec->iconv_handle == (iconv_t)-1 )
|
||||
{
|
||||
msg_Warn( p_subsdec->p_fifo, "Unable to do requested conversion" );
|
||||
}
|
||||
free( val.psz_string);
|
||||
#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
|
||||
{
|
||||
psz_subtitle = psz_new_subtitle;
|
||||
}
|
||||
#endif
|
||||
vout_ShowTextAbsolute( p_subsdec->p_vout, psz_subtitle, NULL,
|
||||
OSD_ALIGN_BOTTOM | p_subsdec->i_align,
|
||||
p_subsdec->i_align ? 20 : 0, 10,
|
||||
i_pts, i_dts );
|
||||
#if defined(HAVE_ICONV)
|
||||
free( psz_new_subtitle );
|
||||
#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 );
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
|
||||
/*****************************************************************************
|
||||
* subsdec.h : sub picture unit decoder thread interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: subsdec.h,v 1.2 2003/08/10 10:22:52 gbazin 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
|
||||
{
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
int i_align;
|
||||
#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 * );
|
||||
|
Loading…
Reference in New Issue
Block a user