]> git.sesse.net Git - vlc/blobdiff - modules/demux/subtitle.c
Fix typo
[vlc] / modules / demux / subtitle.c
index a13995f39e059b4876837f61ed0ed4541f2b415c..307caa235d8a15232c538e941f220d1646bdc05a 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * subtitle.c: Demux for subtitle text files.
  *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
+ * Copyright (C) 1999-2007 the VideoLAN team
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc_input.h>
+
+#include <string.h>
 #include <stdlib.h>
 
 #include <errno.h>
@@ -33,9 +37,8 @@
 #endif
 #include <ctype.h>
 
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-#include "vlc_video.h"
+#include <vlc_demux.h>
+#include <vlc_charset.h>
 
 /*****************************************************************************
  * Module descriptor
@@ -44,19 +47,19 @@ static int  Open ( vlc_object_t *p_this );
 static void Close( vlc_object_t *p_this );
 
 #define SUB_DELAY_LONGTEXT \
-    "Apply a delay to all subtitles (in 1/10s, eg 100 means 10s)."
+    N_("Apply a delay to all subtitles (in 1/10s, eg 100 means 10s).")
 #define SUB_FPS_LONGTEXT \
-    "Override the normal frames per second settings. " \
-    "This will only work with MicroDVD and SubRIP (SRT) subtitles."
+    N_("Override the normal frames per second settings. " \
+    "This will only work with MicroDVD and SubRIP (SRT) subtitles.")
 #define SUB_TYPE_LONGTEXT \
-    "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[] =
+    N_("Force the subtiles format. Valid values are : \"microdvd\", " \
+    "\"subrip\",  \"ssa1\", \"ssa2-4\", \"ass\", \"vplayer\" " \
+    "\"sami\", \"dvdsubtitle\", \"mpl2\" and \"auto\" (meaning autodetection, this " \
+    "should always work).")
+static const char *ppsz_sub_type[] =
 {
     "auto", "microdvd", "subrip", "subviewer", "ssa1",
-    "ssa2-4", "ass", "vplayer", "sami", "dvdsubtitle"
+    "ssa2-4", "ass", "vplayer", "sami", "dvdsubtitle", "mpl2"
 };
 
 vlc_module_begin();
@@ -73,7 +76,7 @@ vlc_module_begin();
                SUB_DELAY_LONGTEXT, VLC_TRUE );
     add_string( "sub-type", "auto", NULL, N_("Subtitles format"),
                 SUB_TYPE_LONGTEXT, VLC_TRUE );
-        change_string_list( ppsz_sub_type, 0, 0 );
+        change_string_list( ppsz_sub_type, NULL, NULL );
     set_callbacks( Open, Close );
 
     add_shortcut( "subtitle" );
@@ -93,7 +96,8 @@ enum
     SUB_TYPE_VPLAYER,
     SUB_TYPE_SAMI,
     SUB_TYPE_SUBVIEWER,
-    SUB_TYPE_DVDSUBTITLE
+    SUB_TYPE_DVDSUBTITLE,
+    SUB_TYPE_MPL2
 };
 
 typedef struct
@@ -121,9 +125,7 @@ struct demux_sys_t
     es_out_id_t *es;
 
     int64_t     i_next_demux_date;
-
     int64_t     i_microsecperframe;
-    int64_t     i_original_mspf;
 
     char        *psz_header;
     int         i_subtitle;
@@ -140,12 +142,13 @@ 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 struct
 {
-    char *psz_type_name;
+    const char *psz_type_name;
     int  i_type;
-    char *psz_name;
+    const char *psz_name;
     int  (*pf_read)( demux_t *, subtitle_t* );
 } sub_read_subtitle_function [] =
 {
@@ -158,6 +161,7 @@ static struct
     { "vplayer",    SUB_TYPE_VPLAYER,     "VPlayer",     ParseVplayer },
     { "sami",       SUB_TYPE_SAMI,        "SAMI",        ParseSami },
     { "dvdsubtitle",SUB_TYPE_DVDSUBTITLE, "DVDSubtitle", ParseDVDSubtitle },
+    { "mpl2",       SUB_TYPE_MPL2,        "MPL2",        ParseMPL2 },
     { NULL,         SUB_TYPE_UNKNOWN,     "Unknown",     NULL }
 };
 
@@ -171,13 +175,14 @@ static int Control( demux_t *, int, va_list );
  *****************************************************************************/
 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;
-    float f_fps;
-    char *psz_type;
+    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 i, i_max;
+    int            i, i_max;
 
     if( strcmp( p_demux->psz_demux, "subtitle" ) )
     {
@@ -188,31 +193,30 @@ static int Open ( vlc_object_t *p_this )
     p_demux->pf_demux = Demux;
     p_demux->pf_control = Control;
     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
-    p_sys->psz_header = NULL;
-    p_sys->i_subtitle = 0;
-    p_sys->i_subtitles= 0;
-    p_sys->subtitle   = NULL;
-
+    p_sys->psz_header         = NULL;
+    p_sys->i_subtitle         = 0;
+    p_sys->i_subtitles        = 0;
+    p_sys->subtitle           = NULL;
+    p_sys->i_microsecperframe = 40000;
 
     /* Get the FPS */
-    f_fps = var_CreateGetFloat( p_demux, "sub-fps" );
-    if( f_fps >= 1.0 )
-    {
-        p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps );
-    }
-    else
+    p_input = (input_thread_t *)vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT );
+    if( p_input )
     {
-        p_sys->i_microsecperframe = 0;
+        f_fps = var_GetFloat( p_input, "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 );
     }
 
-    f_fps = var_CreateGetFloat( p_demux, "sub-original-fps" );
+    /* Check for override of the fps */
+    f_fps = var_CreateGetFloat( p_demux, "sub-fps" );
     if( f_fps >= 1.0 )
     {
-        p_sys->i_original_mspf = (int64_t)( (float)1000000 / f_fps );
-    }
-    else
-    {
-        p_sys->i_original_mspf = 0;
+        p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps );
+        msg_Dbg( p_demux, "Override subtitle fps %f", f_fps );
     }
 
     /* Get or probe the type */
@@ -312,6 +316,12 @@ static int Open ( vlc_object_t *p_this )
                 p_sys->i_type = SUB_TYPE_DVDSUBTITLE;
                 break;
             }
+            else if( sscanf( s, "[%d][%d]", &i_dummy, &i_dummy ) == 2 ||
+                     sscanf( s, "[%d][]", &i_dummy ) == 1)
+            {
+                p_sys->i_type = SUB_TYPE_MPL2;
+                break;
+            }
 
             free( s );
             s = NULL;
@@ -703,14 +713,11 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
     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->psz_text = NULL;
 
+next:
     for( ;; )
     {
         if( ( s = TextGetLine( txt ) ) == NULL )
@@ -727,6 +734,16 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
             break;
         }
     }
+    if( i_start == 1 && i_stop == 1 )
+    {
+        /* We found a possible setting of the framerate "{1}{1}23.976" */
+        /* Check if it's usable, and if the sub-fps is not set */
+        float tmp = us_strtod( buffer_text, NULL );
+        if( tmp > 0.0 && var_GetFloat( p_demux, "sub-fps" ) <= 0.0 )
+            p_sys->i_microsecperframe = (int64_t)( (float)1000000 / tmp );
+        goto next;
+    }
+
     /* replace | by \n */
     for( i = 0; i < strlen( buffer_text ); i++ )
     {
@@ -736,8 +753,8 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
         }
     }
 
-    p_subtitle->i_start = (int64_t)i_start * i_microsecperframe;
-    p_subtitle->i_stop  = (int64_t)i_stop  * i_microsecperframe;
+    p_subtitle->i_start = (int64_t)i_start * p_sys->i_microsecperframe;
+    p_subtitle->i_stop  = (int64_t)i_stop  * p_sys->i_microsecperframe;
     p_subtitle->psz_text = strndup( buffer_text, MAX_LINE );
     return( 0 );
 }
@@ -805,17 +822,6 @@ static int  ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle )
                     p_subtitle->i_start = i_start;
                     p_subtitle->i_stop = i_stop;
                     p_subtitle->psz_text = strdup( buffer_text );
-                    /* If framerate is available, use sub-fps */
-                    if( p_sys->i_microsecperframe != 0 &&
-                        p_sys->i_original_mspf != 0)
-                    {
-                        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;
                 }
                 else
@@ -1087,7 +1093,7 @@ static int  ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle )
     return( 0 );
 }
 
-static char *ParseSamiSearch( text_t *txt, char *psz_start, char *psz_str )
+static char *ParseSamiSearch( text_t *txt, char *psz_start, const char *psz_str )
 {
     if( psz_start )
     {
@@ -1290,3 +1296,54 @@ static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle )
     }
 }
 
+static int ParseMPL2( demux_t *p_demux, subtitle_t *p_subtitle )
+{
+    demux_sys_t *p_sys = p_demux->p_sys;
+    text_t      *txt = &p_sys->txt;
+    /*
+     * 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];
+    int    i_start;
+    int    i_stop;
+    unsigned int i;
+
+    p_subtitle->i_start = 0;
+    p_subtitle->i_stop  = 0;
+    p_subtitle->psz_text = NULL;
+
+    for( ;; )
+    {
+        if( ( s = TextGetLine( txt ) ) == NULL )
+        {
+            return( VLC_EGENERIC );
+        }
+        i_start = 0;
+        i_stop  = 0;
+
+        memset( buffer_text, '\0', MAX_LINE );
+        if( sscanf( s, "[%d][]%[^\r\n]", &i_start, buffer_text ) == 2 ||
+            sscanf( s, "[%d][%d]%[^\r\n]", &i_start, &i_stop, buffer_text ) == 3)
+        {
+            break;
+        }
+    }
+
+    /* replace | by \n */
+    for( i = 0; i < strlen( buffer_text ); i++ )
+    {
+        if( buffer_text[i] == '|' )
+        {
+            buffer_text[i] = '\n';
+        }
+    }
+    p_subtitle->i_start = (int64_t)i_start * 100000;
+    p_subtitle->i_stop  = (int64_t)i_stop  * 100000;
+    p_subtitle->psz_text = strndup( buffer_text, MAX_LINE );
+    return( 0 );
+}