/***************************************************************************** * 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; decoder_sys_t *p_sys; vlc_value_t val; if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','u','b','t') && p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') ) { return VLC_EGENERIC; } p_dec->pf_decode_sub = DecodeBlock; /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) { msg_Err( p_dec, "out of memory" ); return VLC_ENOMEM; } /* init of p_sys */ p_sys->i_align = 0; p_sys->iconv_handle = (vlc_iconv_t)-1; p_sys->b_autodetect_utf8 = VLC_FALSE; p_sys->b_ass = VLC_FALSE; p_sys->i_original_height = -1; p_sys->i_original_width = -1; p_sys->pp_ssa_styles = NULL; p_sys->i_ssa_styles = 0; if( p_dec->fmt_in.subs.psz_encoding && *p_dec->fmt_in.subs.psz_encoding ) { msg_Dbg( p_dec, "using demux suggested character encoding: %s", p_dec->fmt_in.subs.psz_encoding ); if( strcmp( p_dec->fmt_in.subs.psz_encoding, "UTF-8" ) ) p_sys->iconv_handle = vlc_iconv_open( "UTF-8", p_dec->fmt_in.subs.psz_encoding ); } else { 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 ) ) { const char *psz_charset = GetFallbackEncoding(); p_sys->b_autodetect_utf8 = var_CreateGetBool( p_dec, "subsdec-autodetect-utf8" ); p_sys->iconv_handle = vlc_iconv_open( "UTF-8", psz_charset ); msg_Dbg( p_dec, "using fallback character encoding: %s", psz_charset ); } else if( !strcmp( val.psz_string, "UTF-8" ) ) { msg_Dbg( p_dec, "using enforced character encoding: UTF-8" ); } else if( val.psz_string ) { msg_Dbg( p_dec, "using enforced character encoding: %s", val.psz_string ); p_sys->iconv_handle = vlc_iconv_open( "UTF-8", val.psz_string ); if( p_sys->iconv_handle == (vlc_iconv_t)-1 ) { msg_Warn( p_dec, "unable to do requested conversion" ); } } if( val.psz_string ) free( val.psz_string ); } 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( p_dec->fmt_in.i_codec == VLC_FOURCC('s','s','a',' ') && var_CreateGetBool( p_dec, "subsdec-formatted" ) ) { if( p_dec->fmt_in.i_extra > 0 ) ParseSSAHeader( p_dec ); } return VLC_SUCCESS; }
/***************************************************************************** * 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; decoder_sys_t *p_sys; switch( p_dec->fmt_in.i_codec ) { case VLC_CODEC_SUBT: case VLC_CODEC_SSA: case VLC_CODEC_ITU_T140: break; default: return VLC_EGENERIC; } p_dec->pf_decode_sub = DecodeBlock; p_dec->fmt_out.i_cat = SPU_ES; p_dec->fmt_out.i_codec = 0; /* Allocate the memory needed to store the decoder's structure */ p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) ); if( p_sys == NULL ) return VLC_ENOMEM; /* init of p_sys */ p_sys->i_align = 0; p_sys->iconv_handle = (vlc_iconv_t)-1; p_sys->b_autodetect_utf8 = false; p_sys->b_ass = false; p_sys->i_original_height = -1; p_sys->i_original_width = -1; TAB_INIT( p_sys->i_ssa_styles, p_sys->pp_ssa_styles ); TAB_INIT( p_sys->i_images, p_sys->pp_images ); char *psz_charset = NULL; /* First try demux-specified encoding */ if( p_dec->fmt_in.i_codec == VLC_CODEC_ITU_T140 ) psz_charset = strdup( "UTF-8" ); /* IUT T.140 is always using UTF-8 */ else if( p_dec->fmt_in.subs.psz_encoding && *p_dec->fmt_in.subs.psz_encoding ) { psz_charset = strdup (p_dec->fmt_in.subs.psz_encoding); msg_Dbg (p_dec, "trying demuxer-specified character encoding: %s", p_dec->fmt_in.subs.psz_encoding ? p_dec->fmt_in.subs.psz_encoding : "not specified"); } /* Second, try configured encoding */ if (psz_charset == NULL) { psz_charset = var_InheritString (p_dec, "subsdec-encoding"); msg_Dbg (p_dec, "trying configured character encoding: %s", psz_charset ? psz_charset : "not specified"); if (psz_charset != NULL && !strcmp (psz_charset, "system")) { free (psz_charset); psz_charset = strdup (""); /* ^ iconv() treats "" as nl_langinfo(CODESET) */ } } /* Third, try "local" encoding with optional UTF-8 autodetection */ if (psz_charset == NULL) { /* xgettext: The Windows ANSI code page most commonly used for this language. VLC uses this as a guess of the subtitle files character set (if UTF-8 and UTF-16 autodetection fails). Western European languages normally use "CP1252", which is a Microsoft-variant of ISO 8859-1. That suits the Latin alphabet. Other scripts use other code pages. This MUST be a valid iconv character set. If unsure, please refer the VideoLAN translators mailing list. */ const char *acp = vlc_pgettext("GetACP", "CP1252"); psz_charset = strdup (acp); msg_Dbg (p_dec, "trying default character encoding: %s", psz_charset ? psz_charset : "not specified"); if (var_InheritBool (p_dec, "subsdec-autodetect-utf8")) { msg_Dbg (p_dec, "using automatic UTF-8 detection"); p_sys->b_autodetect_utf8 = true; } } /* Forth, don't do character decoding, i.e. assume UTF-8 */ if (psz_charset == NULL) { psz_charset = strdup ("UTF-8"); msg_Dbg (p_dec, "using UTF-8 character encoding" ); } if ((psz_charset != NULL) && strcasecmp (psz_charset, "UTF-8") && strcasecmp (psz_charset, "utf8")) { p_sys->iconv_handle = vlc_iconv_open ("UTF-8", psz_charset); if (p_sys->iconv_handle == (vlc_iconv_t)(-1)) msg_Err (p_dec, "cannot convert from %s: %m", psz_charset); } free (psz_charset); p_sys->i_align = var_InheritInteger( p_dec, "subsdec-align" ); if( p_dec->fmt_in.i_codec == VLC_CODEC_SSA && var_InheritBool( p_dec, "subsdec-formatted" ) ) { if( p_dec->fmt_in.i_extra > 0 ) ParseSSAHeader( p_dec ); } return VLC_SUCCESS; }