]> git.sesse.net Git - vlc/commitdiff
* Backport of SSA/ASS fixes [11158] to 0.8.2
authorDerk-Jan Hartman <hartman@videolan.org>
Tue, 24 May 2005 19:52:57 +0000 (19:52 +0000)
committerDerk-Jan Hartman <hartman@videolan.org>
Tue, 24 May 2005 19:52:57 +0000 (19:52 +0000)
modules/demux/subtitle.c

index ee80ed24c94617e440418a8159dca445e2ced3ed..060ddef0aab9f8c6aac53723e648b942af8c7416 100644 (file)
@@ -49,12 +49,12 @@ 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"
+    "ssa2-4", "ass", "vplayer", "sami"
 };
 
 vlc_module_begin();
@@ -87,6 +87,7 @@ enum
     SUB_TYPE_SUBRIP,
     SUB_TYPE_SSA1,
     SUB_TYPE_SSA2_4,
+    SUB_TYPE_ASS,
     SUB_TYPE_VPLAYER,
     SUB_TYPE_SAMI,
     SUB_TYPE_SUBVIEWER,
@@ -149,6 +150,7 @@ 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 },
     { NULL,         SUB_TYPE_UNKNOWN,   "Unknown",  NULL }
@@ -263,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( 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;
             }
             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]" ) )
@@ -371,7 +374,8 @@ static int Open ( vlc_object_t *p_this )
 
     /* *** add subtitle ES *** */
     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',' ' ) );
     }
@@ -672,7 +676,7 @@ 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;
 
@@ -916,6 +920,7 @@ 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;
     int64_t     i_start;
     int64_t     i_stop;
@@ -927,7 +932,6 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
     for( ;; )
     {
         int h1, m1, s1, c1, h2, m2, s2, c2;
-        int i_dummy;
 
         if( ( s = TextGetLine( txt ) ) == NULL )
         {
@@ -935,9 +939,20 @@ 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 )
@@ -953,15 +968,16 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
                         (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;