Commit fc19e0d5 authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* starting support for external vobsubs.

  we can now read the .idx file. TODO:
  - create a structure to store subinfo in (like WAVEFORMATEX and BITMAPINFO
  - allow for multiple tracks in the sub demux
  - open the .sub vobsub file, remove the mpeg crud and prepare a packet
    for spudec.
parent f698e1fc
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* sub.c * sub.c
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2003 VideoLAN * Copyright (C) 1999-2003 VideoLAN
* $Id: sub.c,v 1.30 2003/10/18 21:46:01 hartman Exp $ * $Id: sub.c,v 1.31 2003/10/31 22:46:19 hartman Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -52,7 +52,8 @@ static void sub_close( subtitle_demux_t *p_sub ); ...@@ -52,7 +52,8 @@ static void sub_close( subtitle_demux_t *p_sub );
static void sub_fix( subtitle_demux_t *p_sub ); static void sub_fix( subtitle_demux_t *p_sub );
static char *ppsz_sub_type[] = { "auto", "microdvd", "subrip", "ssa1", "ssa2-4", "vplayer", "sami", NULL }; static char *ppsz_sub_type[] = { "auto", "microdvd", "subrip", "ssa1", "ssa2-4",
"vplayer", "sami", "vobsub", NULL };
/***************************************************************************** /*****************************************************************************
...@@ -209,6 +210,7 @@ static int sub_SSA1Read ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_mic ...@@ -209,6 +210,7 @@ static int sub_SSA1Read ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_mic
static int sub_SSA2_4Read ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ); static int sub_SSA2_4Read ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe );
static int sub_Vplayer ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ); static int sub_Vplayer ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe );
static int sub_Sami ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ); static int sub_Sami ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe );
static int sub_VobSub ( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe );
static struct static struct
{ {
...@@ -224,7 +226,8 @@ static struct ...@@ -224,7 +226,8 @@ static struct
{ "ssa2-4", SUB_TYPE_SSA2_4, "SSA-2/3/4",sub_SSA2_4Read }, { "ssa2-4", SUB_TYPE_SSA2_4, "SSA-2/3/4",sub_SSA2_4Read },
{ "vplayer", SUB_TYPE_VPLAYER, "VPlayer", sub_Vplayer }, { "vplayer", SUB_TYPE_VPLAYER, "VPlayer", sub_Vplayer },
{ "sami", SUB_TYPE_SAMI, "SAMI", sub_Sami }, { "sami", SUB_TYPE_SAMI, "SAMI", sub_Sami },
{ NULL, SUB_TYPE_UNKNOWN, "Unknow", NULL } { "vobsub", SUB_TYPE_VOBSUB, "VobSub", sub_VobSub },
{ NULL, SUB_TYPE_UNKNOWN, "Unknown", NULL }
}; };
static char * local_stristr( char *psz_big, char *psz_little) static char * local_stristr( char *psz_big, char *psz_little)
...@@ -373,17 +376,18 @@ static int sub_open ( subtitle_demux_t *p_sub, ...@@ -373,17 +376,18 @@ static int sub_open ( subtitle_demux_t *p_sub,
} }
else else
{ {
i_sub_type = SUB_TYPE_SSA2_4; // I hop this will work i_sub_type = SUB_TYPE_SSA2_4; /* I hope this will work */
} }
break; break;
} }
else if( local_stristr( s, "This is a Sub Station Alpha v4 script" ) ) else if( local_stristr( s, "This is a Sub Station Alpha v4 script" ) )
{ {
i_sub_type = SUB_TYPE_SSA2_4; // I hop this will work i_sub_type = SUB_TYPE_SSA2_4; /* I hope this will work */
break;
} }
else if( !strncasecmp( s, "Dialogue: Marked", 16 ) ) else if( !strncasecmp( s, "Dialogue: Marked", 16 ) )
{ {
i_sub_type = SUB_TYPE_SSA2_4; // could be wrong i_sub_type = SUB_TYPE_SSA2_4; /* could be wrong */
break; break;
} }
else if( sscanf( s, "%d:%d:%d:", &i_dummy, &i_dummy, &i_dummy ) == 3 || else if( sscanf( s, "%d:%d:%d:", &i_dummy, &i_dummy, &i_dummy ) == 3 ||
...@@ -392,6 +396,11 @@ static int sub_open ( subtitle_demux_t *p_sub, ...@@ -392,6 +396,11 @@ static int sub_open ( subtitle_demux_t *p_sub,
i_sub_type = SUB_TYPE_VPLAYER; i_sub_type = SUB_TYPE_VPLAYER;
break; break;
} }
else if( local_stristr( s, "# VobSub index file" ) )
{
i_sub_type = SUB_TYPE_VOBSUB;
break;
}
} }
text_rewind( &txt ); text_rewind( &txt );
...@@ -411,6 +420,7 @@ static int sub_open ( subtitle_demux_t *p_sub, ...@@ -411,6 +420,7 @@ static int sub_open ( subtitle_demux_t *p_sub,
{ {
msg_Dbg( p_input, "detected %s format", msg_Dbg( p_input, "detected %s format",
sub_read_subtitle_function[i].psz_name ); sub_read_subtitle_function[i].psz_name );
p_sub->i_sub_type = i_sub_type;
pf_read_subtitle = sub_read_subtitle_function[i].pf_read_subtitle; pf_read_subtitle = sub_read_subtitle_function[i].pf_read_subtitle;
break; break;
} }
...@@ -445,7 +455,7 @@ static int sub_open ( subtitle_demux_t *p_sub, ...@@ -445,7 +455,7 @@ static int sub_open ( subtitle_demux_t *p_sub,
text_unload( &txt ); text_unload( &txt );
/* *** fix subtitle (order and time) *** */ /* *** fix subtitle (order and time) *** */
p_sub->i_subtitle = 0; // will be modified by sub_fix p_sub->i_subtitle = 0; /* will be modified by sub_fix */
sub_fix( p_sub ); sub_fix( p_sub );
/* *** add subtitle ES *** */ /* *** add subtitle ES *** */
...@@ -456,7 +466,16 @@ static int sub_open ( subtitle_demux_t *p_sub, ...@@ -456,7 +466,16 @@ static int sub_open ( subtitle_demux_t *p_sub,
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
p_sub->p_es->i_stream_id = 0xff - i_track_id; /* FIXME */ p_sub->p_es->i_stream_id = 0xff - i_track_id; /* FIXME */
p_sub->p_es->i_fourcc = VLC_FOURCC( 's','u','b','t' );
if( p_sub->i_sub_type != SUB_TYPE_VOBSUB )
{
p_sub->p_es->i_fourcc = VLC_FOURCC( 's','u','b','t' );
}
else
{
p_sub->p_es->i_fourcc = VLC_FOURCC( 's','p','u',' ' );
/* open vobsub file */
}
p_sub->i_previously_selected = 0; p_sub->i_previously_selected = 0;
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -1029,3 +1048,45 @@ static int sub_Sami( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecper ...@@ -1029,3 +1048,45 @@ static int sub_Sami( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecper
#undef ADDC #undef ADDC
} }
static int sub_VobSub( text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe)
{
/*
* 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];
uint32_t i_start, i_location;
for( ;; )
{
if( ( p = text_get_line( txt ) ) == NULL )
{
return( VLC_EGENERIC );
}
i_start = 0;
unsigned int h, m, s, ms, loc;
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->i_vobsub_location = i_location;
fprintf( stderr, "time: %x, location: %x\n", i_start, i_location );
return( 0 );
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* sub.h * sub.h
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * Copyright (C) 2001-2003 VideoLAN
* $Id: sub.h,v 1.8 2003/10/11 22:40:05 hartman Exp $ * $Id: sub.h,v 1.9 2003/10/31 22:46:19 hartman Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define SUB_TYPE_SSA2_4 0x03 #define SUB_TYPE_SSA2_4 0x03
#define SUB_TYPE_VPLAYER 0x04 #define SUB_TYPE_VPLAYER 0x04
#define SUB_TYPE_SAMI 0x05 #define SUB_TYPE_SAMI 0x05
#define SUB_TYPE_VOBSUB 0x100
#define SUB_TYPE_UNKNOWN 0xffff #define SUB_TYPE_UNKNOWN 0xffff
typedef struct subtitle_s typedef struct subtitle_s
...@@ -35,8 +36,22 @@ typedef struct subtitle_s ...@@ -35,8 +36,22 @@ typedef struct subtitle_s
mtime_t i_stop; mtime_t i_stop;
char *psz_text; char *psz_text;
int i_vobsub_location;
} subtitle_t; } subtitle_t;
typedef struct subtitle_track_s
{
int i_track_id;
int i_subtitle;
int i_subtitles;
subtitle_t *subtitle;
char *psz_language;
int i_previously_selected; /* to make pf_seek */
es_descriptor_t *p_es;
} subtitle_track_t;
typedef struct subtitle_demux_s typedef struct subtitle_demux_s
{ {
...@@ -55,15 +70,19 @@ typedef struct subtitle_demux_s ...@@ -55,15 +70,19 @@ typedef struct subtitle_demux_s
/* *** private *** */ /* *** private *** */
input_thread_t *p_input; input_thread_t *p_input;
int i_sub_type; int i_sub_type;
int i_previously_selected; /* to make pf_seek */
int i_subtitle;
int i_subtitles;
subtitle_t *subtitle;
es_descriptor_t *p_es;
int i_previously_selected; // to make pf_seek /*unsigned int i_tracks;
es_descriptor_t *p_es; subtitle_track_t *p_tracks
*/
int i_subtitle;
int i_subtitles;
subtitle_t *subtitle;
} subtitle_demux_t; } subtitle_demux_t;
......
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