X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fsubtitle.c;h=29a2e8e0b04f3c344c611d449db6fb8c8f8f9975;hb=0ade81b0ebaa94d8529e4784b460bc921be70f54;hp=309b5128c092b6742797a9332012ebca6889b5fd;hpb=8fd842248c7f18147213c404a6dc9e97174245a9;p=vlc diff --git a/modules/demux/subtitle.c b/modules/demux/subtitle.c index 309b5128c0..29a2e8e0b0 100644 --- a/modules/demux/subtitle.c +++ b/modules/demux/subtitle.c @@ -19,7 +19,7 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -44,22 +44,24 @@ static int Open ( vlc_object_t *p_this ); static void Close( vlc_object_t *p_this ); #define SUB_DELAY_LONGTEXT \ - "Delay subtitles (in 1/10s)" + "Apply a delay to all subtitles (in 1/10s, eg 100 means 10s)." #define SUB_FPS_LONGTEXT \ - "Override frames per second. " \ - "It will only work with MicroDVD subtitles." + "Override the normal frames per second settings. " \ + "This will only work with MicroDVD and SubRIP (SRT) subtitles." #define SUB_TYPE_LONGTEXT \ - "One from \"microdvd\", \"subrip\", \"ssa1\", \"ssa2-4\", \"ass\", \"vplayer\" " \ - "\"sami\" (auto for autodetection, it should always work)." + "Force the subtiles format. Valid values are : \"microdvd\", \"subrip\"," \ + "\"ssa1\", \"ssa2-4\", \"ass\", \"vplayer\" " \ + "\"sami\", \"dvdsubtitle\" and \"auto\" (meaning autodetection, this " \ + "should always work)." static char *ppsz_sub_type[] = { "auto", "microdvd", "subrip", "subviewer", "ssa1", - "ssa2-4", "ass", "vplayer", "sami" + "ssa2-4", "ass", "vplayer", "sami", "dvdsubtitle" }; vlc_module_begin(); set_shortname( _("Subtitles")); - set_description( _("Text subtitles demux") ); + set_description( _("Text subtitles parser") ); set_capability( "demux2", 0 ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_DEMUX ); @@ -69,7 +71,7 @@ vlc_module_begin(); add_integer( "sub-delay", 0, NULL, N_("Subtitles delay"), SUB_DELAY_LONGTEXT, VLC_TRUE ); - add_string( "sub-type", "auto", NULL, "Subtitles fileformat", + add_string( "sub-type", "auto", NULL, N_("Subtitles format"), SUB_TYPE_LONGTEXT, VLC_TRUE ); change_string_list( ppsz_sub_type, 0, 0 ); set_callbacks( Open, Close ); @@ -91,6 +93,7 @@ enum SUB_TYPE_VPLAYER, SUB_TYPE_SAMI, SUB_TYPE_SUBVIEWER, + SUB_TYPE_DVDSUBTITLE }; typedef struct @@ -130,12 +133,13 @@ struct demux_sys_t int64_t i_length; }; -static int ParseMicroDvd ( demux_t *, subtitle_t * ); -static int ParseSubRip ( demux_t *, subtitle_t * ); -static int ParseSubViewer( demux_t *, subtitle_t * ); -static int ParseSSA ( demux_t *, subtitle_t * ); -static int ParseVplayer ( demux_t *, subtitle_t * ); -static int ParseSami ( demux_t *, subtitle_t * ); +static int ParseMicroDvd ( demux_t *, subtitle_t * ); +static int ParseSubRip ( demux_t *, subtitle_t * ); +static int ParseSubViewer ( demux_t *, subtitle_t * ); +static int ParseSSA ( demux_t *, subtitle_t * ); +static int ParseVplayer ( demux_t *, subtitle_t * ); +static int ParseSami ( demux_t *, subtitle_t * ); +static int ParseDVDSubtitle( demux_t *, subtitle_t * ); static struct { @@ -145,15 +149,16 @@ static struct int (*pf_read)( demux_t *, subtitle_t* ); } sub_read_subtitle_function [] = { - { "microdvd", SUB_TYPE_MICRODVD, "MicroDVD", ParseMicroDvd }, - { "subrip", SUB_TYPE_SUBRIP, "SubRIP", ParseSubRip }, - { "subviewer", SUB_TYPE_SUBVIEWER, "SubViewer",ParseSubViewer }, - { "ssa1", SUB_TYPE_SSA1, "SSA-1", ParseSSA }, - { "ssa2-4", SUB_TYPE_SSA2_4, "SSA-2/3/4",ParseSSA }, - { "ass", SUB_TYPE_ASS, "SSA/ASS", ParseSSA }, - { "vplayer", SUB_TYPE_VPLAYER, "VPlayer", ParseVplayer }, - { "sami", SUB_TYPE_SAMI, "SAMI", ParseSami }, - { NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL } + { "microdvd", SUB_TYPE_MICRODVD, "MicroDVD", ParseMicroDvd }, + { "subrip", SUB_TYPE_SUBRIP, "SubRIP", ParseSubRip }, + { "subviewer", SUB_TYPE_SUBVIEWER, "SubViewer", ParseSubViewer }, + { "ssa1", SUB_TYPE_SSA1, "SSA-1", ParseSSA }, + { "ssa2-4", SUB_TYPE_SSA2_4, "SSA-2/3/4", ParseSSA }, + { "ass", SUB_TYPE_ASS, "SSA/ASS", ParseSSA }, + { "vplayer", SUB_TYPE_VPLAYER, "VPlayer", ParseVplayer }, + { "sami", SUB_TYPE_SAMI, "SAMI", ParseSami }, + { "dvdsubtitle",SUB_TYPE_DVDSUBTITLE, "DVDSubtitle", ParseDVDSubtitle }, + { NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL } }; static int Demux( demux_t * ); @@ -301,6 +306,12 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_type = SUB_TYPE_VPLAYER; break; } + else if( sscanf( s, "{T %d:%d:%d:%d", &i_dummy, &i_dummy, + &i_dummy, &i_dummy ) == 4 ) + { + p_sys->i_type = SUB_TYPE_DVDSUBTITLE; + break; + } free( s ); s = NULL; @@ -633,7 +644,7 @@ static int TextLoad( text_t *txt, stream_t *s ) if( txt->i_line_count >= i_line_max ) { i_line_max += 100; - txt->line = realloc( txt->line, i_line_max * sizeof( char*) ); + txt->line = realloc( txt->line, i_line_max * sizeof( char * ) ); } } @@ -693,9 +704,9 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle ) unsigned int i; int i_microsecperframe = 40000; /* default to 25 fps */ - if( p_sys->i_microsecperframe > 0 ) + if( p_sys->i_microsecperframe > 0 ) i_microsecperframe = p_sys->i_microsecperframe; - + p_subtitle->i_start = 0; p_subtitle->i_stop = 0; p_subtitle->psz_text = NULL; @@ -996,12 +1007,12 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) if( p_sys->psz_header != NULL ) { if( !( p_sys->psz_header = realloc( p_sys->psz_header, - strlen( p_sys->psz_header ) + strlen( s ) + 2 ) ) ) + strlen( p_sys->psz_header ) + 1 + strlen( s ) + 2 ) ) ) { msg_Err( p_demux, "out of memory"); return VLC_ENOMEM; } - p_sys->psz_header = strcat( p_sys->psz_header, strdup( s ) ); + p_sys->psz_header = strcat( p_sys->psz_header, s ); p_sys->psz_header = strcat( p_sys->psz_header, "\n" ); } else @@ -1011,7 +1022,7 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) msg_Err( p_demux, "out of memory"); return VLC_ENOMEM; } - p_sys->psz_header = strdup( s ); + p_sys->psz_header = s; p_sys->psz_header = strcat( p_sys->psz_header, "\n" ); } } @@ -1203,3 +1214,79 @@ static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle ) return( VLC_SUCCESS ); #undef ADDC } + +static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle ) +{ + demux_sys_t *p_sys = p_demux->p_sys; + text_t *txt = &p_sys->txt; + + /* + * {T h1:m1:s1:c1 + * Line1 + * Line2 + * ... + * } + * + */ + char *s; + char buffer_text[ 10 * MAX_LINE]; + int i_buffer_text; + int64_t i_start; + + p_subtitle->i_start = 0; + p_subtitle->i_stop = 0; + p_subtitle->psz_text = NULL; + + for( ;; ) + { + int h1, m1, s1, c1; + if( ( s = TextGetLine( txt ) ) == NULL ) + { + return( VLC_EGENERIC ); + } + if( sscanf( s, + "{T %d:%d:%d:%d", + &h1, &m1, &s1, &c1 ) == 4 ) + { + i_start = ( (int64_t)h1 * 3600*1000 + + (int64_t)m1 * 60*1000 + + (int64_t)s1 * 1000 + + (int64_t)c1 * 10) * 1000; + + /* Now read text until a line containing "}" */ + for( i_buffer_text = 0;; ) + { + int i_len; + if( ( s = TextGetLine( txt ) ) == NULL ) + { + return( VLC_EGENERIC ); + } + + i_len = strlen( s ); + if( i_len == 1 && s[0] == '}' ) + { + /* "}" -> end of this subtitle */ + buffer_text[__MAX( i_buffer_text - 1, 0 )] = '\0'; + p_subtitle->i_start = i_start; + p_subtitle->i_stop = 0; + p_subtitle->psz_text = strdup( buffer_text ); + return 0; + } + else + { + if( i_buffer_text + i_len + 1 < 10 * MAX_LINE ) + { + memcpy( buffer_text + i_buffer_text, + s, + i_len ); + i_buffer_text += i_len; + + buffer_text[i_buffer_text] = '\n'; + i_buffer_text++; + } + } + } + } + } +} +