X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fsubtitle.c;h=6a5c9383e64cd17a1d30cabf207c91c497e2422f;hb=08be58ddca5bfc5dbba58928f936934d6350426b;hp=20572f5e4243444674664e2475d160e41ce3dffd;hpb=d8f026b7dfcfb750fd873bef178f04ba7fd40ddf;p=vlc diff --git a/modules/demux/subtitle.c b/modules/demux/subtitle.c index 20572f5e42..6a5c9383e6 100644 --- a/modules/demux/subtitle.c +++ b/modules/demux/subtitle.c @@ -1,7 +1,7 @@ /***************************************************************************** - * subtitle.c: Demux for text and vobsub files. + * subtitle.c: Demux for subtitle text files. ***************************************************************************** - * Copyright (C) 1999-2004 VideoLAN + * Copyright (C) 1999-2004 the VideoLAN team * $Id$ * * Authors: Laurent Aimar @@ -28,19 +28,15 @@ #include #include -#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif #include #include #include #include "vlc_video.h" -#include "ps.h" - -#if (!defined( WIN32 ) || defined(__MINGW32__)) -# include -#endif - /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -53,27 +49,32 @@ static void Close( vlc_object_t *p_this ); "Override frames per second. " \ "It will only work with MicroDVD subtitles." #define SUB_TYPE_LONGTEXT \ - "One from \"microdvd\", \"subrip\", \"ssa1\", \"ssa2-4\", \"vplayer\" " \ + "One from \"microdvd\", \"subrip\", \"ssa1\", \"ssa2-4\", \"ass\", \"vplayer\" " \ "\"sami\" (auto for autodetection, it should always work)." static char *ppsz_sub_type[] = { "auto", "microdvd", "subrip", "subviewer", "ssa1", - "ssa2-4", "vplayer", "sami", "vobsub" + "ssa2-4", "ass", "vplayer", "sami" }; vlc_module_begin(); + set_shortname( _("Subtitles")); set_description( _("Text subtitles demux") ); set_capability( "demux2", 0 ); + set_category( CAT_INPUT ); + set_subcategory( SUBCAT_INPUT_DEMUX ); add_float( "sub-fps", 0.0, NULL, N_("Frames per second"), SUB_FPS_LONGTEXT, VLC_TRUE ); + add_integer( "sub-delay", 0, NULL, + N_("Subtitles delay"), + SUB_DELAY_LONGTEXT, VLC_TRUE ); add_string( "sub-type", "auto", NULL, "Subtitles fileformat", SUB_TYPE_LONGTEXT, VLC_TRUE ); change_string_list( ppsz_sub_type, 0, 0 ); set_callbacks( Open, Close ); add_shortcut( "subtitle" ); - add_shortcut( "vobsub" ); vlc_module_end(); /***************************************************************************** @@ -86,10 +87,10 @@ enum SUB_TYPE_SUBRIP, SUB_TYPE_SSA1, SUB_TYPE_SSA2_4, + SUB_TYPE_ASS, SUB_TYPE_VPLAYER, SUB_TYPE_SAMI, SUB_TYPE_SUBVIEWER, - SUB_TYPE_VOBSUB, }; typedef struct @@ -103,11 +104,10 @@ static void TextUnload( text_t * ); typedef struct { - mtime_t i_start; - mtime_t i_stop; + int64_t i_start; + int64_t i_stop; char *psz_text; - int i_vobsub_location; } subtitle_t; @@ -120,13 +120,12 @@ struct demux_sys_t int64_t i_next_demux_date; int64_t i_microsecperframe; + int64_t i_original_mspf; char *psz_header; int i_subtitle; int i_subtitles; subtitle_t *subtitle; - FILE *p_vobsub_file; - mtime_t i_original_mspf; int64_t i_length; }; @@ -137,9 +136,6 @@ 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 ParseVobSubIDX( demux_t *, subtitle_t * ); - -static int DemuxVobSub( demux_t *, block_t * ); static struct { @@ -154,18 +150,16 @@ static struct { "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 }, - { "vobsub", SUB_TYPE_VOBSUB, "VobSub", ParseVobSubIDX }, { NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL } }; static int Demux( demux_t * ); static int Control( demux_t *, int, va_list ); -static void Fix( demux_t * ); - -#define DVD_VIDEO_LB_LEN 2048 +/*static void Fix( demux_t * );*/ /***************************************************************************** * Module initializer @@ -180,8 +174,7 @@ static int Open ( vlc_object_t *p_this ) int (*pf_read)( demux_t *, subtitle_t* ); int i, i_max; - if( strcmp( p_demux->psz_demux, "subtitle" ) && - strcmp( p_demux->psz_demux, "vobsub" ) ) + if( strcmp( p_demux->psz_demux, "subtitle" ) ) { msg_Dbg( p_demux, "subtitle demux discarded" ); return VLC_EGENERIC; @@ -194,16 +187,27 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_subtitle = 0; p_sys->i_subtitles= 0; p_sys->subtitle = NULL; - p_sys->p_vobsub_file = NULL; - p_sys->i_original_mspf = 0; /* Get the FPS */ - p_sys->i_microsecperframe = 40000; /* default to 25 fps */ f_fps = var_CreateGetFloat( p_demux, "sub-fps" ); if( f_fps >= 1.0 ) { - p_sys->i_microsecperframe = (mtime_t)( (float)1000000 / f_fps ); + p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps ); + } + else + { + p_sys->i_microsecperframe = 0; + } + + f_fps = var_CreateGetFloat( p_demux, "sub-original-fps" ); + if( f_fps >= 1.0 ) + { + p_sys->i_original_mspf = (int64_t)( (float)1000000 / f_fps ); + } + else + { + p_sys->i_original_mspf = 0; } /* Get or probe the type */ @@ -261,28 +265,29 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_type = SUB_TYPE_SUBRIP; break; } - else if( sscanf( s, - "!: This is a Sub Station Alpha v%d.x script.", - &i_dummy ) == 1) + else if( !strncasecmp( s, "!: This is a Sub Station Alpha v1", 33 ) ) { - if( i_dummy <= 1 ) - { - p_sys->i_type = SUB_TYPE_SSA1; - } - else - { - p_sys->i_type = SUB_TYPE_SSA2_4; /* I hope this will work */ - } + p_sys->i_type = SUB_TYPE_SSA1; + break; + } + else if( !strncasecmp( s, "ScriptType: v4.00+", 18 ) ) + { + p_sys->i_type = SUB_TYPE_ASS; break; } - else if( strcasestr( s, "This is a Sub Station Alpha v4 script" ) ) + else if( !strncasecmp( s, "ScriptType: v4.00", 17 ) ) { - p_sys->i_type = SUB_TYPE_SSA2_4; /* I hope this will work */ + p_sys->i_type = SUB_TYPE_SSA2_4; break; } else if( !strncasecmp( s, "Dialogue: Marked", 16 ) ) { - p_sys->i_type = SUB_TYPE_SSA2_4; /* could be wrong */ + p_sys->i_type = SUB_TYPE_SSA2_4; + break; + } + else if( !strncasecmp( s, "Dialogue:", 9 ) ) + { + p_sys->i_type = SUB_TYPE_ASS; break; } else if( strcasestr( s, "[INFORMATION]" ) ) @@ -296,11 +301,6 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_type = SUB_TYPE_VPLAYER; break; } - else if( strcasestr( s, "# VobSub index file" ) ) - { - p_sys->i_type = SUB_TYPE_VOBSUB; - break; - } free( s ); s = NULL; @@ -318,6 +318,7 @@ static int Open ( vlc_object_t *p_this ) if( p_sys->i_type == SUB_TYPE_UNKNOWN ) { msg_Err( p_demux, "failed to recognize subtitle type" ); + free( p_sys ); return VLC_EGENERIC; } @@ -347,6 +348,10 @@ static int Open ( vlc_object_t *p_this ) sizeof(subtitle_t) * i_max ) ) ) { msg_Err( p_demux, "out of memory"); + if( p_sys->subtitle != NULL ) + free( p_sys->subtitle ); + TextUnload( &p_sys->txt ); + free( p_sys ); return VLC_ENOMEM; } } @@ -363,10 +368,6 @@ static int Open ( vlc_object_t *p_this ) /* Fix subtitle (order and time) *** */ p_sys->i_subtitle = 0; - if( p_sys->i_type != SUB_TYPE_VOBSUB ) - { - Fix( p_demux ); - } p_sys->i_length = 0; if( p_sys->i_subtitles > 0 ) { @@ -377,25 +378,9 @@ static int Open ( vlc_object_t *p_this ) } /* *** add subtitle ES *** */ - if( p_sys->i_type == SUB_TYPE_VOBSUB ) - { - int i_len = strlen( p_demux->psz_path ); - char *psz_vobname = strdup( p_demux->psz_path ); - - strcpy( psz_vobname + i_len - 4, ".sub" ); - - /* open file */ - if( !( p_sys->p_vobsub_file = fopen( psz_vobname, "rb" ) ) ) - { - msg_Err( p_demux, "couldn't open .sub Vobsub file: %s", - psz_vobname ); - } - free( psz_vobname ); - - es_format_Init( &fmt, SPU_ES, VLC_FOURCC( 's','p','u',' ' ) ); - } - else if( p_sys->i_type == SUB_TYPE_SSA1 || - p_sys->i_type == SUB_TYPE_SSA2_4 ) + if( p_sys->i_type == SUB_TYPE_SSA1 || + p_sys->i_type == SUB_TYPE_SSA2_4 || + p_sys->i_type == SUB_TYPE_ASS ) { es_format_Init( &fmt, SPU_ES, VLC_FOURCC( 's','s','a',' ' ) ); } @@ -430,9 +415,6 @@ static void Close( vlc_object_t *p_this ) if( p_sys->subtitle ) free( p_sys->subtitle ); - if( p_sys->p_vobsub_file ) - fclose( p_sys->p_vobsub_file ); - free( p_sys ); } @@ -531,111 +513,57 @@ static int Demux( demux_t *p_demux ) if( p_sys->i_subtitle >= p_sys->i_subtitles ) return 0; - i_maxdate = p_sys->i_next_demux_date; + i_maxdate = p_sys->i_next_demux_date - var_GetTime( p_demux->p_parent, "spu-delay" );; if( i_maxdate <= 0 && p_sys->i_subtitle < p_sys->i_subtitles ) { /* Should not happen */ i_maxdate = p_sys->subtitle[p_sys->i_subtitle].i_start + 1; } - if( p_sys->i_type != SUB_TYPE_VOBSUB ) + while( p_sys->i_subtitle < p_sys->i_subtitles && + p_sys->subtitle[p_sys->i_subtitle].i_start < i_maxdate ) { - while( p_sys->i_subtitle < p_sys->i_subtitles && - p_sys->subtitle[p_sys->i_subtitle].i_start < i_maxdate ) - { - block_t *p_block; - int i_len = strlen( p_sys->subtitle[p_sys->i_subtitle].psz_text ) + 1; + block_t *p_block; + int i_len = strlen( p_sys->subtitle[p_sys->i_subtitle].psz_text ) + 1; - if( i_len <= 1 ) - { - /* empty subtitle */ - p_sys->i_subtitle++; - continue; - } - - if( ( p_block = block_New( p_demux, i_len ) ) == NULL ) - { - p_sys->i_subtitle++; - continue; - } - - if( p_sys->subtitle[p_sys->i_subtitle].i_start < 0 ) - { - p_sys->i_subtitle++; - continue; - } - - p_block->i_pts = p_sys->subtitle[p_sys->i_subtitle].i_start; - p_block->i_dts = p_block->i_pts; - if( p_sys->subtitle[p_sys->i_subtitle].i_stop > 0 ) - { - p_block->i_length = - p_sys->subtitle[p_sys->i_subtitle].i_stop - p_block->i_pts; - } - - memcpy( p_block->p_buffer, - p_sys->subtitle[p_sys->i_subtitle].psz_text, i_len ); - if( p_block->i_pts > 0 ) - { - es_out_Send( p_demux->out, p_sys->es, p_block ); - } - else - { - block_Release( p_block ); - } + if( i_len <= 1 ) + { + /* empty subtitle */ p_sys->i_subtitle++; + continue; } - } - else - { - while( p_sys->i_subtitle < p_sys->i_subtitles && - p_sys->subtitle[p_sys->i_subtitle].i_start < i_maxdate ) - { - int i_pos = p_sys->subtitle[p_sys->i_subtitle].i_vobsub_location; - block_t *p_block; - int i_size = 0; - - /* first compute SPU size */ - if( p_sys->i_subtitle + 1 < p_sys->i_subtitles ) - { - i_size = p_sys->subtitle[p_sys->i_subtitle+1].i_vobsub_location - i_pos; - } - if( i_size <= 0 ) i_size = 65535; /* Invalid or EOF */ - - /* Seek at the right place */ - if( fseek( p_sys->p_vobsub_file, i_pos, SEEK_SET ) ) - { - msg_Warn( p_demux, - "cannot seek at right vobsub location %d", i_pos ); - p_sys->i_subtitle++; - continue; - } - - /* allocate a packet */ - if( ( p_block = block_New( p_demux, i_size ) ) == NULL ) - { - p_sys->i_subtitle++; - continue; - } - /* read data */ - p_block->i_buffer = fread( p_block->p_buffer, 1, i_size, - p_sys->p_vobsub_file ); - if( p_block->i_buffer <= 6 ) - { - block_Release( p_block ); - p_sys->i_subtitle++; - continue; - } + if( ( p_block = block_New( p_demux, i_len ) ) == NULL ) + { + p_sys->i_subtitle++; + continue; + } - /* pts */ - p_block->i_pts = p_sys->subtitle[p_sys->i_subtitle].i_start; + if( p_sys->subtitle[p_sys->i_subtitle].i_start < 0 ) + { + p_sys->i_subtitle++; + continue; + } - /* demux this block */ - DemuxVobSub( p_demux, p_block ); + p_block->i_pts = p_sys->subtitle[p_sys->i_subtitle].i_start; + p_block->i_dts = p_block->i_pts; + if( p_sys->subtitle[p_sys->i_subtitle].i_stop > 0 ) + { + p_block->i_length = + p_sys->subtitle[p_sys->i_subtitle].i_stop - p_block->i_pts; + } - p_sys->i_subtitle++; + memcpy( p_block->p_buffer, + p_sys->subtitle[p_sys->i_subtitle].psz_text, i_len ); + if( p_block->i_pts > 0 ) + { + es_out_Send( p_demux->out, p_sys->es, p_block ); } + else + { + block_Release( p_block ); + } + p_sys->i_subtitle++; } /* */ @@ -647,6 +575,7 @@ static int Demux( demux_t *p_demux ) /***************************************************************************** * Fix: fix time stamp and order of subtitle *****************************************************************************/ +#ifdef USE_THIS_UNUSED_PIECE_OF_CODE static void Fix( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; @@ -680,6 +609,7 @@ static void Fix( demux_t *p_demux ) } } while( !b_done ); } +#endif static int TextLoad( text_t *txt, stream_t *s ) { @@ -703,7 +633,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 * ) ); } } @@ -753,18 +683,21 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle ) * each line: * {n1}{n2}Line1|Line2|Line3.... * where n1 and n2 are the video frame number... - * + * {n2} can also be {} */ char *s; char buffer_text[MAX_LINE + 1]; - unsigned int i_start; - unsigned int i_stop; + int i_start; + int i_stop; unsigned int i; + int i_microsecperframe = 40000; /* default to 25 fps */ + if( p_sys->i_microsecperframe > 0 ) + i_microsecperframe = p_sys->i_microsecperframe; + p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) @@ -792,8 +725,8 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle ) } } - p_subtitle->i_start = (mtime_t)i_start * p_sys->i_microsecperframe; - p_subtitle->i_stop = (mtime_t)i_stop * p_sys->i_microsecperframe; + p_subtitle->i_start = (int64_t)i_start * i_microsecperframe; + p_subtitle->i_stop = (int64_t)i_stop * i_microsecperframe; p_subtitle->psz_text = strndup( buffer_text, MAX_LINE ); return( 0 ); } @@ -815,12 +748,11 @@ static int ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle ) char *s; char buffer_text[ 10 * MAX_LINE]; int i_buffer_text; - mtime_t i_start; - mtime_t i_stop; + int64_t i_start; + int64_t i_stop; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) @@ -835,15 +767,15 @@ static int ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle ) &h1, &m1, &s1, &d1, &h2, &m2, &s2, &d2 ) == 8 ) { - i_start = ( (mtime_t)h1 * 3600*1000 + - (mtime_t)m1 * 60*1000 + - (mtime_t)s1 * 1000 + - (mtime_t)d1 ) * 1000; + i_start = ( (int64_t)h1 * 3600*1000 + + (int64_t)m1 * 60*1000 + + (int64_t)s1 * 1000 + + (int64_t)d1 ) * 1000; - i_stop = ( (mtime_t)h2 * 3600*1000 + - (mtime_t)m2 * 60*1000 + - (mtime_t)s2 * 1000 + - (mtime_t)d2 ) * 1000; + i_stop = ( (int64_t)h2 * 3600*1000 + + (int64_t)m2 * 60*1000 + + (int64_t)s2 * 1000 + + (int64_t)d2 ) * 1000; /* Now read text until an empty line */ for( i_buffer_text = 0;; ) @@ -855,7 +787,7 @@ static int ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle ) } i_len = strlen( s ); - if( i_len <= 1 ) + if( i_len <= 0 ) { /* empty line -> end of this subtitle */ buffer_text[__MAX( i_buffer_text - 1, 0 )] = '\0'; @@ -866,12 +798,12 @@ static int ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle ) if( p_sys->i_microsecperframe != 0 && p_sys->i_original_mspf != 0) { - p_subtitle->i_start = (mtime_t)i_start * - p_sys->i_original_mspf / - p_sys->i_microsecperframe; - p_subtitle->i_stop = (mtime_t)i_stop * - p_sys->i_original_mspf / - p_sys->i_microsecperframe; + p_subtitle->i_start = (int64_t)i_start * + p_sys->i_microsecperframe/ + p_sys->i_original_mspf; + p_subtitle->i_stop = (int64_t)i_stop * + p_sys->i_microsecperframe / + p_sys->i_original_mspf; } return 0; } @@ -909,12 +841,11 @@ static int ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle ) char *s; char buffer_text[ 10 * MAX_LINE]; int i_buffer_text; - mtime_t i_start; - mtime_t i_stop; + int64_t i_start; + int64_t i_stop; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) @@ -929,15 +860,15 @@ static int ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle ) &h1, &m1, &s1, &d1, &h2, &m2, &s2, &d2 ) == 8 ) { - i_start = ( (mtime_t)h1 * 3600*1000 + - (mtime_t)m1 * 60*1000 + - (mtime_t)s1 * 1000 + - (mtime_t)d1 ) * 1000; + i_start = ( (int64_t)h1 * 3600*1000 + + (int64_t)m1 * 60*1000 + + (int64_t)s1 * 1000 + + (int64_t)d1 ) * 1000; - i_stop = ( (mtime_t)h2 * 3600*1000 + - (mtime_t)m2 * 60*1000 + - (mtime_t)s2 * 1000 + - (mtime_t)d2 ) * 1000; + i_stop = ( (int64_t)h2 * 3600*1000 + + (int64_t)m2 * 60*1000 + + (int64_t)s2 * 1000 + + (int64_t)d2 ) * 1000; /* Now read text until an empty line */ for( i_buffer_text = 0;; ) @@ -949,7 +880,7 @@ static int ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle ) } i_len = strlen( s ); - if( i_len <= 1 ) + if( i_len <= 0 ) { /* empty line -> end of this subtitle */ buffer_text[__MAX( i_buffer_text - 1, 0 )] = '\0'; @@ -957,14 +888,15 @@ static int ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle ) p_subtitle->i_stop = i_stop; /* replace [br] by \n */ - for( i = 0; i < strlen( buffer_text ) - 3; i++ ) + for( i = 0; i < i_buffer_text - 3; i++ ) { if( buffer_text[i] == '[' && buffer_text[i+1] == 'b' && buffer_text[i+2] == 'r' && buffer_text[i+3] == ']' ) { char *temp = buffer_text + i + 1; buffer_text[i] = '\n'; - memmove( temp, temp+3, strlen( temp-3 )); + memmove( temp, temp+3, strlen( temp ) -3 ); + temp[strlen( temp )-3] = '\0'; } } p_subtitle->psz_text = strdup( buffer_text ); @@ -995,19 +927,18 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) text_t *txt = &p_sys->txt; char buffer_text[ 10 * MAX_LINE]; + char buffer_text2[ 10 * MAX_LINE]; char *s; - mtime_t i_start; - mtime_t i_stop; + int64_t i_start; + int64_t i_stop; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) { int h1, m1, s1, c1, h2, m2, s2, c2; - int i_dummy; if( ( s = TextGetLine( txt ) ) == NULL ) { @@ -1015,33 +946,45 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) } p_subtitle->psz_text = malloc( strlen( s ) ); + /* We expect (SSA2-4): + * Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text + * Dialogue: Marked=0,0:02:40.65,0:02:41.79,Wolf main,Cher,0000,0000,0000,,Et les enregistrements de ses ondes delta ? + * + * SSA-1 is similar but only has 8 commas up untill the subtitle text. Probably the Effect field is no present, but not 100 % sure. + */ + + /* For ASS: + * Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text + * Dialogue: Layer#,0:02:40.65,0:02:41.79,Wolf main,Cher,0000,0000,0000,,Et les enregistrements de ses ondes delta ? + */ if( sscanf( s, - "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d%[^\r\n]", - &i_dummy, + "Dialogue: %[^,],%d:%d:%d.%d,%d:%d:%d.%d,%[^\r\n]", + buffer_text2, &h1, &m1, &s1, &c1, &h2, &m2, &s2, &c2, buffer_text ) == 10 ) { - i_start = ( (mtime_t)h1 * 3600*1000 + - (mtime_t)m1 * 60*1000 + - (mtime_t)s1 * 1000 + - (mtime_t)c1 * 10 ) * 1000; + i_start = ( (int64_t)h1 * 3600*1000 + + (int64_t)m1 * 60*1000 + + (int64_t)s1 * 1000 + + (int64_t)c1 * 10 ) * 1000; - i_stop = ( (mtime_t)h2 * 3600*1000 + - (mtime_t)m2 * 60*1000 + - (mtime_t)s2 * 1000 + - (mtime_t)c2 * 10 ) * 1000; + i_stop = ( (int64_t)h2 * 3600*1000 + + (int64_t)m2 * 60*1000 + + (int64_t)s2 * 1000 + + (int64_t)c2 * 10 ) * 1000; /* The dec expects: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text */ + /* (Layer comes from ASS specs ... it's empty for SSA.) */ if( p_sys->i_type == SUB_TYPE_SSA1 ) { sprintf( p_subtitle->psz_text, - ",%d%s", i_dummy, strdup( buffer_text) ); + ",%s", strdup( buffer_text) ); /* SSA1 has only 8 commas before the text starts, not 9 */ } else { sprintf( p_subtitle->psz_text, - ",%d,%s", i_dummy, strdup( buffer_text) ); + ",,%s", strdup( buffer_text) ); /* ReadOrder, Layer, %s(rest of fields) */ } p_subtitle->i_start = i_start; p_subtitle->i_stop = i_stop; @@ -1053,12 +996,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 @@ -1068,7 +1011,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" ); } } @@ -1089,12 +1032,11 @@ static int ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle ) */ char *p; char buffer_text[MAX_LINE + 1]; - mtime_t i_start; + int64_t i_start; unsigned int i; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; for( ;; ) @@ -1112,9 +1054,9 @@ static int ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle ) memset( buffer_text, '\0', MAX_LINE ); if( sscanf( p, "%d:%d:%d%[ :]%[^\r\n]", &h, &m, &s, &c, buffer_text ) == 5 ) { - i_start = ( (mtime_t)h * 3600*1000 + - (mtime_t)m * 60*1000 + - (mtime_t)s * 1000 ) * 1000; + i_start = ( (int64_t)h * 3600*1000 + + (int64_t)m * 60*1000 + + (int64_t)s * 1000 ) * 1000; break; } } @@ -1171,14 +1113,13 @@ static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle ) text_t *txt = &p_sys->txt; char *p; - int i_start; + int64_t i_start; int i_text; char buffer_text[10*MAX_LINE + 1]; p_subtitle->i_start = 0; p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; p_subtitle->psz_text = NULL; #define ADDC( c ) \ @@ -1262,117 +1203,3 @@ static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle ) return( VLC_SUCCESS ); #undef ADDC } - -static int ParseVobSubIDX( demux_t *p_demux, subtitle_t *p_subtitle ) -{ - demux_sys_t *p_sys = p_demux->p_sys; - text_t *txt = &p_sys->txt; - - /* - * Parse the idx file. Each line: - * timestamp: hh:mm:ss:mss, filepos: loc - * hexint is the hex location of the vobsub in the .sub file - * - */ - char *p; - char buffer_text[MAX_LINE + 1]; - unsigned int i_start, i_location; - - p_subtitle->i_start = 0; - p_subtitle->i_stop = 0; - p_subtitle->i_vobsub_location = 0; - p_subtitle->psz_text = NULL; - - for( ;; ) - { - unsigned int h, m, s, ms, loc; - - if( ( p = TextGetLine( txt ) ) == NULL ) - { - return( VLC_EGENERIC ); - } - i_start = 0; - - memset( buffer_text, '\0', MAX_LINE ); - if( sscanf( p, "timestamp: %d:%d:%d:%d, filepos: %x%[^\r\n]", - &h, &m, &s, &ms, &loc, buffer_text ) == 5 ) - { - i_start = ( (mtime_t)h * 3600*1000 + - (mtime_t)m * 60*1000 + - (mtime_t)s * 1000 + - (mtime_t)ms ) * 1000; - i_location = loc; - break; - } - } - p_subtitle->i_start = (mtime_t)i_start; - p_subtitle->i_stop = 0; - p_subtitle->psz_text = NULL; - p_subtitle->i_vobsub_location = i_location; - fprintf( stderr, "time: %x, location: %x\n", i_start, i_location ); - return( 0 ); -} - -static int DemuxVobSub( demux_t *p_demux, block_t *p_bk ) -{ - demux_sys_t *p_sys = p_demux->p_sys; - uint8_t *p = p_bk->p_buffer; - uint8_t *p_end = &p_bk->p_buffer[p_bk->i_buffer]; - - while( p < p_end ) - { - int i_size = ps_pkt_size( p, p_end - p ); - block_t *p_pkt; - int i_id; - int i_spu; - - if( i_size <= 0 ) - { - break; - } - if( p[0] != 0 || p[1] != 0 || p[2] != 0x01 ) - { - msg_Warn( p_demux, "invalid PES" ); - break; - } - - if( p[3] != 0xbd ) - { - msg_Dbg( p_demux, "we don't need these ps packets (id=0x1%2.2x)", p[3] ); - p += i_size; - continue; - } - - /* Create a block */ - p_pkt = block_New( p_demux, i_size ); - memcpy( p_pkt->p_buffer, p, i_size); - p += i_size; - - i_id = ps_pkt_id( p_pkt ); - if( (i_id&0xffe0) != 0xbd20 || - ps_pkt_parse_pes( p_pkt, 1 ) ) - { - block_Release( p_pkt ); - continue; - } - i_spu = i_id&0x1f; - msg_Dbg( p_demux, "SPU track %d size %d", i_spu, i_size ); - - /* FIXME i_spu == determines which of the spu tracks we will show. */ - if( p_sys->es && i_spu == 0 ) - { - p_pkt->i_dts = p_pkt->i_pts = p_bk->i_pts; - p_pkt->i_length = 0; - es_out_Send( p_demux->out, p_sys->es, p_pkt ); - - p_bk->i_pts = 0; /* only first packet has a pts */ - } - else - { - block_Release( p_pkt ); - continue; - } - } - - return VLC_SUCCESS; -}