Commit 6be80cac authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* Fix some detection logic for SSA/ASS subs

* Added ASS support
parent b748d47b
...@@ -49,12 +49,12 @@ static void Close( vlc_object_t *p_this ); ...@@ -49,12 +49,12 @@ static void Close( vlc_object_t *p_this );
"Override frames per second. " \ "Override frames per second. " \
"It will only work with MicroDVD subtitles." "It will only work with MicroDVD subtitles."
#define SUB_TYPE_LONGTEXT \ #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)." "\"sami\" (auto for autodetection, it should always work)."
static char *ppsz_sub_type[] = static char *ppsz_sub_type[] =
{ {
"auto", "microdvd", "subrip", "subviewer", "ssa1", "auto", "microdvd", "subrip", "subviewer", "ssa1",
"ssa2-4", "vplayer", "sami" "ssa2-4", "ass", "vplayer", "sami"
}; };
vlc_module_begin(); vlc_module_begin();
...@@ -87,6 +87,7 @@ enum ...@@ -87,6 +87,7 @@ enum
SUB_TYPE_SUBRIP, SUB_TYPE_SUBRIP,
SUB_TYPE_SSA1, SUB_TYPE_SSA1,
SUB_TYPE_SSA2_4, SUB_TYPE_SSA2_4,
SUB_TYPE_ASS,
SUB_TYPE_VPLAYER, SUB_TYPE_VPLAYER,
SUB_TYPE_SAMI, SUB_TYPE_SAMI,
SUB_TYPE_SUBVIEWER, SUB_TYPE_SUBVIEWER,
...@@ -149,6 +150,7 @@ static struct ...@@ -149,6 +150,7 @@ static struct
{ "subviewer", SUB_TYPE_SUBVIEWER, "SubViewer",ParseSubViewer }, { "subviewer", SUB_TYPE_SUBVIEWER, "SubViewer",ParseSubViewer },
{ "ssa1", SUB_TYPE_SSA1, "SSA-1", ParseSSA }, { "ssa1", SUB_TYPE_SSA1, "SSA-1", ParseSSA },
{ "ssa2-4", SUB_TYPE_SSA2_4, "SSA-2/3/4",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 }, { "vplayer", SUB_TYPE_VPLAYER, "VPlayer", ParseVplayer },
{ "sami", SUB_TYPE_SAMI, "SAMI", ParseSami }, { "sami", SUB_TYPE_SAMI, "SAMI", ParseSami },
{ NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL } { NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL }
...@@ -263,28 +265,29 @@ static int Open ( vlc_object_t *p_this ) ...@@ -263,28 +265,29 @@ static int Open ( vlc_object_t *p_this )
p_sys->i_type = SUB_TYPE_SUBRIP; p_sys->i_type = SUB_TYPE_SUBRIP;
break; break;
} }
else if( sscanf( s, else if( !strncasecmp( s, "!: This is a Sub Station Alpha v1", 33 ) )
"!: This is a Sub Station Alpha v%d.x script.",
&i_dummy ) == 1)
{ {
if( i_dummy <= 1 ) p_sys->i_type = SUB_TYPE_SSA1;
{
p_sys->i_type = SUB_TYPE_SSA1;
}
else
{
p_sys->i_type = SUB_TYPE_SSA2_4; /* I hope this will work */
}
break; break;
} }
else if( strcasestr( s, "This is a Sub Station Alpha v4 script" ) ) else if( !strncasecmp( s, "ScriptType: v4.00+", 18 ) )
{ {
p_sys->i_type = SUB_TYPE_SSA2_4; /* I hope this will work */ p_sys->i_type = SUB_TYPE_ASS;
break;
}
else if( !strncasecmp( s, "ScriptType: v4.00", 17 ) )
{
p_sys->i_type = SUB_TYPE_SSA2_4;
break; break;
} }
else if( !strncasecmp( s, "Dialogue: Marked", 16 ) ) 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; break;
} }
else if( strcasestr( s, "[INFORMATION]" ) ) else if( strcasestr( s, "[INFORMATION]" ) )
...@@ -371,7 +374,8 @@ static int Open ( vlc_object_t *p_this ) ...@@ -371,7 +374,8 @@ static int Open ( vlc_object_t *p_this )
/* *** add subtitle ES *** */ /* *** add subtitle ES *** */
if( p_sys->i_type == SUB_TYPE_SSA1 || if( p_sys->i_type == SUB_TYPE_SSA1 ||
p_sys->i_type == SUB_TYPE_SSA2_4 ) 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',' ' ) ); es_format_Init( &fmt, SPU_ES, VLC_FOURCC( 's','s','a',' ' ) );
} }
...@@ -672,7 +676,7 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle ) ...@@ -672,7 +676,7 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
* each line: * each line:
* {n1}{n2}Line1|Line2|Line3.... * {n1}{n2}Line1|Line2|Line3....
* where n1 and n2 are the video frame number... * where n1 and n2 are the video frame number...
* * {n2} can also be {}
*/ */
char *s; char *s;
...@@ -916,6 +920,7 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) ...@@ -916,6 +920,7 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
text_t *txt = &p_sys->txt; text_t *txt = &p_sys->txt;
char buffer_text[ 10 * MAX_LINE]; char buffer_text[ 10 * MAX_LINE];
char buffer_text2[ 10 * MAX_LINE];
char *s; char *s;
int64_t i_start; int64_t i_start;
int64_t i_stop; int64_t i_stop;
...@@ -927,7 +932,6 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) ...@@ -927,7 +932,6 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
for( ;; ) for( ;; )
{ {
int h1, m1, s1, c1, h2, m2, s2, c2; int h1, m1, s1, c1, h2, m2, s2, c2;
int i_dummy;
if( ( s = TextGetLine( txt ) ) == NULL ) if( ( s = TextGetLine( txt ) ) == NULL )
{ {
...@@ -935,9 +939,20 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) ...@@ -935,9 +939,20 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
} }
p_subtitle->psz_text = malloc( strlen( s ) ); 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, if( sscanf( s,
"Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d%[^\r\n]", "Dialogue: %[^,],%d:%d:%d.%d,%d:%d:%d.%d,%[^\r\n]",
&i_dummy, buffer_text2,
&h1, &m1, &s1, &c1, &h1, &m1, &s1, &c1,
&h2, &m2, &s2, &c2, &h2, &m2, &s2, &c2,
buffer_text ) == 10 ) buffer_text ) == 10 )
...@@ -953,15 +968,16 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle ) ...@@ -953,15 +968,16 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
(int64_t)c2 * 10 ) * 1000; (int64_t)c2 * 10 ) * 1000;
/* The dec expects: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text */ /* 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 ) if( p_sys->i_type == SUB_TYPE_SSA1 )
{ {
sprintf( p_subtitle->psz_text, 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 else
{ {
sprintf( p_subtitle->psz_text, 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_start = i_start;
p_subtitle->i_stop = i_stop; p_subtitle->i_stop = i_stop;
......
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