Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
e7eea0d2
Commit
e7eea0d2
authored
Sep 18, 2004
by
Derk-Jan Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* split vobsub and textual demuxers.
parent
a350c47f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
591 additions
and
256 deletions
+591
-256
configure.ac
configure.ac
+1
-1
modules/demux/Modules.am
modules/demux/Modules.am
+1
-0
modules/demux/subtitle.c
modules/demux/subtitle.c
+40
-255
modules/demux/vobsub.c
modules/demux/vobsub.c
+549
-0
No files found.
configure.ac
View file @
e7eea0d2
...
...
@@ -955,7 +955,7 @@ VLC_ADD_PLUGINS([aout_file equalizer])
VLC_ADD_PLUGINS([i420_rgb i420_yuy2 i422_yuy2 i420_ymga])
VLC_ADD_PLUGINS([m3u id3 playlist export sgimb])
VLC_ADD_PLUGINS([rawvideo blend scale])
VLC_ADD_PLUGINS([wav araw subtitle adpcm a52sys dtssys au])
VLC_ADD_PLUGINS([wav araw subtitle
vobsub
adpcm a52sys dtssys au])
VLC_ADD_PLUGINS([access_file access_udp access_tcp access_http ipv4 access_mms])
VLC_ADD_PLUGINS([access_ftp access_directory sap http])
...
...
modules/demux/Modules.am
View file @
e7eea0d2
...
...
@@ -20,3 +20,4 @@ SOURCES_aiff = aiff.c
SOURCES_sgimb = sgimb.c
SOURCES_mjpeg = mjpeg.c
SOURCES_subtitle = subtitle.c
SOURCES_vobsub = vobsub.c
modules/demux/subtitle.c
View file @
e7eea0d2
/*****************************************************************************
* subtitle.c: Demux for
text and vobsub
files.
* subtitle.c: Demux for
subtitle text
files.
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id$
...
...
@@ -35,7 +35,6 @@
#include <vlc/input.h>
#include "vlc_video.h"
#include "ps.h"
#if (!defined( WIN32 ) || defined(__MINGW32__))
# include <dirent.h>
...
...
@@ -58,7 +57,7 @@ static void Close( vlc_object_t *p_this );
static
char
*
ppsz_sub_type
[]
=
{
"auto"
,
"microdvd"
,
"subrip"
,
"subviewer"
,
"ssa1"
,
"ssa2-4"
,
"vplayer"
,
"sami"
,
"vobsub"
"ssa2-4"
,
"vplayer"
,
"sami"
};
vlc_module_begin
();
...
...
@@ -73,7 +72,6 @@ vlc_module_begin();
set_callbacks
(
Open
,
Close
);
add_shortcut
(
"subtitle"
);
add_shortcut
(
"vobsub"
);
vlc_module_end
();
/*****************************************************************************
...
...
@@ -89,7 +87,7 @@ enum
SUB_TYPE_VPLAYER
,
SUB_TYPE_SAMI
,
SUB_TYPE_SUBVIEWER
,
SUB_TYPE_VOBSUB
,
NULL
};
typedef
struct
...
...
@@ -107,7 +105,6 @@ typedef struct
mtime_t
i_stop
;
char
*
psz_text
;
int
i_vobsub_location
;
}
subtitle_t
;
...
...
@@ -125,7 +122,6 @@ struct demux_sys_t
int
i_subtitle
;
int
i_subtitles
;
subtitle_t
*
subtitle
;
FILE
*
p_vobsub_file
;
mtime_t
i_original_mspf
;
int64_t
i_length
;
...
...
@@ -137,9 +133,6 @@ 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
ParseVobSubIDX
(
demux_t
*
,
subtitle_t
*
);
static
int
DemuxVobSub
(
demux_t
*
,
block_t
*
);
static
struct
{
...
...
@@ -156,7 +149,6 @@ static struct
{
"ssa2-4"
,
SUB_TYPE_SSA2_4
,
"SSA-2/3/4"
,
ParseSSA
},
{
"vplayer"
,
SUB_TYPE_VPLAYER
,
"VPlayer"
,
ParseVplayer
},
{
"sami"
,
SUB_TYPE_SAMI
,
"SAMI"
,
ParseSami
},
{
"vobsub"
,
SUB_TYPE_VOBSUB
,
"VobSub"
,
ParseVobSubIDX
},
{
NULL
,
SUB_TYPE_UNKNOWN
,
"Unknown"
,
NULL
}
};
...
...
@@ -165,8 +157,6 @@ static int Control( demux_t *, int, va_list );
static
void
Fix
(
demux_t
*
);
#define DVD_VIDEO_LB_LEN 2048
/*****************************************************************************
* Module initializer
*****************************************************************************/
...
...
@@ -180,8 +170,7 @@ static int Open ( vlc_object_t *p_this )
int
(
*
pf_read
)(
demux_t
*
,
subtitle_t
*
);
int
i
,
i_max
;
if
(
strcmp
(
p_demux
->
psz_demux
,
"subtitle"
)
&&
strcmp
(
p_demux
->
psz_demux
,
"vobsub"
)
)
if
(
strcmp
(
p_demux
->
psz_demux
,
"subtitle"
)
)
{
msg_Dbg
(
p_demux
,
"subtitle demux discarded"
);
return
VLC_EGENERIC
;
...
...
@@ -194,7 +183,6 @@ static int Open ( vlc_object_t *p_this )
p_sys
->
i_subtitle
=
0
;
p_sys
->
i_subtitles
=
0
;
p_sys
->
subtitle
=
NULL
;
p_sys
->
p_vobsub_file
=
NULL
;
p_sys
->
i_original_mspf
=
0
;
...
...
@@ -296,11 +284,6 @@ static int Open ( vlc_object_t *p_this )
p_sys
->
i_type
=
SUB_TYPE_VPLAYER
;
break
;
}
else
if
(
strcasestr
(
s
,
"# VobSub index file"
)
)
{
p_sys
->
i_type
=
SUB_TYPE_VOBSUB
;
break
;
}
free
(
s
);
s
=
NULL
;
...
...
@@ -363,10 +346,6 @@ static int Open ( vlc_object_t *p_this )
/* Fix subtitle (order and time) *** */
p_sys
->
i_subtitle
=
0
;
if
(
p_sys
->
i_type
!=
SUB_TYPE_VOBSUB
)
{
Fix
(
p_demux
);
}
p_sys
->
i_length
=
0
;
if
(
p_sys
->
i_subtitles
>
0
)
{
...
...
@@ -377,24 +356,7 @@ static int Open ( vlc_object_t *p_this )
}
/* *** add subtitle ES *** */
if
(
p_sys
->
i_type
==
SUB_TYPE_VOBSUB
)
{
int
i_len
=
strlen
(
p_demux
->
psz_path
);
char
*
psz_vobname
=
strdup
(
p_demux
->
psz_path
);
strcpy
(
psz_vobname
+
i_len
-
4
,
".sub"
);
/* open file */
if
(
!
(
p_sys
->
p_vobsub_file
=
fopen
(
psz_vobname
,
"rb"
)
)
)
{
msg_Err
(
p_demux
,
"couldn't open .sub Vobsub file: %s"
,
psz_vobname
);
}
free
(
psz_vobname
);
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
);
}
else
if
(
p_sys
->
i_type
==
SUB_TYPE_SSA1
||
if
(
p_sys
->
i_type
==
SUB_TYPE_SSA1
||
p_sys
->
i_type
==
SUB_TYPE_SSA2_4
)
{
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_FOURCC
(
's'
,
's'
,
'a'
,
' '
)
);
...
...
@@ -430,9 +392,6 @@ static void Close( vlc_object_t *p_this )
if
(
p_sys
->
subtitle
)
free
(
p_sys
->
subtitle
);
if
(
p_sys
->
p_vobsub_file
)
fclose
(
p_sys
->
p_vobsub_file
);
free
(
p_sys
);
}
...
...
@@ -538,104 +497,50 @@ static int Demux( demux_t *p_demux )
i_maxdate
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
+
1
;
}
if
(
p_sys
->
i_type
!=
SUB_TYPE_VOBSUB
)
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i_maxdate
)
{
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i_maxdate
)
{
block_t
*
p_block
;
int
i_len
=
strlen
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
psz_text
)
+
1
;
block_t
*
p_block
;
int
i_len
=
strlen
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
psz_text
)
+
1
;
if
(
i_len
<=
1
)
{
/* empty subtitle */
p_sys
->
i_subtitle
++
;
continue
;
}
if
(
(
p_block
=
block_New
(
p_demux
,
i_len
)
)
==
NULL
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
if
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
0
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
p_block
->
i_pts
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
p_block
->
i_dts
=
p_block
->
i_pts
;
if
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_stop
>
0
)
{
p_block
->
i_length
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_stop
-
p_block
->
i_pts
;
}
memcpy
(
p_block
->
p_buffer
,
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
psz_text
,
i_len
);
if
(
p_block
->
i_pts
>
0
)
{
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
,
p_block
);
}
else
{
block_Release
(
p_block
);
}
if
(
i_len
<=
1
)
{
/* empty subtitle */
p_sys
->
i_subtitle
++
;
continue
;
}
}
else
{
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i_maxdate
)
{
int
i_pos
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_vobsub_location
;
block_t
*
p_block
;
int
i_size
=
0
;
/* first compute SPU size */
if
(
p_sys
->
i_subtitle
+
1
<
p_sys
->
i_subtitles
)
{
i_size
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
+
1
].
i_vobsub_location
-
i_pos
;
}
if
(
i_size
<=
0
)
i_size
=
65535
;
/* Invalid or EOF */
/* Seek at the right place */
if
(
fseek
(
p_sys
->
p_vobsub_file
,
i_pos
,
SEEK_SET
)
)
{
msg_Warn
(
p_demux
,
"cannot seek at right vobsub location %d"
,
i_pos
);
p_sys
->
i_subtitle
++
;
continue
;
}
/* allocate a packet */
if
(
(
p_block
=
block_New
(
p_demux
,
i_size
)
)
==
NULL
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
/* read data */
p_block
->
i_buffer
=
fread
(
p_block
->
p_buffer
,
1
,
i_size
,
p_sys
->
p_vobsub_file
);
if
(
p_block
->
i_buffer
<=
6
)
{
block_Release
(
p_block
);
p_sys
->
i_subtitle
++
;
continue
;
}
if
(
(
p_block
=
block_New
(
p_demux
,
i_len
)
)
==
NULL
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
/* pts */
p_block
->
i_pts
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
if
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
0
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
/* demux this block */
DemuxVobSub
(
p_demux
,
p_block
);
p_block
->
i_pts
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
p_block
->
i_dts
=
p_block
->
i_pts
;
if
(
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_stop
>
0
)
{
p_block
->
i_length
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_stop
-
p_block
->
i_pts
;
}
p_sys
->
i_subtitle
++
;
memcpy
(
p_block
->
p_buffer
,
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
psz_text
,
i_len
);
if
(
p_block
->
i_pts
>
0
)
{
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
,
p_block
);
}
else
{
block_Release
(
p_block
);
}
p_sys
->
i_subtitle
++
;
}
/* */
...
...
@@ -764,7 +669,6 @@ static int ParseMicroDvd( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
...
...
@@ -820,7 +724,6 @@ static int ParseSubRip( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
...
...
@@ -914,7 +817,6 @@ static int ParseSubViewer( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
...
...
@@ -1002,7 +904,6 @@ static int ParseSSA( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
...
...
@@ -1095,7 +996,6 @@ static int ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
...
...
@@ -1179,7 +1079,6 @@ static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle )
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
#define ADDC( c ) \
...
...
@@ -1263,117 +1162,3 @@ static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle )
return
(
VLC_SUCCESS
);
#undef ADDC
}
static
int
ParseVobSubIDX
(
demux_t
*
p_demux
,
subtitle_t
*
p_subtitle
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
text_t
*
txt
=
&
p_sys
->
txt
;
/*
* 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
];
unsigned
int
i_start
,
i_location
;
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
p_subtitle
->
psz_text
=
NULL
;
for
(
;;
)
{
unsigned
int
h
,
m
,
s
,
ms
,
loc
;
if
(
(
p
=
TextGetLine
(
txt
)
)
==
NULL
)
{
return
(
VLC_EGENERIC
);
}
i_start
=
0
;
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
->
psz_text
=
NULL
;
p_subtitle
->
i_vobsub_location
=
i_location
;
fprintf
(
stderr
,
"time: %x, location: %x
\n
"
,
i_start
,
i_location
);
return
(
0
);
}
static
int
DemuxVobSub
(
demux_t
*
p_demux
,
block_t
*
p_bk
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
uint8_t
*
p
=
p_bk
->
p_buffer
;
uint8_t
*
p_end
=
&
p_bk
->
p_buffer
[
p_bk
->
i_buffer
];
while
(
p
<
p_end
)
{
int
i_size
=
ps_pkt_size
(
p
,
p_end
-
p
);
block_t
*
p_pkt
;
int
i_id
;
int
i_spu
;
if
(
i_size
<=
0
)
{
break
;
}
if
(
p
[
0
]
!=
0
||
p
[
1
]
!=
0
||
p
[
2
]
!=
0x01
)
{
msg_Warn
(
p_demux
,
"invalid PES"
);
break
;
}
if
(
p
[
3
]
!=
0xbd
)
{
msg_Dbg
(
p_demux
,
"we don't need these ps packets (id=0x1%2.2x)"
,
p
[
3
]
);
p
+=
i_size
;
continue
;
}
/* Create a block */
p_pkt
=
block_New
(
p_demux
,
i_size
);
memcpy
(
p_pkt
->
p_buffer
,
p
,
i_size
);
p
+=
i_size
;
i_id
=
ps_pkt_id
(
p_pkt
);
if
(
(
i_id
&
0xffe0
)
!=
0xbd20
||
ps_pkt_parse_pes
(
p_pkt
,
1
)
)
{
block_Release
(
p_pkt
);
continue
;
}
i_spu
=
i_id
&
0x1f
;
msg_Dbg
(
p_demux
,
"SPU track %d size %d"
,
i_spu
,
i_size
);
/* FIXME i_spu == determines which of the spu tracks we will show. */
if
(
p_sys
->
es
&&
i_spu
==
0
)
{
p_pkt
->
i_dts
=
p_pkt
->
i_pts
=
p_bk
->
i_pts
;
p_pkt
->
i_length
=
0
;
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
,
p_pkt
);
p_bk
->
i_pts
=
0
;
/* only first packet has a pts */
}
else
{
block_Release
(
p_pkt
);
continue
;
}
}
return
VLC_SUCCESS
;
}
modules/demux/vobsub.c
0 → 100644
View file @
e7eea0d2
/*****************************************************************************
* subtitle.c: Demux vobsub files.
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Derk-Jan Hartman <hartman at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "vlc_video.h"
#include "ps.h"
#define MAX_LINE 8192
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
);
static
void
Close
(
vlc_object_t
*
p_this
);
vlc_module_begin
();
set_description
(
_
(
"Vobsub subtitles demux"
)
);
set_capability
(
"demux2"
,
0
);
set_callbacks
(
Open
,
Close
);
add_shortcut
(
"vobsub"
);
vlc_module_end
();
/*****************************************************************************
* Prototypes:
*****************************************************************************/
typedef
struct
{
int
i_line_count
;
int
i_line
;
char
**
line
;
}
text_t
;
static
int
TextLoad
(
text_t
*
,
stream_t
*
s
);
static
void
TextUnload
(
text_t
*
);
typedef
struct
{
mtime_t
i_start
;
mtime_t
i_stop
;
int
i_vobsub_location
;
}
subtitle_t
;
struct
demux_sys_t
{
int
i_type
;
text_t
txt
;
es_out_id_t
*
es
;
int64_t
i_next_demux_date
;
int
i_subtitle
;
int
i_subtitles
;
subtitle_t
*
subtitle
;
FILE
*
p_vobsub_file
;
int64_t
i_length
;
};
static
int
Demux
(
demux_t
*
);
static
int
Control
(
demux_t
*
,
int
,
va_list
);
static
int
ParseVobSubIDX
(
demux_t
*
,
subtitle_t
*
);
static
int
DemuxVobSub
(
demux_t
*
f
,
block_t
*
);
/*****************************************************************************
* Module initializer
*****************************************************************************/
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
;
int
i_max
;
if
(
strcmp
(
p_demux
->
psz_demux
,
"vobsub"
)
)
{
msg_Dbg
(
p_demux
,
"vobsub demux discarded"
);
return
VLC_EGENERIC
;
}
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_control
=
Control
;
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_sys
->
i_subtitle
=
0
;
p_sys
->
i_subtitles
=
0
;
p_sys
->
subtitle
=
NULL
;
p_sys
->
p_vobsub_file
=
NULL
;
char
*
s
=
NULL
;
if
(
(
s
=
stream_ReadLine
(
p_demux
->
s
)
)
!=
NULL
)
{
if
(
!
strcasestr
(
s
,
"# VobSub index file"
)
)
{
msg_Err
(
p_demux
,
"this doesn't seem to be a vobsub file, bailing"
);
free
(
s
);
return
VLC_EGENERIC
;
}
free
(
s
);
s
=
NULL
;
if
(
stream_Seek
(
p_demux
->
s
,
0
)
)
{
msg_Warn
(
p_demux
,
"failed to rewind"
);
}
}
else
{
msg_Err
(
p_demux
,
"could not read vobsub IDX file"
);
return
VLC_EGENERIC
;
}
/* Load the whole file */
TextLoad
(
&
p_sys
->
txt
,
p_demux
->
s
);
/* Parse it */
for
(
i_max
=
0
;;
)
{
if
(
p_sys
->
i_subtitles
>=
i_max
)
{
i_max
+=
500
;
if
(
!
(
p_sys
->
subtitle
=
realloc
(
p_sys
->
subtitle
,
sizeof
(
subtitle_t
)
*
i_max
)
)
)
{
msg_Err
(
p_demux
,
"out of memory"
);
return
VLC_ENOMEM
;
}
}
if
(
ParseVobSubIDX
(
p_demux
,
&
p_sys
->
subtitle
[
p_sys
->
i_subtitles
]
)
)
break
;
p_sys
->
i_subtitles
++
;
}
/* Unload */
TextUnload
(
&
p_sys
->
txt
);
msg_Dbg
(
p_demux
,
"loaded %d subtitles"
,
p_sys
->
i_subtitles
);
/* Fix subtitle (order and time) *** */
p_sys
->
i_subtitle
=
0
;
p_sys
->
i_length
=
0
;
if
(
p_sys
->
i_subtitles
>
0
)
{
p_sys
->
i_length
=
p_sys
->
subtitle
[
p_sys
->
i_subtitles
-
1
].
i_stop
;
/* +1 to avoid 0 */
if
(
p_sys
->
i_length
<=
0
)
p_sys
->
i_length
=
p_sys
->
subtitle
[
p_sys
->
i_subtitles
-
1
].
i_start
+
1
;
}
int
i_len
=
strlen
(
p_demux
->
psz_path
);
char
*
psz_vobname
=
strdup
(
p_demux
->
psz_path
);
strcpy
(
psz_vobname
+
i_len
-
4
,
".sub"
);
/* open file */
if
(
!
(
p_sys
->
p_vobsub_file
=
fopen
(
psz_vobname
,
"rb"
)
)
)
{
msg_Err
(
p_demux
,
"couldn't open .sub Vobsub file: %s"
,
psz_vobname
);
}
free
(
psz_vobname
);
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
);
p_sys
->
es
=
es_out_Add
(
p_demux
->
out
,
&
fmt
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close: Close subtitle demux
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
p_sys
->
subtitle
)
free
(
p_sys
->
subtitle
);
if
(
p_sys
->
p_vobsub_file
)
fclose
(
p_sys
->
p_vobsub_file
);
free
(
p_sys
);
}
/*****************************************************************************
* Control:
*****************************************************************************/
static
int
Control
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int64_t
*
pi64
,
i64
;
double
*
pf
,
f
;
switch
(
i_query
)
{
case
DEMUX_GET_LENGTH
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
p_sys
->
i_length
;
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
if
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
)
{
*
pi64
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
return
VLC_SUCCESS
;
}
return
VLC_EGENERIC
;
case
DEMUX_SET_TIME
:
i64
=
(
int64_t
)
va_arg
(
args
,
int64_t
);
p_sys
->
i_subtitle
=
0
;
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i64
)
{
p_sys
->
i_subtitle
++
;
}
if
(
p_sys
->
i_subtitle
>=
p_sys
->
i_subtitles
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
case
DEMUX_GET_POSITION
:
pf
=
(
double
*
)
va_arg
(
args
,
double
*
);
if
(
p_sys
->
i_subtitle
>=
p_sys
->
i_subtitles
)
{
*
pf
=
1
.
0
;
}
else
if
(
p_sys
->
i_subtitles
>
0
)
{
*
pf
=
(
double
)
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
/
(
double
)
p_sys
->
i_length
;
}
else
{
*
pf
=
0
.
0
;
}
return
VLC_SUCCESS
;
case
DEMUX_SET_POSITION
:
f
=
(
double
)
va_arg
(
args
,
double
);
i64
=
f
*
p_sys
->
i_length
;
p_sys
->
i_subtitle
=
0
;
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i64
)
{
p_sys
->
i_subtitle
++
;
}
if
(
p_sys
->
i_subtitle
>=
p_sys
->
i_subtitles
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
case
DEMUX_SET_NEXT_DEMUX_TIME
:
p_sys
->
i_next_demux_date
=
(
int64_t
)
va_arg
(
args
,
int64_t
);
return
VLC_SUCCESS
;
case
DEMUX_GET_FPS
:
case
DEMUX_GET_META
:
case
DEMUX_GET_TITLE_INFO
:
return
VLC_EGENERIC
;
default:
msg_Err
(
p_demux
,
"unknown query in subtitle control"
);
return
VLC_EGENERIC
;
}
}
/*****************************************************************************
* Demux: Send subtitle to decoder
*****************************************************************************/
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int64_t
i_maxdate
;
if
(
p_sys
->
i_subtitle
>=
p_sys
->
i_subtitles
)
return
0
;
i_maxdate
=
p_sys
->
i_next_demux_date
;
if
(
i_maxdate
<=
0
&&
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
)
{
/* Should not happen */
i_maxdate
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
+
1
;
}
while
(
p_sys
->
i_subtitle
<
p_sys
->
i_subtitles
&&
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
<
i_maxdate
)
{
int
i_pos
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_vobsub_location
;
block_t
*
p_block
;
int
i_size
=
0
;
/* first compute SPU size */
if
(
p_sys
->
i_subtitle
+
1
<
p_sys
->
i_subtitles
)
{
i_size
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
+
1
].
i_vobsub_location
-
i_pos
;
}
if
(
i_size
<=
0
)
i_size
=
65535
;
/* Invalid or EOF */
/* Seek at the right place */
if
(
fseek
(
p_sys
->
p_vobsub_file
,
i_pos
,
SEEK_SET
)
)
{
msg_Warn
(
p_demux
,
"cannot seek at right vobsub location %d"
,
i_pos
);
p_sys
->
i_subtitle
++
;
continue
;
}
/* allocate a packet */
if
(
(
p_block
=
block_New
(
p_demux
,
i_size
)
)
==
NULL
)
{
p_sys
->
i_subtitle
++
;
continue
;
}
/* read data */
p_block
->
i_buffer
=
fread
(
p_block
->
p_buffer
,
1
,
i_size
,
p_sys
->
p_vobsub_file
);
if
(
p_block
->
i_buffer
<=
6
)
{
block_Release
(
p_block
);
p_sys
->
i_subtitle
++
;
continue
;
}
/* pts */
p_block
->
i_pts
=
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
/* demux this block */
DemuxVobSub
(
p_demux
,
p_block
);
p_sys
->
i_subtitle
++
;
}
/* */
p_sys
->
i_next_demux_date
=
0
;
return
1
;
}
static
int
TextLoad
(
text_t
*
txt
,
stream_t
*
s
)
{
int
i_line_max
;
/* init txt */
i_line_max
=
500
;
txt
->
i_line_count
=
0
;
txt
->
i_line
=
0
;
txt
->
line
=
calloc
(
i_line_max
,
sizeof
(
char
*
)
);
/* load the complete file */
for
(
;;
)
{
char
*
psz
=
stream_ReadLine
(
s
);
if
(
psz
==
NULL
)
break
;
txt
->
line
[
txt
->
i_line_count
++
]
=
psz
;
if
(
txt
->
i_line_count
>=
i_line_max
)
{
i_line_max
+=
100
;
txt
->
line
=
realloc
(
txt
->
line
,
i_line_max
*
sizeof
(
char
*
)
);
}
}
if
(
txt
->
i_line_count
<=
0
)
{
free
(
txt
->
line
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
void
TextUnload
(
text_t
*
txt
)
{
int
i
;
for
(
i
=
0
;
i
<
txt
->
i_line_count
;
i
++
)
{
free
(
txt
->
line
[
i
]
);
}
free
(
txt
->
line
);
txt
->
i_line
=
0
;
txt
->
i_line_count
=
0
;
}
static
char
*
TextGetLine
(
text_t
*
txt
)
{
if
(
txt
->
i_line
>=
txt
->
i_line_count
)
return
(
NULL
);
return
txt
->
line
[
txt
->
i_line
++
];
}
static
void
TextPreviousLine
(
text_t
*
txt
)
{
if
(
txt
->
i_line
>
0
)
txt
->
i_line
--
;
}
static
int
ParseVobSubIDX
(
demux_t
*
p_demux
,
subtitle_t
*
p_subtitle
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
text_t
*
txt
=
&
p_sys
->
txt
;
/*
* 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
];
unsigned
int
i_start
,
i_location
;
p_subtitle
->
i_start
=
0
;
p_subtitle
->
i_stop
=
0
;
p_subtitle
->
i_vobsub_location
=
0
;
for
(
;;
)
{
unsigned
int
h
,
m
,
s
,
ms
,
loc
;
if
(
(
p
=
TextGetLine
(
txt
)
)
==
NULL
)
{
return
(
VLC_EGENERIC
);
}
i_start
=
0
;
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
);
}
static
int
DemuxVobSub
(
demux_t
*
p_demux
,
block_t
*
p_bk
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
uint8_t
*
p
=
p_bk
->
p_buffer
;
uint8_t
*
p_end
=
&
p_bk
->
p_buffer
[
p_bk
->
i_buffer
];
while
(
p
<
p_end
)
{
int
i_size
=
ps_pkt_size
(
p
,
p_end
-
p
);
block_t
*
p_pkt
;
int
i_id
;
int
i_spu
;
if
(
i_size
<=
0
)
{
break
;
}
if
(
p
[
0
]
!=
0
||
p
[
1
]
!=
0
||
p
[
2
]
!=
0x01
)
{
msg_Warn
(
p_demux
,
"invalid PES"
);
break
;
}
if
(
p
[
3
]
!=
0xbd
)
{
msg_Dbg
(
p_demux
,
"we don't need these ps packets (id=0x1%2.2x)"
,
p
[
3
]
);
p
+=
i_size
;
continue
;
}
/* Create a block */
p_pkt
=
block_New
(
p_demux
,
i_size
);
memcpy
(
p_pkt
->
p_buffer
,
p
,
i_size
);
p
+=
i_size
;
i_id
=
ps_pkt_id
(
p_pkt
);
if
(
(
i_id
&
0xffe0
)
!=
0xbd20
||
ps_pkt_parse_pes
(
p_pkt
,
1
)
)
{
block_Release
(
p_pkt
);
continue
;
}
i_spu
=
i_id
&
0x1f
;
msg_Dbg
(
p_demux
,
"SPU track %d size %d"
,
i_spu
,
i_size
);
/* FIXME i_spu == determines which of the spu tracks we will show. */
if
(
p_sys
->
es
&&
i_spu
==
0
)
{
p_pkt
->
i_dts
=
p_pkt
->
i_pts
=
p_bk
->
i_pts
;
p_pkt
->
i_length
=
0
;
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
,
p_pkt
);
p_bk
->
i_pts
=
0
;
/* only first packet has a pts */
}
else
{
block_Release
(
p_pkt
);
continue
;
}
}
return
VLC_SUCCESS
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment