Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
62487ef4
Commit
62487ef4
authored
Aug 12, 2010
by
Jean-Baptiste Kempf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove unmaintained SSA demuxer
We don't need it anyway
parent
2f00cae9
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
0 additions
and
1424 deletions
+0
-1424
modules/LIST
modules/LIST
+0
-1
modules/demux/Modules.am
modules/demux/Modules.am
+0
-1
modules/demux/asademux.c
modules/demux/asademux.c
+0
-538
modules/demux/asademux.h
modules/demux/asademux.h
+0
-162
modules/demux/asademux_defs.h
modules/demux/asademux_defs.h
+0
-219
modules/demux/subtitle_asa.c
modules/demux/subtitle_asa.c
+0
-499
po/POTFILES.in
po/POTFILES.in
+0
-4
No files found.
modules/LIST
View file @
62487ef4
...
...
@@ -44,7 +44,6 @@ $Id$
* aout_file: Audio output to write to a file
* aout_sdl: audio output module using the SDL library
* araw: Pseudo audio decoder for raw PCM
* asademux: ASS/SSA subtitles demuxer
* asf: ASF demuxer
* atmo: Ambilight-like video-output
* au: AU file demuxer
...
...
modules/demux/Modules.am
View file @
62487ef4
...
...
@@ -18,7 +18,6 @@ SOURCES_pva = pva.c
SOURCES_aiff = aiff.c
SOURCES_mjpeg = mjpeg.c
SOURCES_subtitle = subtitle.c
SOURCES_asademux = subtitle_asa.c asademux.c asademux_defs.h asademux.h
SOURCES_ty = ty.c ../codec/cc.h
SOURCES_vobsub = vobsub.c vobsub.h
SOURCES_voc = voc.c
...
...
modules/demux/asademux.c
deleted
100644 → 0
View file @
2f00cae9
/*****************************************************************************
* asademux.c: asa demuxer VM
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
*
* Originated from asa: portable digital subtitle renderer
*
* Authors: David Lamparter <equinox at diac24 dot net>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
****************************************************************************/
/****************************************************************************
* Changes from asa version:
* - headers adapted
* - external definition file support dropped
* - integer timestamps
****************************************************************************
* Please retain Linux kernel CodingStyle for sync.
* base commit d8c269b0fae9a8f8904e16e92313da165d664c74
****************************************************************************/
#include "config.h"
#include <vlc_common.h>
#include <vlc_input.h>
#include <vlc_demux.h>
#include <limits.h>
#include <string.h>
#include "asademux.h"
#define MAXDELTA 4
/**< nr of times kept for delta backref */
#define MAXGROUP 24
/**< maximum number of regex match groups */
#define xfree free
static
inline
char
*
xstrdup
(
const
char
*
str
)
{
char
*
ret
=
strdup
(
str
);
if
(
unlikely
(
ret
==
NULL
))
abort
();
return
ret
;
}
/** state of a running import */
struct
asa_import_state
{
demux_t
*
demux
;
/**< demuxer for msg* funcs */
const
char
*
line
;
/**< beginning of current line */
size_t
remain
;
/**< remaining data at line */
char
**
matches
;
/**< active matchgroups */
unsigned
nmatches
;
/**< number of matchgroups */
char
*
selstr
;
/**< buffer for currently selected */
size_t
sellen
;
/**< strlen of selstr */
char
*
out
;
/**< output buffer (NULL if empty) */
size_t
outlen
;
/**< length of output string w/o \0 */
int64_t
usecperf
,
/**< microseconds per frame, active */
origusecperf
,
/**< microseconds per frame, from app */
start
,
/**< start time */
end
;
/**< end time */
int64_t
delta
[
MAXDELTA
];
/**< hist of last times for delta */
asa_import_callback
*
cb
;
/**< commit callback */
void
*
cb_arg
;
/**< callback argument */
};
#define iargs struct asa_import_state *state, struct asa_import_insn *insn
/** asa instruction function.
* @param state import state
* @param insn instruction to execute
* @return status code.\n
* 0: continue
* -1: restart from beginning
* >0: break level
*/
typedef
int
(
*
asa_import_func
)(
iargs
);
static
int
asai_commit
(
iargs
);
static
int
asai_discard
(
iargs
);
static
int
asai_break
(
iargs
);
static
int
asai_select
(
iargs
);
static
int
asai_sg
(
iargs
);
static
int
asai_sgu
(
iargs
);
static
int
asai_append
(
iargs
);
static
int
asai_fps
(
iargs
);
static
int
asai_show
(
iargs
);
static
int
asai_hide
(
iargs
);
static
int
asai_child
(
iargs
);
#undef iargs
/** vm functions. KEEP IN SYNC WITH imports.h! */
static
const
asa_import_func
importfuncs
[]
=
{
asai_commit
,
asai_discard
,
asai_break
,
asai_select
,
asai_sg
,
asai_sgu
,
asai_append
,
asai_fps
,
asai_show
,
asai_hide
,
asai_child
};
#define ASAI_MAX (unsigned)(sizeof(importfuncs) / sizeof(importfuncs[0]))
struct
asa_import_detect
*
asa_det_first
=
NULL
,
**
asa_det_last
=
&
asa_det_first
;
struct
asa_import_format
*
asa_fmt_first
=
NULL
,
**
asa_fmt_last
=
&
asa_fmt_first
;
/** asa_imports_crosslink - resolve references in imports file.
* updates asa_import_format.prevtgt, asa_import_format.nexttgt,
* asa_import_detect.fmt
*/
static
void
asa_imports_crosslink
(
void
)
{
struct
asa_import_format
*
fmt
,
*
fmt2
;
struct
asa_import_detect
*
det
;
for
(
fmt
=
asa_fmt_first
;
fmt
;
fmt
=
fmt
->
next
)
{
for
(
fmt2
=
fmt
->
next
;
fmt2
;
fmt2
=
fmt2
->
next
)
if
(
!
strcmp
(
fmt
->
name
,
fmt2
->
name
))
{
fmt
->
nexttgt
=
fmt2
;
fmt2
->
prevtgt
=
fmt
;
break
;
}
}
for
(
det
=
asa_det_first
;
det
;
det
=
det
->
next
)
{
det
->
fmt
=
NULL
;
for
(
fmt
=
asa_fmt_first
;
fmt
;
fmt
=
fmt
->
next
)
if
(
!
strcmp
(
det
->
name
,
fmt
->
name
))
{
det
->
fmt
=
fmt
;
break
;
}
}
}
/** asa_imports_detect - autodetect subtitle format.
* @param data pointer to subtitle byte data
* @param datalen byte length of data
* @return the detect structure that hit or NULL if detection failed
*/
struct
asa_import_detect
*
asa_imports_detect
(
const
void
*
data
,
size_t
dlen
)
{
struct
asa_import_detect
*
det
;
const
char
*
d
=
(
const
char
*
)
data
;
int
v
[
64
];
if
(
dlen
>
2048
)
dlen
=
2048
;
for
(
det
=
asa_det_first
;
det
;
det
=
det
->
next
)
if
(
pcre_exec
(
det
->
re
.
pcre
,
NULL
,
d
,
dlen
,
0
,
0
,
v
,
64
)
>=
0
)
return
det
;
return
NULL
;
}
/** asai_run_insns - execute a list of instructions.
* @see asa_import_func */
static
int
asai_run_insns
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
struct
asa_import_insn
*
inow
=
insn
,
preload
;
int
rv
,
repeating
=
0
;
preload
.
next
=
insn
;
for
(;
inow
;
inow
=
inow
->
next
)
{
if
(
repeating
&&
inow
->
insn
!=
ASAI_CHILD
)
continue
;
if
(
inow
->
insn
>=
ASAI_MAX
)
continue
;
rv
=
importfuncs
[
inow
->
insn
](
state
,
inow
);
if
(
rv
==
-
1
)
{
inow
=
&
preload
;
continue
;
}
if
(
rv
>
0
)
return
rv
-
1
;
}
/* ran through everything, let's try another round */
return
-
1
;
}
/** asai_commit - commit a block to the user.
* @see asa_import_func */
static
int
asai_commit
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
int
rv
=
0
;
if
(
!
state
->
out
)
return
0
;
if
(
state
->
outlen
>
0
)
rv
=
state
->
cb
(
state
->
demux
,
state
->
cb_arg
,
state
->
start
,
state
->
end
,
state
->
out
,
state
->
outlen
);
xfree
(
state
->
out
);
state
->
out
=
NULL
;
state
->
outlen
=
0
;
if
(
rv
)
return
INT_MAX
;
return
0
;
}
/** asai_discard - clear the buffer without committing.
* @see asa_import_func */
static
int
asai_discard
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
if
(
!
state
->
out
)
return
0
;
xfree
(
state
->
out
);
state
->
out
=
NULL
;
state
->
outlen
=
0
;
return
0
;
}
/** asai_break - jump out of child.
* @see asa_import_func */
static
int
asai_break
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
return
insn
->
v
.
break_depth
;
}
/** asai_select - choose a match group to be the active one.
* @see asa_import_func */
static
int
asai_select
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
if
(
insn
->
v
.
select
<
0
||
(
unsigned
)
insn
->
v
.
select
>=
state
->
nmatches
)
{
msg_Err
(
state
->
demux
,
"import script trying to "
"reference group %d, maximum is %d"
,
insn
->
v
.
select
,
state
->
nmatches
);
return
0
;
}
if
(
state
->
selstr
)
xfree
(
state
->
selstr
);
state
->
selstr
=
xstrdup
(
state
->
matches
[
insn
->
v
.
select
]);
state
->
sellen
=
strlen
(
state
->
selstr
);
return
0
;
}
#include <stddef.h>
static
ptrdiff_t
asai_process_replace
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
,
int
*
v
,
int
rv
)
{
struct
asa_repl
*
r
;
char
*
newstr
;
ptrdiff_t
newpos
,
firstold
;
size_t
newstr_size
;
newstr_size
=
v
[
0
]
*
2
;
newstr
=
(
char
*
)
xmalloc
(
newstr_size
);
memcpy
(
newstr
,
state
->
selstr
,
v
[
0
]);
newpos
=
v
[
0
];
for
(
r
=
insn
->
v
.
sg
.
repl
;
r
;
r
=
r
->
next
)
{
size_t
avail
=
newstr_size
-
newpos
,
need
;
const
char
*
src
;
if
(
r
->
group
>=
rv
)
{
msg_Err
(
state
->
demux
,
"import script trying to replace by "
"reference group %d, maximum is %d"
,
r
->
group
,
rv
);
continue
;
}
if
(
r
->
group
>=
0
)
{
need
=
v
[
r
->
group
*
2
+
1
]
-
v
[
r
->
group
*
2
];
src
=
state
->
selstr
+
v
[
r
->
group
*
2
];
}
else
{
need
=
strlen
(
r
->
text
);
src
=
r
->
text
;
}
if
(
need
>
avail
)
{
newstr_size
+=
need
-
avail
+
256
;
newstr
=
(
char
*
)
xrealloc
(
newstr
,
newstr_size
);
}
memcpy
(
newstr
+
newpos
,
src
,
need
);
newpos
+=
need
;
}
firstold
=
newpos
;
newstr_size
=
newpos
+
state
->
sellen
-
v
[
1
];
newstr
=
(
char
*
)
xrealloc
(
newstr
,
newstr_size
+
1
);
memcpy
(
newstr
+
newpos
,
state
->
selstr
+
v
[
1
],
state
->
sellen
-
v
[
1
]
+
1
);
state
->
selstr
=
newstr
;
state
->
sellen
=
newstr_size
;
return
firstold
;
}
/** asai_sg - search and replace.
* @see asa_import_func */
static
int
asai_sg
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
int
rv
,
v
[
MAXGROUP
*
2
];
char
*
oldstr
;
ptrdiff_t
s
=
0
;
if
(
!
state
->
selstr
)
return
0
;
while
((
unsigned
)
s
<
state
->
sellen
&&
(
rv
=
pcre_exec
(
insn
->
v
.
sg
.
regex
.
pcre
,
NULL
,
state
->
selstr
,
state
->
sellen
,
s
,
0
,
v
,
MAXGROUP
*
2
))
>=
0
)
{
oldstr
=
state
->
selstr
;
s
=
asai_process_replace
(
state
,
insn
,
v
,
rv
);
xfree
(
oldstr
);
}
return
0
;
}
/** asai_chunk_alloc - allocate composite chunk.
* @see asa_import_func */
static
inline
char
**
asai_chunk_alloc
(
char
**
old
,
int
*
v
,
int
rv
)
{
size_t
s
=
rv
*
sizeof
(
char
*
);
int
i
;
for
(
i
=
0
;
i
<
rv
;
i
++
)
s
+=
v
[
i
*
2
+
1
]
-
v
[
i
*
2
]
+
1
;
return
(
char
**
)
xrealloc
(
old
,
s
);
}
/** asai_set_matches - load result from pcre_exec into matches */
static
void
asai_set_matches
(
struct
asa_import_state
*
state
,
const
char
*
src
,
int
*
v
,
int
rv
)
{
unsigned
i
;
char
*
dst
;
state
->
matches
=
asai_chunk_alloc
(
state
->
matches
,
v
,
rv
);
state
->
nmatches
=
rv
;
dst
=
(
char
*
)(
state
->
matches
+
rv
);
for
(
i
=
0
;
i
<
state
->
nmatches
;
i
++
)
{
size_t
len
=
v
[
2
*
i
+
1
]
-
v
[
2
*
i
];
state
->
matches
[
i
]
=
dst
;
memcpy
(
dst
,
src
+
v
[
2
*
i
],
len
);
dst
[
len
]
=
'\0'
;
dst
+=
len
+
1
;
}
if
(
state
->
selstr
)
xfree
(
state
->
selstr
);
state
->
selstr
=
xstrdup
(
state
->
matches
[
0
]);
state
->
sellen
=
strlen
(
state
->
selstr
);
}
/** asai_sgu - replace one time and update matches.
* @see asa_import_func */
static
int
asai_sgu
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
int
rv
,
v
[
MAXGROUP
*
2
];
char
*
oldstr
;
if
(
!
state
->
selstr
)
return
0
;
if
((
rv
=
pcre_exec
(
insn
->
v
.
sg
.
regex
.
pcre
,
NULL
,
state
->
selstr
,
state
->
sellen
,
0
,
0
,
v
,
MAXGROUP
*
2
))
>=
0
)
{
oldstr
=
state
->
selstr
;
asai_process_replace
(
state
,
insn
,
v
,
rv
);
asai_set_matches
(
state
,
oldstr
,
v
,
rv
);
xfree
(
oldstr
);
}
return
0
;
}
/** asai_append - append selected string to output buffer.
* @see asa_import_func */
static
int
asai_append
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
state
->
out
=
(
char
*
)
xrealloc
(
state
->
out
,
state
->
outlen
+
state
->
sellen
+
1
);
memcpy
(
state
->
out
+
state
->
outlen
,
state
->
selstr
,
state
->
sellen
);
state
->
outlen
+=
state
->
sellen
;
state
->
out
[
state
->
outlen
]
=
'\0'
;
return
0
;
}
/** asai_fps - override fps.
* @see asa_import_func */
static
int
asai_fps
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
if
(
insn
->
v
.
fps_value
==
0
)
state
->
usecperf
=
state
->
origusecperf
;
else
state
->
usecperf
=
(
int64_t
)(
1000000
.
/
insn
->
v
.
fps_value
);
return
0
;
}
/** asai_gettime - walk asa_tspec and sum up the time.
* @see asa_import_func
* @return the calculated time, delta[0] on error
* also updates the delta history.
*/
static
int64_t
asai_gettime
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
struct
asa_tspec
*
tsp
;
int64_t
t
=
0
;
if
(
insn
->
v
.
tspec
.
delta_select
!=
-
1
)
{
if
(
insn
->
v
.
tspec
.
delta_select
<
MAXDELTA
)
t
+=
state
->
delta
[
insn
->
v
.
tspec
.
delta_select
];
else
msg_Err
(
state
->
demux
,
"imports: tspec "
"delta %d exceeds compiled-in maximum of %d"
,
insn
->
v
.
tspec
.
delta_select
,
MAXDELTA
);
}
for
(
tsp
=
insn
->
v
.
tspec
.
tsp
;
tsp
;
tsp
=
tsp
->
next
)
{
char
*
errptr
;
double
src
;
if
((
unsigned
)
tsp
->
group
>=
state
->
nmatches
)
{
msg_Err
(
state
->
demux
,
"imports: tspec "
"tries to access group %d, but only "
"%d groups exist"
,
tsp
->
group
,
state
->
nmatches
);
continue
;
}
if
(
!*
state
->
matches
[
tsp
->
group
])
continue
;
src
=
strtod
(
state
->
matches
[
tsp
->
group
],
&
errptr
);
if
(
*
errptr
)
msg_Warn
(
state
->
demux
,
"imports: invalid tspec '%s'"
,
state
->
matches
[
tsp
->
group
]);
t
+=
(
src
*
tsp
->
mult
*
1000000
)
+
src
*
tsp
->
fps_mult
*
state
->
usecperf
;
}
memmove
(
state
->
delta
+
1
,
state
->
delta
,
sizeof
(
state
->
delta
[
0
])
*
(
MAXDELTA
-
1
));
state
->
delta
[
0
]
=
t
;
return
t
;
}
/** asai_show - set start time.
* @see asa_import_func */
static
int
asai_show
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
state
->
start
=
asai_gettime
(
state
,
insn
);
return
0
;
}
/** asai_hide - set end time.
* @see asa_import_func */
static
int
asai_hide
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
state
->
end
=
asai_gettime
(
state
,
insn
);
return
0
;
}
/** asai_child - execute childs if we match.
* @see asa_import_func */
static
int
asai_child
(
struct
asa_import_state
*
state
,
struct
asa_import_insn
*
insn
)
{
int
rv
,
v
[
MAXGROUP
*
2
];
if
((
rv
=
pcre_exec
(
insn
->
v
.
child
.
regex
.
pcre
,
NULL
,
state
->
line
,
state
->
remain
,
0
,
0
,
v
,
MAXGROUP
*
2
))
>=
0
)
{
asai_set_matches
(
state
,
state
->
line
,
v
,
rv
);
state
->
line
+=
v
[
1
];
state
->
remain
-=
v
[
1
];
rv
=
asai_run_insns
(
state
,
insn
->
v
.
child
.
insns
);
return
rv
;
}
return
0
;
}
int
asa_import
(
demux_t
*
d
,
const
void
*
data
,
size_t
dlen
,
int64_t
usecperframe
,
struct
asa_import_detect
*
det
,
asa_import_callback
*
callback
,
void
*
arg
)
{
struct
asa_import_format
*
fmt
=
det
->
fmt
;
struct
asa_import_state
state
;
int
rv
;
memset
(
&
state
,
0
,
sizeof
(
state
));
state
.
demux
=
d
;
state
.
usecperf
=
state
.
origusecperf
=
usecperframe
;
state
.
line
=
(
const
char
*
)
data
;
state
.
remain
=
dlen
;
state
.
cb
=
callback
;
state
.
cb_arg
=
arg
;
rv
=
asai_run_insns
(
&
state
,
fmt
->
insns
);
if
(
state
.
matches
)
xfree
(
state
.
matches
);
if
(
state
.
out
)
{
callback
(
d
,
arg
,
state
.
start
,
state
.
end
,
state
.
out
,
state
.
outlen
);
xfree
(
state
.
out
);
}
if
(
state
.
selstr
)
xfree
(
state
.
selstr
);
return
rv
;
}
int
asa_pcre_compile
(
asa_pcre
*
out
,
const
char
*
str
)
{
const
char
*
err
;
int
ec
,
eo
;
out
->
pcre
=
pcre_compile2
(
str
,
0
,
&
ec
,
&
err
,
&
eo
,
NULL
);
if
(
out
->
pcre
)
return
0
;
return
1
;
}
#include "asademux_defs.h"
void
asa_init_import
()
{
static
int
setup
=
0
;
if
(
setup
)
return
;
preparse_add
();
asa_imports_crosslink
();
setup
=
1
;
}
modules/demux/asademux.h
deleted
100644 → 0
View file @
2f00cae9
/*****************************************************************************
* asademux.c: asa demuxer VM
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
*
* Originated from asa: portable digital subtitle renderer
*
* Authors: David Lamparter <equinox at diac24 dot net>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
****************************************************************************/
/****************************************************************************
* Changes from asa version:
* - headers adapted
* - external definition file support dropped
* - integer timestamps
****************************************************************************
* Please retain Linux kernel CodingStyle for sync.
* base commit d8c269b0fae9a8f8904e16e92313da165d664c74
****************************************************************************/
#ifndef _ASADEMUX_H
#define _ASADEMUX_H
#include <pcre.h>
/** parser reuse. imports-to-C uses char *, real VM uses pcre * */
typedef
union
{
pcre
*
pcre
;
char
*
str
;
}
asa_pcre
;
/** pcre_compile wrapper.
* used to allow loading differently for imports-to-C conversion.
* @param out output (parsed pcre)
* @param str regular expression string
* @return 0 on success, any other on error
*/
extern
int
asa_pcre_compile
(
asa_pcre
*
out
,
const
char
*
str
);
/** import instruction code */
enum
asa_import_insn_type
{
ASAI_COMMIT
=
0
,
/**< put current buffer as line */
ASAI_DISCARD
,
/**< discard current buffer */
ASAI_BREAK
,
/**< leave child group */
ASAI_SELECT
,
/**< select source matchgroup */
ASAI_SG
,
/**< execute search & replace on selected */
ASAI_SGU
,
/**< like ASAI_SG, but update matchgroups */
ASAI_APPEND
,
/**< append selected source to buffer */
ASAI_FPS
,
/**< set fixed fps */
ASAI_SHOW
,
/**< set start time */
ASAI_HIDE
,
/**< set end time */
ASAI_CHILD
/**< child regex match */
};
/** replacement element for ASAI_SG / ASAI_SGU */
struct
asa_repl
{
struct
asa_repl
*
next
;
/**< next element */
int
group
;
/**< -1 if fixed string, else source group */
char
*
text
;
/**< fixed string for group == -1 */
};
/** time specification element */
struct
asa_tspec
{
struct
asa_tspec
*
next
;
/**< next element */
int
group
;
/**< source matchgroup */
double
mult
,
/**< ts multiplier. 1.0 = 1 second */
fps_mult
;
/**< fps multiplier. probably 0.0 or 1.0 */
};
/** single import instruction */
struct
asa_import_insn
{
struct
asa_import_insn
*
parent
,
/**< owner insn, NULL if format child */
*
next
;
/**< next instruction */
enum
asa_import_insn_type
insn
;
/**< instruction code */
/** instruction parameters */
union
{
int
break_depth
;
/**< depth to break out */
int
select
;
/**< matchgroup to select */
/** search-replace parameters */
struct
{
asa_pcre
regex
;
/**< search for */
struct
asa_repl
*
repl
;
/**< replace by */
}
sg
;
/** time specification */
struct
{
struct
asa_tspec
*
tsp
;
/**< sources to sum up */
int
delta_select
;
/**< -1 or delta index */
}
tspec
;
/** child instructions */
struct
{
asa_pcre
regex
;
/** <if this matches... */
struct
asa_import_insn
*
insns
;
/**< do this. */
}
child
;
double
fps_value
;
/**< fixed fps value */
}
v
;
};
/** destination format of import rules */
enum
asa_import_target
{
ASAI_TARGET_TEXT
=
(
1
<<
0
),
/**< plain text packets */
ASAI_TARGET_SSA
=
(
1
<<
1
)
/**< MKV ASS packets */
};
/** importing instructions for format */
struct
asa_import_format
{
struct
asa_import_format
*
next
,
/**< next format */
*
prevtgt
,
/**< previous target */
*
nexttgt
;
/**< next target of this*/
char
*
name
;
/**< format name */
enum
asa_import_target
target
;
/**< target */
struct
asa_import_insn
*
insns
;
/**< instructions */
};
/** format detection rules */
struct
asa_import_detect
{
struct
asa_import_detect
*
next
;
/**< next rule */
asa_pcre
re
;
/**< if this matches... */
char
*
name
;
/**< use this format */
struct
asa_import_format
*
fmt
;
/**< through this pointer */
};
extern
struct
asa_import_detect
*
asa_det_first
,
**
asa_det_last
;
extern
struct
asa_import_format
*
asa_fmt_first
,
**
asa_fmt_last
;
typedef
int
(
asa_import_callback
)(
demux_t
*
demux
,
void
*
arg
,
int64_t
start
,
int64_t
stop
,
const
char
*
buffer
,
size_t
buffer_length
);
extern
struct
asa_import_detect
*
asa_imports_detect
(
const
void
*
data
,
size_t
dlen
);
extern
int
asa_import
(
demux_t
*
d
,
const
void
*
data
,
size_t
dlen
,
int64_t
usecperframe
,
struct
asa_import_detect
*
det
,
asa_import_callback
*
callback
,
void
*
arg
);
extern
void
asa_init_import
(
void
);
#endif
modules/demux/asademux_defs.h
deleted
100644 → 0
View file @
2f00cae9
/* AUTOGENERATED FILE, DO NOT EDIT */
/* generated from "./imports" on 2007-08-31T13:23:59+00:00 */
void
preparse_add
()
{
#define insn_init { NULL, NULL, 0, { 0 } }
#define det(n,r) { static struct asa_import_detect d = { NULL }; \
d.name = n; \
if (!asa_pcre_compile(&d.re, r)) \
asa_det_last = &(*asa_det_last = &d)->next; }
#define fmt_b(n,t) { static struct asa_import_format f = { NULL }; \
struct asa_import_insn *i, **i0 = NULL; \
f.name = n; f.target = t;
#define fmt_e() \
}
#define insn(n,t) { static struct asa_import_insn ii = insn_init; \
i = ⅈ *n = i; n = &i->next; i->insn = t; }
#define insn_b(n, m, t, r) { struct asa_import_insn **m;\
{ static struct asa_import_insn ii = insn_init; \
i = ⅈ ii.insn = t; \
m = &ii.v.child.insns; \
}\
if (!asa_pcre_compile(&i->v.child.regex, r)) { \
*n = i; n = &i->next;
#define insn_e() } }
#define insn_sg(n, t, r) { struct asa_repl **repl;\
{ static struct asa_import_insn ii = insn_init; \
i = ⅈ ii.insn = t; \
repl = &ii.v.sg.repl; \
}\
if (!asa_pcre_compile(&i->v.sg.regex, r)) { \
*n = i; n = &i->next;
#define insn_sge() } }
#define repl(g, t) { static struct asa_repl r = { NULL, g, t }; \
*repl = &r; repl = &r.next; }
#define insn_ts(n, t, d) { struct asa_tspec **tsp;\
{ static struct asa_import_insn ii = insn_init; \
i = ⅈ ii.insn = t; ii.v.tspec.delta_select = d; \
tsp = &ii.v.tspec.tsp; \
}\
*n = i; n = &i->next;
#define insn_tse() }
#define tsp(g, m, f) { static struct asa_tspec t = { NULL, g, m, f }; \
*tsp = &t; tsp = &t.next; }
det
(
"qttext"
,
"^
\\
{QTtext
\\
}"
)
det
(
"rtf"
,
"^
\\
{
\\\\
rtf"
)
det
(
"viplay"
,
"^
\\
{
\\
* VIPLAY"
)
det
(
"zerog"
,
"^% Zero G"
)
det
(
"sst"
,
"^SST "
)
det
(
"philips"
,
"^# PHILIPS SVCD DESIGNER"
)
det
(
"ulead"
,
"^#Ulead subtitle"
)
det
(
"sonicscenarist"
,
"^st_format
\\
s*
\\
d"
)
det
(
"dvdjunior"
,
"^Subtitle File Mark"
)
det
(
"captionsdat"
,
"^
\\
0
\\
r#"
)
det
(
"inscriber"
,
"^@@.*
\\
n@@
\\
d Created by URUSoft"
)
det
(
"ssa"
,
"(?mi)^(ScriptType:|
\\
[Script Info)"
)
det
(
"subrip"
,
"^
\\
d+
\\
s*
\\
n
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d,
\\
d
\\
d
\\
d
\\
s+-->
\\
s+
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d,
\\
d
\\
d
\\
d
\\
s*
\\
n"
)
det
(
"microdvd"
,
"^
\\
{
\\
d+
\\
}
\\
{
\\
d+
\\
}"
)
det
(
"sami"
,
"(?i)<SAMI"
)
det
(
"smil"
,
"(?i)<SMIL"
)
det
(
"smil_rt"
,
"(?i)<WINDOW"
)
det
(
"html"
,
"(?i)<HTML"
)
det
(
"jacosub"
,
"(?m)^#([DT]
\\
d+)"
)
det
(
"sasamis2k"
,
"(?m)^;(Env|Set)
\\
."
)
det
(
"phoenix"
,
"^[
\\
d]+,[
\\
d]+,
\"
.*
\"
"
)
det
(
"vkt"
,
"(?m)^
\\
{
\\
d+ .*
\\
}"
)
det
(
"e2"
,
"^
\\
[
\\
d+
\\
]
\\
[
\\
d+
\\
]"
)
det
(
"powerdivx"
,
"^
\\
{
\\
d+:
\\
d
\\
d:
\\
d
\\
d
\\
}
\\
{
\\
d+:
\\
d
\\
d:
\\
d
\\
d
\\
}"
)
det
(
"sbt"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
s*
\\
n
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
s*
\\
n
\\
s*
\\
n"
)
det
(
"karaokelrc"
,
"(?m)^
\\
[
\\
d
\\
d:
\\
d
\\
d
\\
.
\\
d
\\
d
\\
]"
)
det
(
"dks"
,
"^
\\
[
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
]"
)
det
(
"aqtitle"
,
"^-->>
\\
d+
\\
s*
\\
n"
)
det
(
"panimator"
,
"^
\\
/(c|d
\\
d+
\\
d+)
\\
s*
\\
n"
)
det
(
"tmplayer"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d,
\\
d="
)
det
(
"cap32"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d ,
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d , "
)
det
(
"not_encore"
,
"(?m)^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d "
)
det
(
"encore_ntsc"
,
"(?m)^
\\
d+
\\
d+;
\\
d+;
\\
d+;
\\
d+
\\
d+;
\\
d+;
\\
d+;
\\
d+ "
)
det
(
"encore_pal"
,
"(?m)^
\\
d+
\\
d+:
\\
d+:
\\
d+:
\\
d+
\\
d+:
\\
d+:
\\
d+:
\\
d+ "
)
det
(
"turbotitler"
,
"^
\\
d+:
\\
d
\\
d:
\\
d
\\
d
\\
.
\\
d
\\
d,
\\
d+:
\\
d
\\
d:
\\
d
\\
d
\\
.
\\
d
\\
d,"
)
det
(
"macdvdpro"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
t
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
t"
)
det
(
"powerpixel"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
t
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
r?
\\
n"
)
det
(
"ovr"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d [^[:digit:][:space:][:punct:]]"
)
det
(
"fab"
,
"^
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
s*
\\
n[^[:digit:][:space:][:punct:]]"
)
det
(
"sonicdvd"
,
"^
\\
d{4}
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d:
\\
d
\\
d "
)
det
(
"koalaplayer"
,
"(?m)^
\\
d+:
\\
d
\\
d:
\\
d
\\
d:[^[:digit:][:space:][:punct:]]"
)
det
(
"subcreator1"
,
"^
\\
d+:
\\
d
\\
d:
\\
d
\\
d
\\
.
\\
d+:"
)
fmt_b
(
"subrip"
,
2
)
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^
\\
d+
\\
s*
\\
n(
\\
d
\\
d):(
\\
d
\\
d):(
\\
d
\\
d),(
\\
d
\\
d
\\
d)
\\
s+-->
\\
s+(
\\
d
\\
d):(
\\
d
\\
d):(
\\
d
\\
d),(
\\
d
\\
d
\\
d)
\\
s*
\\
r?
\\
n"
)
insn_ts
(
i1
,
8
,
-
1
);
tsp
(
1
,
3600
.
000000
,
0
.
000000
)
tsp
(
2
,
60
.
000000
,
0
.
000000
)
tsp
(
3
,
1
.
000000
,
0
.
000000
)
tsp
(
4
,
0
.
001000
,
0
.
000000
)
insn_tse
()
insn_ts
(
i1
,
9
,
-
1
);
tsp
(
5
,
3600
.
000000
,
0
.
000000
)
tsp
(
6
,
60
.
000000
,
0
.
000000
)
tsp
(
7
,
1
.
000000
,
0
.
000000
)
tsp
(
8
,
0
.
001000
,
0
.
000000
)
insn_tse
()
insn_b
(
i1
,
i2
,
ASAI_CHILD
,
"(?s)^(.*?)
\\
s*
\\
n
\\
s*
\\
n"
)
insn
(
i2
,
ASAI_SELECT
);
i
->
v
.
select
=
1
;
insn_sg
(
i2
,
4
,
"
\\\\
"
)
repl
(
-
1
,
"
\\\\
"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"
\\
{"
)
repl
(
-
1
,
"
\\
{"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"
\\
}"
)
repl
(
-
1
,
"
\\
}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"
\\
n"
)
repl
(
-
1
,
"
\\
n"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<[Bb]>"
)
repl
(
-
1
,
"{
\\
b1}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<
\\
/[Bb]>"
)
repl
(
-
1
,
"{
\\
b0}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<[Ii]>"
)
repl
(
-
1
,
"{
\\
i1}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<
\\
/[Ii]>"
)
repl
(
-
1
,
"{
\\
i0}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<
\\
/(.*?)>"
)
repl
(
-
1
,
"{"
)
repl
(
12
,
NULL
)
repl
(
-
1
,
"3}"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"<"
)
repl
(
-
1
,
"<"
)
insn_sge
()
insn_sg
(
i2
,
4
,
">"
)
repl
(
-
1
,
">"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"&"
)
repl
(
-
1
,
"&"
)
insn_sge
()
insn_sg
(
i2
,
4
,
"^"
)
repl
(
-
1
,
",,,0,0,0,,"
)
insn_sge
()
insn
(
i2
,
6
);
insn
(
i2
,
0
);
insn
(
i2
,
ASAI_BREAK
);
i
->
v
.
break_depth
=
1
;
insn_e
()
insn_e
()
fmt_e
()
fmt_b
(
"encore_pal"
,
1
)
insn
(
i0
,
ASAI_FPS
);
i
->
v
.
fps_value
=
25
.
000000
;
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^
\\
d+ (
\\
d+):(
\\
d+):(
\\
d+):(
\\
d+) (
\\
d+):(
\\
d+):(
\\
d+):(
\\
d+) (.*(
\\
n[^
\\
d].*)*)
\\
n"
)
insn_ts
(
i1
,
8
,
-
1
);
tsp
(
1
,
3600
.
000000
,
0
.
000000
)
tsp
(
2
,
60
.
000000
,
0
.
000000
)
tsp
(
3
,
1
.
000000
,
0
.
000000
)
tsp
(
4
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn_ts
(
i1
,
9
,
-
1
);
tsp
(
5
,
3600
.
000000
,
0
.
000000
)
tsp
(
6
,
60
.
000000
,
0
.
000000
)
tsp
(
7
,
1
.
000000
,
0
.
000000
)
tsp
(
8
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn
(
i1
,
ASAI_SELECT
);
i
->
v
.
select
=
9
;
insn_sg
(
i1
,
4
,
"
\\
/
\\
/"
)
repl
(
-
1
,
"
\x0a
"
)
insn_sge
()
insn
(
i1
,
6
);
insn
(
i1
,
0
);
insn_e
()
fmt_e
()
fmt_b
(
"encore_ntsc"
,
1
)
insn
(
i0
,
ASAI_FPS
);
i
->
v
.
fps_value
=
29
.
969999
;
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^
\\
d+ (
\\
d+);(
\\
d+);(
\\
d+);(
\\
d+) (
\\
d+);(
\\
d+);(
\\
d+);(
\\
d+) (.*(
\\
n[^
\\
d].*)*)
\\
n"
)
insn_ts
(
i1
,
8
,
-
1
);
tsp
(
1
,
3600
.
000000
,
0
.
000000
)
tsp
(
2
,
60
.
000000
,
0
.
000000
)
tsp
(
3
,
1
.
000000
,
0
.
000000
)
tsp
(
4
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn_ts
(
i1
,
9
,
-
1
);
tsp
(
5
,
3600
.
000000
,
0
.
000000
)
tsp
(
6
,
60
.
000000
,
0
.
000000
)
tsp
(
7
,
1
.
000000
,
0
.
000000
)
tsp
(
8
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn
(
i1
,
ASAI_SELECT
);
i
->
v
.
select
=
9
;
insn_sg
(
i1
,
4
,
"
\\
/
\\
/"
)
repl
(
-
1
,
"
\x0a
"
)
insn_sge
()
insn
(
i1
,
6
);
insn
(
i1
,
0
);
insn_e
()
fmt_e
()
fmt_b
(
"microdvd"
,
1
)
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^
\\
{
\\
s*(
\\
d+)
\\
}
\\
{
\\
s*(
\\
d+)
\\
}(.*?)
\\
s*
\\
n"
)
insn_ts
(
i1
,
8
,
-
1
);
tsp
(
1
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn_ts
(
i1
,
9
,
-
1
);
tsp
(
2
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn
(
i1
,
ASAI_SELECT
);
i
->
v
.
select
=
3
;
insn_sg
(
i1
,
4
,
"
\\
|"
)
repl
(
-
1
,
"
\x0a
"
)
insn_sge
()
insn
(
i1
,
6
);
insn
(
i1
,
0
);
insn_e
()
fmt_e
()
fmt_b
(
"vkt"
,
1
)
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^#.*
\\
n"
)
insn_e
()
insn_b
(
i0
,
i1
,
ASAI_CHILD
,
"^{(
\\
d+) (.*)}
\\
s*
\\
n"
)
insn_ts
(
i1
,
9
,
-
1
);
tsp
(
1
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn
(
i1
,
0
);
insn_ts
(
i1
,
8
,
-
1
);
tsp
(
1
,
0
.
000000
,
1
.
000000
)
insn_tse
()
insn
(
i1
,
ASAI_SELECT
);
i
->
v
.
select
=
2
;
insn
(
i1
,
6
);
insn_e
()
fmt_e
()
}
modules/demux/subtitle_asa.c
deleted
100644 → 0
View file @
2f00cae9
/*****************************************************************************
* subtitle_asa.c: Demux for subtitle text files using the asa engine.
*****************************************************************************
* Copyright (C) 1999-2007 the VideoLAN team
* $Id$
*
* Authors: David Lamparter <equinox at videolan dot org>
*
* Originated from subtitle.c
*
* 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "config.h"
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_input.h>
#include <vlc_memory.h>
#include <vlc_demux.h>
#include "asademux.h"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
);
static
void
Close
(
vlc_object_t
*
p_this
);
#define SUB_DELAY_LONGTEXT \
N_("Apply a delay to all subtitles (in 1/10s, eg 100 means 10s).")
#define SUB_FPS_LONGTEXT \
N_("Override the normal frames per second settings. " \
"This will only affect frame-based subtitle formats without a fixed value.")
#define SUB_TYPE_LONGTEXT \
N_("Force the subtiles format. Use \"auto\", the set of supported values varies.")
vlc_module_begin
()
set_shortname
(
N_
(
"Subtitles (asa demuxer)"
))
set_description
(
N_
(
"Text subtitles parser"
)
)
set_capability
(
"demux"
,
50
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_DEMUX
)
add_float
(
"sub-fps"
,
0
.
0
,
NULL
,
N_
(
"Frames per second"
),
SUB_FPS_LONGTEXT
,
true
)
add_integer
(
"sub-delay"
,
0
,
NULL
,
N_
(
"Subtitles delay"
),
SUB_DELAY_LONGTEXT
,
true
)
add_string
(
"sub-type"
,
"auto"
,
NULL
,
N_
(
"Subtitles format"
),
SUB_TYPE_LONGTEXT
,
true
)
set_callbacks
(
Open
,
Close
)
add_shortcut
(
"asademux"
)
vlc_module_end
()
/*****************************************************************************
* Prototypes:
*****************************************************************************/
typedef
struct
{
int64_t
i_start
;
int64_t
i_stop
;
char
*
psz_text
;
}
subtitle_t
;
struct
demux_sys_t
{
int
i_type
;
es_out_id_t
*
es
;
int64_t
i_next_demux_date
;
int64_t
i_microsecperframe
;
char
*
psz_header
;
int
i_subtitle
;
int
i_subtitles
;
int
i_subs_alloc
;
subtitle_t
*
subtitle
;
int64_t
i_length
;
};
static
int
Demux
(
demux_t
*
);
static
int
Control
(
demux_t
*
,
int
,
va_list
);
static
void
Fix
(
demux_t
*
);
static
int
ProcessLine
(
demux_t
*
,
void
*
,
int64_t
,
int64_t
,
const
char
*
,
size_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
;
float
f_fps
;
char
*
psz_type
;
int64_t
i_ssize
;
void
*
p_data
;
struct
asa_import_detect
*
p_detect
=
NULL
;
if
(
strcmp
(
p_demux
->
psz_demux
,
"asademux"
)
)
{
return
VLC_EGENERIC
;
}
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_control
=
Control
;
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
if
(
!
p_sys
)
return
VLC_ENOMEM
;
p_sys
->
psz_header
=
NULL
;
p_sys
->
i_subtitle
=
0
;
p_sys
->
i_subtitles
=
0
;
p_sys
->
i_subs_alloc
=
0
;
p_sys
->
subtitle
=
NULL
;
p_sys
->
i_microsecperframe
=
40000
;
/* Get the 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
);
/* Check for override of 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
);
msg_Dbg
(
p_demux
,
"Override subtitle fps %f"
,
f_fps
);
}
/* Get or probe the type */
psz_type
=
var_CreateGetString
(
p_demux
,
"sub-type"
);
if
(
*
psz_type
)
{
for
(
p_detect
=
asa_det_first
;
p_detect
;
p_detect
=
p_detect
->
next
)
{
if
(
!
strcmp
(
p_detect
->
name
,
psz_type
)
)
{
break
;
}
}
if
(
!
p_detect
)
{
msg_Warn
(
p_demux
,
"unknown sub-type
\"
%s
\"
"
,
psz_type
);
}
}
free
(
psz_type
);
/* Probe if unknown type */
if
(
!
p_detect
)
{
int
i_size
;
const
uint8_t
*
p
;
msg_Dbg
(
p_demux
,
"autodetecting subtitle format"
);
i_size
=
stream_Peek
(
p_demux
->
s
,
&
p
,
4096
);
if
(
i_size
<=
0
)
{
msg_Warn
(
p_demux
,
"cannot process subtitles (no data?)"
);
return
VLC_EGENERIC
;
}
p_detect
=
asa_imports_detect
(
p
,
i_size
);
}
if
(
!
p_detect
)
{
msg_Err
(
p_demux
,
"failed to recognize subtitle type"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
if
(
!
p_detect
->
fmt
)
{
msg_Err
(
p_demux
,
"detected %s subtitle format, no asa support"
,
p_detect
->
name
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_demux
,
"detected %s subtitle format"
,
p_detect
->
name
);
stream_Control
(
p_demux
->
s
,
STREAM_GET_SIZE
,
&
i_ssize
);
p_data
=
malloc
(
i_ssize
);
if
(
!
p_data
)
{
free
(
p_sys
);
return
VLC_ENOMEM
;
}
if
(
stream_Read
(
p_demux
->
s
,
&
p_data
,
i_ssize
)
!=
i_ssize
)
{
msg_Err
(
p_demux
,
"subtitle stream read error"
);
free
(
p_data
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
asa_import
(
p_demux
,
p_data
,
i_ssize
,
p_sys
->
i_microsecperframe
,
p_detect
,
ProcessLine
,
NULL
);
free
(
p_data
);
msg_Dbg
(
p_demux
,
"loaded %d subtitles"
,
p_sys
->
i_subtitles
);
/* Fix subtitle (order and time) *** */
Fix
(
p_demux
);
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
+
VLC_TS_0
;
}
/* *** add subtitle ES *** */
if
(
p_detect
->
fmt
->
target
==
ASAI_TARGET_SSA
)
{
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_CODEC_SSA
);
}
else
{
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_CODEC_SUBT
);
}
p_sys
->
es
=
es_out_Add
(
p_demux
->
out
,
&
fmt
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* ProcessLine: Callback for asa_import, fed one line
* (note: return values are not kept. nonzero signals abort to asa_import)
*****************************************************************************/
static
int
ProcessLine
(
demux_t
*
p_demux
,
void
*
p_arg
,
int64_t
i_start
,
int64_t
i_stop
,
const
char
*
p_buffer
,
size_t
i_buffer_length
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
subtitle_t
*
p_subtitle
;
char
*
psz_text
;
VLC_UNUSED
(
p_arg
);
if
(
p_sys
->
i_subtitles
>=
p_sys
->
i_subs_alloc
)
{
p_sys
->
i_subs_alloc
+=
500
;
if
(
!
(
p_sys
->
subtitle
=
realloc_or_free
(
p_sys
->
subtitle
,
sizeof
(
subtitle_t
)
*
p_sys
->
i_subs_alloc
)
)
)
{
return
VLC_ENOMEM
;
}
}
p_subtitle
=
&
p_sys
->
subtitle
[
p_sys
->
i_subtitles
];
psz_text
=
malloc
(
i_buffer_length
+
1
);
if
(
!
psz_text
)
return
VLC_ENOMEM
;
memcpy
(
psz_text
,
p_buffer
,
i_buffer_length
);
psz_text
[
i_buffer_length
]
=
'\0'
;
p_subtitle
->
i_start
=
i_start
;
p_subtitle
->
i_stop
=
i_stop
;
p_subtitle
->
psz_text
=
psz_text
;
p_sys
->
i_subtitles
++
;
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
;
int
i
;
for
(
i
=
0
;
i
<
p_sys
->
i_subtitles
;
i
++
)
free
(
p_sys
->
subtitle
[
i
].
psz_text
);
free
(
p_sys
->
subtitle
);
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_ATTACHMENTS
:
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
-
var_GetTime
(
p_demux
->
p_parent
,
"spu-delay"
);;
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
)
{
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
=
VLC_TS_0
+
p_sys
->
subtitle
[
p_sys
->
i_subtitle
].
i_start
;
p_block
->
i_dts
=
VLC_TS_0
+
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
>
VLC_TS_INVALID
)
{
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
,
p_block
);
}
else
{
block_Release
(
p_block
);
}
p_sys
->
i_subtitle
++
;
}
/* */
p_sys
->
i_next_demux_date
=
0
;
return
1
;
}
/*****************************************************************************
* Fix: fix time stamp and order of subtitle
*****************************************************************************/
static
void
Fix
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
bool
b_done
;
int
i_index
;
/* *** fix order (to be sure...) *** */
/* We suppose that there are near in order and this durty bubble sort
* wont take too much time
*/
do
{
b_done
=
true
;
for
(
i_index
=
1
;
i_index
<
p_sys
->
i_subtitles
;
i_index
++
)
{
if
(
p_sys
->
subtitle
[
i_index
].
i_start
<
p_sys
->
subtitle
[
i_index
-
1
].
i_start
)
{
subtitle_t
sub_xch
;
memcpy
(
&
sub_xch
,
p_sys
->
subtitle
+
i_index
-
1
,
sizeof
(
subtitle_t
)
);
memcpy
(
p_sys
->
subtitle
+
i_index
-
1
,
p_sys
->
subtitle
+
i_index
,
sizeof
(
subtitle_t
)
);
memcpy
(
p_sys
->
subtitle
+
i_index
,
&
sub_xch
,
sizeof
(
subtitle_t
)
);
b_done
=
false
;
}
}
}
while
(
!
b_done
);
}
po/POTFILES.in
View file @
62487ef4
...
...
@@ -435,9 +435,6 @@ modules/control/rc.c
modules/control/unimotion.c
modules/control/unimotion.h
modules/demux/aiff.c
modules/demux/asademux.c
modules/demux/asademux.h
modules/demux/asademux_defs.h
modules/demux/asf/asf.c
modules/demux/asf/libasf.c
modules/demux/asf/libasf.h
...
...
@@ -519,7 +516,6 @@ modules/demux/rawvid.c
modules/demux/real.c
modules/demux/smf.c
modules/demux/subtitle.c
modules/demux/subtitle_asa.c
modules/demux/ts.c
modules/demux/tta.c
modules/demux/ty.c
...
...
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