]> git.sesse.net Git - vlc/blobdiff - modules/demux/subtitle.c
Fix IVLCVideo.teletext binding
[vlc] / modules / demux / subtitle.c
index 2b9b8c4d16c035af949508d32a8b88ada9495338..09b2eecf40cb92226937593994ea632c2a44f268 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 #include <vlc_input.h>
 
-#include <string.h>
 
 #include <errno.h>
 #ifdef HAVE_SYS_TYPES_H
@@ -134,21 +137,21 @@ 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  ParseDVDSubtitle( demux_t *, subtitle_t * );
-static int  ParseMPL2       ( demux_t *, subtitle_t * );
+static int  ParseMicroDvd   ( demux_t *, subtitle_t *, int );
+static int  ParseSubRip     ( demux_t *, subtitle_t *, int );
+static int  ParseSubViewer  ( demux_t *, subtitle_t *, int );
+static int  ParseSSA        ( demux_t *, subtitle_t *, int );
+static int  ParseVplayer    ( demux_t *, subtitle_t *, int );
+static int  ParseSami       ( demux_t *, subtitle_t *, int );
+static int  ParseDVDSubtitle( demux_t *, subtitle_t *, int );
+static int  ParseMPL2       ( demux_t *, subtitle_t *, int );
 
 static struct
 {
     const char *psz_type_name;
     int  i_type;
     const char *psz_name;
-    int  (*pf_read)( demux_t *, subtitle_t* );
+    int  (*pf_read)( demux_t *, subtitle_t*, int );
 } sub_read_subtitle_function [] =
 {
     { "microdvd",   SUB_TYPE_MICRODVD,    "MicroDVD",    ParseMicroDvd },
@@ -177,13 +180,12 @@ static int Open ( vlc_object_t *p_this )
     demux_t        *p_demux = (demux_t*)p_this;
     demux_sys_t    *p_sys;
     es_format_t    fmt;
-    input_thread_t *p_input;
     float          f_fps;
     char           *psz_type;
-    int  (*pf_read)( demux_t *, subtitle_t* );
+    int  (*pf_read)( demux_t *, subtitle_t*, int );
     int            i, i_max;
 
-    if( strcmp( p_demux->psz_demux, "subtitle" ) )
+    if( !p_demux->b_force )
     {
         msg_Dbg( p_demux, "subtitle demux discarded" );
         return VLC_EGENERIC;
@@ -199,16 +201,11 @@ static int Open ( vlc_object_t *p_this )
     p_sys->i_microsecperframe = 40000;
 
     /* Get the FPS */
-    p_input = (input_thread_t *)vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT );
-    if( p_input )
-    {
-        f_fps = var_GetFloat( p_input, "sub-original-fps" );
-        if( f_fps >= 1.0 )
-            p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps );
+    f_fps = var_CreateGetFloat( p_demux, "sub-original-fps" );
+    if( f_fps >= 1.0 )
+        p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps );
 
-        msg_Dbg( p_demux, "Movie fps: %f", f_fps );
-        vlc_object_release( p_input );
-    }
+    msg_Dbg( p_demux, "Movie fps: %f", f_fps );
 
     /* Check for override of the fps */
     f_fps = var_CreateGetFloat( p_demux, "sub-fps" );
@@ -326,7 +323,7 @@ static int Open ( vlc_object_t *p_this )
             s = NULL;
         }
 
-        if( s ) free( s );
+        free( s );
 
         /* It will nearly always work even for non seekable stream thanks the
          * caching system, and if it fails we lose just a few sub */
@@ -368,15 +365,15 @@ 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 );
+                free( p_sys->subtitle );
                 TextUnload( &p_sys->txt );
                 free( p_sys );
                 return VLC_ENOMEM;
             }
         }
 
-        if( pf_read( p_demux, &p_sys->subtitle[p_sys->i_subtitles] ) )
+        if( pf_read( p_demux, &p_sys->subtitle[p_sys->i_subtitles],
+                     p_sys->i_subtitles ) )
             break;
 
         p_sys->i_subtitles++;
@@ -428,12 +425,8 @@ static void Close( vlc_object_t *p_this )
     int i;
 
     for( i = 0; i < p_sys->i_subtitles; i++ )
-    {
-        if( p_sys->subtitle[i].psz_text )
-            free( p_sys->subtitle[i].psz_text );
-    }
-    if( p_sys->subtitle )
-        free( p_sys->subtitle );
+        free( p_sys->subtitle[i].psz_text );
+    free( p_sys->subtitle );
 
     free( p_sys );
 }
@@ -515,10 +508,11 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
         case DEMUX_GET_META:
         case DEMUX_GET_ATTACHMENTS:
         case DEMUX_GET_TITLE_INFO:
+        case DEMUX_HAS_UNSUPPORTED_META:
             return VLC_EGENERIC;
 
         default:
-            msg_Err( p_demux, "unknown query in subtitle control" );
+            msg_Err( p_demux, "unknown query %d in subtitle control", i_query );
             return VLC_EGENERIC;
     }
 }
@@ -700,7 +694,8 @@ static void TextPreviousLine( text_t *txt )
  *      {n1}{n2}Line1|Line2|Line3....
  *  where n1 and n2 are the video frame number (n2 can be empty)
  */
-static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
+static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle,
+                          int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;
@@ -834,7 +829,7 @@ static int ParseSubRipSubViewer( demux_t *p_demux, subtitle_t *p_subtitle,
         if( b_replace_br )
         {
             char *p;
-            
             while( ( p = strstr( psz_text, "[br]" ) ) )
             {
                 *p++ = '\n';
@@ -845,7 +840,8 @@ static int ParseSubRipSubViewer( demux_t *p_demux, subtitle_t *p_subtitle,
 }
 /* ParseSubRip
  */
-static int  ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle )
+static int  ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle,
+                         int i_idx )
 {
     return ParseSubRipSubViewer( p_demux, p_subtitle,
                                  "%d:%d:%d,%d --> %d:%d:%d,%d",
@@ -853,7 +849,8 @@ static int  ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle )
 }
 /* ParseSubViewer
  */
-static int  ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle )
+static int  ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle,
+                            int i_idx )
 {
     return ParseSubRipSubViewer( p_demux, p_subtitle,
                                  "%d:%d:%d.%d,%d:%d:%d.%d",
@@ -862,7 +859,8 @@ static int  ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle )
 
 /* ParseSSA
  */
-static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
+static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle,
+                      int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;
@@ -872,6 +870,7 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
         const char *s = TextGetLine( txt );
         int h1, m1, s1, c1, h2, m2, s2, c2;
         char *psz_text;
+        char temp[16];
 
         if( !s )
             return VLC_EGENERIC;
@@ -887,15 +886,18 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
          * 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 ?
          */
-        psz_text = malloc( 2 + strlen( s ) + 1 );
+
+        /* The output text is - at least, not removing numbers - 18 chars shorter than the input text. */
+        psz_text = malloc( strlen(s) );
         if( !psz_text )
             return VLC_ENOMEM;
 
         if( sscanf( s,
-                    "Dialogue: %*[^,],%d:%d:%d.%d,%d:%d:%d.%d,%[^\r\n]",
+                    "Dialogue: %15[^,],%d:%d:%d.%d,%d:%d:%d.%d,%[^\r\n]",
+                    temp,
                     &h1, &m1, &s1, &c1,
                     &h2, &m2, &s2, &c2,
-                    psz_text ) == 9 )
+                    psz_text ) == 10 )
         {
             /* The dec expects: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text */
             /* (Layer comes from ASS specs ... it's empty for SSA.) */
@@ -907,10 +909,12 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
             }
             else
             {
+                int i_layer = ( p_sys->i_type == SUB_TYPE_ASS ) ? atoi( temp ) : 0;
+
                 /* ReadOrder, Layer, %s(rest of fields) */
-                memmove( &psz_text[2], psz_text, strlen(psz_text)+1 );
-                psz_text[0] = ',';
-                psz_text[1] = ',';
+                snprintf( temp, sizeof(temp), "%d,%d,", i_idx, i_layer );
+                memmove( psz_text + strlen(temp), psz_text, strlen(psz_text)+1 );
+                memcpy( psz_text, temp, strlen(temp) );
             }
 
             p_subtitle->i_start = ( (int64_t)h1 * 3600*1000 +
@@ -946,7 +950,8 @@ static int  ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
  *  or
  *      h:m:s Line1|Line2|Line3....
  */
-static int  ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle )
+static int  ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle,
+                          int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;
@@ -1011,7 +1016,7 @@ static char *ParseSamiSearch( text_t *txt,
         }
     }
 }
-static int  ParseSami( demux_t *p_demux, subtitle_t *p_subtitle )
+static int  ParseSami( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;
@@ -1108,7 +1113,8 @@ static int  ParseSami( demux_t *p_demux, subtitle_t *p_subtitle )
  *      LANG support would be cool
  *      CODEPAGE is probably mandatory FIXME
  */
-static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle )
+static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle,
+                             int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;
@@ -1172,7 +1178,7 @@ static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle )
  *     [n1][n2]Line1|Line2|Line3...
  *  where n1 and n2 are the video frame number (n2 can be empty)
  */
-static int ParseMPL2( demux_t *p_demux, subtitle_t *p_subtitle )
+static int ParseMPL2( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     text_t      *txt = &p_sys->txt;