summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/changes.rst1
-rw-r--r--DOCS/man/en/options.rst19
-rw-r--r--Makefile1
-rw-r--r--core/cfg-mplayer.h5
-rw-r--r--core/command.c1
-rw-r--r--core/mp_core.h10
-rw-r--r--core/mplayer.c125
-rw-r--r--core/mplayer.h2
-rw-r--r--demux/demux.c10
-rw-r--r--sub/find_subfiles.c53
-rw-r--r--sub/find_subfiles.h1
-rw-r--r--sub/spudec.c28
-rw-r--r--sub/vobsub.c980
-rw-r--r--sub/vobsub.h43
14 files changed, 74 insertions, 1205 deletions
diff --git a/DOCS/man/en/changes.rst b/DOCS/man/en/changes.rst
index c2cceddcfc..82066cb75c 100644
--- a/DOCS/man/en/changes.rst
+++ b/DOCS/man/en/changes.rst
@@ -112,6 +112,7 @@ Command line switches
-sub-fuzziness --autosub-match
-subfont-text-scale --sub-scale
-spugauss --sub-gauss
+ -vobsub --sub (pass the .idx file)
=================================== ===================================
input.conf and slave commands
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index 1e24d2b071..4f2acc5793 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -205,6 +205,8 @@
:fuzzy: Load all subs containing movie name.
:all: Load all subs in the current and ``--sub-paths`` directories.
+ (Default: exact.)
+
--autosync=<factor>
Gradually adjusts the A/V sync based on audio delay measurements.
Specifying ``--autosync=0``, the default, will cause frame timing to be
@@ -779,10 +781,6 @@
*NOTE*: This option only works if the underlying media supports seeking
(i.e. not with stdin, pipe, etc).
---ifo=<file>
- Indicate the VOBsub IFO file that will be used to load palette and frame
- size for VOBsub subtitles.
-
--ignore-start
Matters with the builtin AVI demuxer only, which is not enabled by default.
Ignore the specified starting time for streams in AVI files. This
@@ -1692,7 +1690,7 @@
--sid=<ID|auto|no>
Display the subtitle stream specified by <ID> (0-31). ``auto`` selects the
default, ``no`` disables subtitles.
- See also ``--slang``, ``--vobsubid``, ``--no-sub``.
+ See also ``--slang``, ``--no-sub``.
--slang=<languagecode[,languagecode,...]>
Specify a priority list of subtitle languages to use. Different container
@@ -1883,7 +1881,9 @@
Open the given file with a demuxer, and use its subtitle streams. Same as
``--audiofile``, but for subtitle streams.
- Use ``--sub`` for normal text subtitle files.
+ *NOTE*: use ``--sub`` for subtitle files. This option is useless, unless
+ you want to force libavformat subtitle parsers instead of libass or
+ internal subtitle parsers.
--subfps=<rate>
Specify the framerate of the subtitle file (default: movie fps).
@@ -2210,13 +2210,6 @@
configuration files specifying a list of fallbacks may make sense. See
`video_outputs` for details and descriptions of available drivers.
---vobsub=<file>
- Specify a VOBsub file to use for subtitles. Has to be the full pathname
- without extension, i.e. without the ``.idx``, ``.ifo`` or ``.sub``.
-
---vobsubid=<0-31>
- Specify the VOBsub subtitle ID.
-
--volstep=<0-100>
Set the step size of mixer volume changes in percent of the whole range
(default: 3).
diff --git a/Makefile b/Makefile
index e5808bc3c4..16299e3744 100644
--- a/Makefile
+++ b/Makefile
@@ -225,7 +225,6 @@ SOURCES = talloc.c \
sub/sub.c \
sub/subassconvert.c \
sub/subreader.c \
- sub/vobsub.c \
video/csputils.c \
video/fmt-conversion.c \
video/image_writer.c \
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 310405dee2..6534672223 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -498,8 +498,6 @@ const m_option_t common_opts[] = {
{"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
OPT_MAKE_FLAGS("autosub", sub_auto, 0),
{"sub-forced-only", &forced_subs_only, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- // specify IFO file for VOBSUB subtitle
- {"ifo", &spudec_ifo, CONF_TYPE_STRING, 0, 0, 0, NULL},
// enable Closed Captioning display
{"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL},
{"sub-no-text-pp", &sub_no_text_pp, CONF_TYPE_FLAG, 0, 0, 1, NULL},
@@ -649,9 +647,6 @@ const m_option_t mplayer_opts[]={
OPT_INTRANGE("osd-duration", osd_duration, 0, 0, 3600000),
OPT_MAKE_FLAGS("osd-fractions", osd_fractions, 0),
- OPT_STRING("vobsub", vobsub_name, 0),
- {"vobsubid", &vobsub_id, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
-
{"sstep", &step_sec, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL},
OPT_CHOICE("framedrop", frame_dropping, 0,
diff --git a/core/command.c b/core/command.c
index 7f2940fbaa..1e4ccd88bc 100644
--- a/core/command.c
+++ b/core/command.c
@@ -52,7 +52,6 @@
#include "video/decode/dec_video.h"
#include "audio/decode/dec_audio.h"
#include "osdep/strsep.h"
-#include "sub/vobsub.h"
#include "sub/spudec.h"
#include "core/path.h"
#include "sub/ass_mp.h"
diff --git a/core/mp_core.h b/core/mp_core.h
index f633f3481f..92803d2dd0 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -35,7 +35,6 @@
#define INITIALIZED_GETCH2 8
#define INITIALIZED_SPUDEC 32
#define INITIALIZED_STREAM 64
-#define INITIALIZED_VOBSUB 256
#define INITIALIZED_DEMUXER 512
#define INITIALIZED_ACODEC 1024
#define INITIALIZED_VCODEC 2048
@@ -43,12 +42,6 @@
#define INITIALIZED_ALL 0xFFFF
-#define SUB_SOURCE_SUBS 0
-#define SUB_SOURCE_VOBSUB 1
-#define SUB_SOURCE_DEMUX 2
-#define SUB_SOURCES 3
-
-
enum stop_play_reason {
KEEP_PLAYING = 0, // must be 0, numeric values of others do not matter
AT_END_OF_FILE, // file has ended normally, prepare to play next
@@ -120,9 +113,6 @@ struct track {
// External text subtitle using non-libass subtitle renderer.
struct sub_data *subdata;
-
- // External image subtitle (data is in vo_vobsub). 0 if not set.
- int vobsub_id_plus_one;
};
typedef struct MPContext {
diff --git a/core/mplayer.c b/core/mplayer.c
index 81302f284f..5ef73de0f7 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -92,7 +92,6 @@
#include "core/codec-cfg.h"
#include "sub/spudec.h"
-#include "sub/vobsub.h"
#include "osdep/getch2.h"
#include "osdep/timer.h"
@@ -217,8 +216,6 @@ char **video_fm_list; // override video codec family
// use this to allow dvdnav to follow -slang across stream resets,
// in particular the subtitle ID for a language changes
int dvdsub_lang_id;
-int vobsub_id = -1;
-static char *spudec_ifo = NULL;
int forced_subs_only = 0;
// A-V sync:
@@ -246,6 +243,9 @@ int use_filedir_conf;
static void reset_subtitles(struct MPContext *mpctx);
static void reinit_subs(struct MPContext *mpctx);
+static struct track *open_external_file(struct MPContext *mpctx, char *filename,
+ char *demuxer_name, int stream_cache,
+ enum stream_type filter);
static float get_relative_time(struct MPContext *mpctx)
{
@@ -605,13 +605,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
getch2_disable();
}
- if (mask & INITIALIZED_VOBSUB) {
- mpctx->initialized_flags &= ~INITIALIZED_VOBSUB;
- if (vo_vobsub)
- vobsub_close(vo_vobsub);
- vo_vobsub = NULL;
- }
-
if (mask & INITIALIZED_SPUDEC) {
mpctx->initialized_flags &= ~INITIALIZED_SPUDEC;
spudec_free(vo_spudec);
@@ -1001,6 +994,10 @@ struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
if (!sh && !subd) {
+ struct track *ext = open_external_file(mpctx, filename, NULL, 0,
+ STREAM_SUB);
+ if (ext)
+ return ext;
mp_tmsg(MSGT_CPLAYER, noerr ? MSGL_WARN : MSGL_ERR,
"Cannot load subtitles: %s\n", filename);
return NULL;
@@ -1030,13 +1027,6 @@ void init_vo_spudec(struct MPContext *mpctx)
if (!mpctx->sh_video)
return;
- if (spudec_ifo) {
- unsigned int palette[16];
- if (vobsub_parse_ifo(NULL, spudec_ifo, palette, &width, &height,
- 1, -1, NULL) >= 0)
- vo_spudec = spudec_new_scaled(palette, width, height, NULL, 0);
- }
-
width = mpctx->sh_video->disp_w;
height = mpctx->sh_video->disp_h;
@@ -1796,26 +1786,14 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
}
// DVD sub:
- if ((track->vobsub_id_plus_one || type == 'v')
- && !(sh_sub && sh_sub->active))
- {
+ if (type == 'v' && !(sh_sub && sh_sub->active)) {
int timestamp;
// Get a sub packet from the demuxer (or the vobsub.c thing, which
// should be a demuxer, but isn't).
while (1) {
// Vobsub
len = 0;
- if (track->vobsub_id_plus_one) {
- if (curpts_s >= 0) {
- len = vobsub_get_packet(vo_vobsub, curpts_s,
- (void **)&packet, &timestamp);
- if (len > 0)
- mp_dbg(MSGT_CPLAYER, MSGL_V, "\rVOB sub: len=%d "
- "v_pts=%5.3f v_timer=%5.3f sub=%5.3f ts=%d \n",
- len, refpts_s, sh_video->timer,
- timestamp / 90000.0, timestamp);
- }
- } else {
+ {
// DVD sub
assert(d_sub->sh == sh_sub);
len = ds_get_packet_sub(d_sub, (unsigned char **)&packet);
@@ -1843,7 +1821,7 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
// PGS subtitles.
if (!vo_spudec)
vo_spudec = spudec_new(NULL);
- if (track->vobsub_id_plus_one || timestamp >= 0)
+ if (timestamp >= 0)
spudec_assemble(vo_spudec, packet, len, timestamp);
}
} else if (d_sub && (is_text_sub(type) || (sh_sub && sh_sub->active))) {
@@ -1854,6 +1832,9 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
while (d_sub->first) {
double subpts_s = ds_get_next_pts(d_sub);
if (subpts_s > curpts_s) {
+ mp_dbg(MSGT_CPLAYER, MSGL_V,
+ "Sub early: c_pts=%5.3f s_pts=%5.3f\n",
+ curpts_s, subpts_s);
// Libass handled subs can be fed to it in advance
if (!opts->ass_enabled || !is_text_sub(type))
break;
@@ -1874,10 +1855,8 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
}
if (sh_sub && sh_sub->active) {
sub_decode(sh_sub, mpctx->osd, packet, len, subpts_s, duration);
- continue;
- }
- // is_text_sub() case
- if (subpts_s != MP_NOPTS_VALUE) {
+ } else if (subpts_s != MP_NOPTS_VALUE) {
+ // text sub
if (duration < 0)
sub_clear_text(&mpctx->subs, MP_NOPTS_VALUE);
if (type == 'a') { // ssa/ass subs without libass => convert to plaintext
@@ -2000,8 +1979,6 @@ static void reinit_subs(struct MPContext *mpctx)
init_demux_stream(mpctx, STREAM_SUB);
- vobsub_id = -1;
-
if (!track)
return;
@@ -2023,9 +2000,7 @@ static void reinit_subs(struct MPContext *mpctx)
mpctx->initialized_flags |= INITIALIZED_SUB;
- if (track->vobsub_id_plus_one) {
- vobsub_id = track->vobsub_id_plus_one - 1;
- } else if (track->subdata || track->sh_sub) {
+ if (track->subdata || track->sh_sub) {
#ifdef CONFIG_ASS
if (opts->ass_enabled && track->sh_sub)
sub_init(track->sh_sub, mpctx->osd);
@@ -2717,7 +2692,7 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
mpctx->delay = 0;
mpctx->time_frame = 0;
// Not all demuxers set d_video->pts during seek, so this value
- // (which is used by at least vobsub code below) may be completely
+ // (which was used by at least vobsub code below) may be completely
// wrong (probably 0).
mpctx->sh_video->pts = mpctx->sh_video->ds->pts + mpctx->video_offset;
mpctx->video_pts = mpctx->sh_video->pts;
@@ -2733,10 +2708,6 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
reset_subtitles(mpctx);
- if (vo_vobsub && mpctx->sh_video) {
- vobsub_seek(vo_vobsub, mpctx->sh_video->pts);
- }
-
mpctx->restart_playback = true;
mpctx->hrseek_active = false;
mpctx->hrseek_framedrop = false;
@@ -3600,7 +3571,6 @@ static int match_lang(char **langs, char *lang)
* Sort tracks based on the following criteria, and pick the first:
* 0) track matches tid (always wins)
* 1) track is external
- * 1.5) track is external and vobsub and has higher vobsub ID
* 2) earlier match in lang list
* 3) track is marked default
* 4) lower track number
@@ -3618,8 +3588,6 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs)
return l1 > l2;
if (t1->default_track != t2->default_track)
return t1->default_track;
- if (t1->vobsub_id_plus_one != t2->vobsub_id_plus_one)
- return t1->vobsub_id_plus_one >= t2->vobsub_id_plus_one;
return t1->user_tid <= t2->user_tid;
}
static struct track *select_track(struct MPContext *mpctx,
@@ -3680,45 +3648,6 @@ static void init_input(struct MPContext *mpctx)
stream_set_interrupt_callback(mp_input_check_interrupt, mpctx->input);
}
-static void open_vobsubs_from_options(struct MPContext *mpctx)
-{
- if (mpctx->opts.vobsub_name) {
- vo_vobsub = vobsub_open(mpctx->opts.vobsub_name, spudec_ifo, 1, &vo_spudec);
- if (vo_vobsub == NULL)
- mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Cannot load subtitles: %s\n",
- mpctx->opts.vobsub_name);
- } else if (mpctx->opts.sub_auto) {
- char **vob = find_vob_subtitles(&mpctx->opts, mpctx->filename);
- for (int i = 0; i < MP_TALLOC_ELEMS(vob); i++) {
- vo_vobsub = vobsub_open(vob[i], spudec_ifo, 0, &vo_spudec);
- if (vo_vobsub)
- break;
- }
- talloc_free(vob);
- }
- if (vo_vobsub) {
- mpctx->initialized_flags |= INITIALIZED_VOBSUB;
- // TODO: let frontend do the selection
- vobsub_set_from_lang(vo_vobsub, mpctx->opts.sub_lang);
- mp_property_do("sub-forced-only", M_PROPERTY_SET, &forced_subs_only,
- mpctx);
-
- for (int i = 0; i < vobsub_get_indexes_count(vo_vobsub); i++) {
- int id = vobsub_get_id_by_index(vo_vobsub, i);
- struct track *track = talloc_ptrtype(NULL, track);
- *track = (struct track) {
- .type = STREAM_SUB,
- .user_tid = find_new_tid(mpctx, STREAM_SUB),
- .demuxer_id = -1,
- .lang = talloc_strdup(track, vobsub_get_id(vo_vobsub, id)),
- .is_external = true,
- .vobsub_id_plus_one = id + 1,
- };
- MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
- }
- }
-}
-
static void open_subtitles_from_options(struct MPContext *mpctx)
{
// after reading video params we should load subtitles because
@@ -3738,13 +3667,13 @@ static void open_subtitles_from_options(struct MPContext *mpctx)
}
}
-static void open_external_file(struct MPContext *mpctx, char *filename,
- char *demuxer_name, int stream_cache,
- enum stream_type filter)
+static struct track *open_external_file(struct MPContext *mpctx, char *filename,
+ char *demuxer_name, int stream_cache,
+ enum stream_type filter)
{
struct MPOpts *opts = &mpctx->opts;
if (!filename)
- return;
+ return NULL;
int format = 0;
struct stream *stream = open_stream(filename, &mpctx->opts, &format);
if (!stream)
@@ -3767,7 +3696,7 @@ static void open_external_file(struct MPContext *mpctx, char *filename,
free_stream(stream);
goto err_out;
}
- int num_added = 0;
+ struct track *first = NULL;
for (int n = 0; n < demuxer->num_streams; n++) {
struct sh_stream *stream = demuxer->streams[n];
if (stream->type == filter) {
@@ -3775,19 +3704,22 @@ static void open_external_file(struct MPContext *mpctx, char *filename,
t->is_external = true;
t->title = talloc_strdup(t, filename);
t->external_filename = talloc_strdup(t, filename);
- num_added++;
+ first = t;
}
}
- if (num_added == 0) {
+ if (!first) {
+ free_demuxer(demuxer);
mp_msg(MSGT_CPLAYER, MSGL_WARN, "No streams added from file %s.\n",
filename);
+ goto err_out;
}
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, demuxer);
- return;
+ return first;
err_out:
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Can not open external file %s.\n",
filename);
+ return false;
}
static void open_audiofiles_from_options(struct MPContext *mpctx)
@@ -4048,7 +3980,6 @@ goto_enable_cache: ;
add_subtitle_fonts_from_sources(mpctx);
open_subtitles_from_options(mpctx);
- open_vobsubs_from_options(mpctx);
open_audiofiles_from_options(mpctx);
open_subfiles_from_options(mpctx);
diff --git a/core/mplayer.h b/core/mplayer.h
index 004c770901..0471a3137d 100644
--- a/core/mplayer.h
+++ b/core/mplayer.h
@@ -31,8 +31,6 @@ extern float audio_delay;
extern double force_fps;
-extern int vobsub_id;
-
struct MPContext;
struct MPOpts;
struct subtitle;
diff --git a/demux/demux.c b/demux/demux.c
index f765b2ae87..41b74b20c4 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -459,6 +459,16 @@ void free_demuxer(demuxer_t *demuxer)
void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
{
+ // demux API can't handle 0-sized packets, but at least some vobsubs
+ // generate them. Skipping them seems to work fine. Not skipping them will
+ // stop demuxing with external vobsubs. See FATE sub/vobsub.{idx,sub} at
+ // pts=185.91.
+ if (dp->len == 0 && ds->stream_type == STREAM_SUB) {
+ mp_dbg(MSGT_DEMUXER, MSGL_INFO, "Discarding empty subtitle packet.\n");
+ free_demux_packet(dp);
+ return;
+ }
+
// append packet to DS stream:
++ds->packs;
ds->bytes += dp->len;
diff --git a/sub/find_subfiles.c b/sub/find_subfiles.c
index 502fc911dc..95004b564f 100644
--- a/sub/find_subfiles.c
+++ b/sub/find_subfiles.c
@@ -87,7 +87,7 @@ static void append_dir_subtitles(struct MPOpts *opts,
struct bstr path, const char *fname,
int limit_fuzziness)
{
- char *sub_exts[] = {"utf", "utf8", "utf-8", "sub", "srt", "smi", "rt", "txt", "ssa", "aqt", "jss", "js", "ass", NULL};
+ char *sub_exts[] = {"utf", "utf8", "utf-8", "idx", "sub", "srt", "smi", "rt", "txt", "ssa", "aqt", "jss", "js", "ass", NULL};
void *tmpmem = talloc_new(NULL);
FILE *f;
assert(strlen(fname) < 1e6);
@@ -117,20 +117,6 @@ static void append_dir_subtitles(struct MPOpts *opts,
struct bstr tmp_fname_ext = get_ext(dename);
struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext);
- // If it's a .sub, check if there is a .idx with the same name. If
- // there is one, it's certainly a vobsub so we skip it.
- if (bstrcasecmp(tmp_fname_ext, bstr0("sub")) == 0) {
- char *idxname = talloc_asprintf(tmpmem2, "%.*s.idx",
- (int)tmp_fname_noext.len,
- de->d_name);
- char *idx = mp_path_join(tmpmem2, path, bstr0(idxname));
- f = fopen(idx, "rt");
- if (f) {
- fclose(f);
- goto next_sub;
- }
- }
-
// does it end with a subtitle extension?
#ifdef CONFIG_ICONV
#ifdef CONFIG_ENCA
@@ -183,7 +169,7 @@ static void append_dir_subtitles(struct MPOpts *opts,
if (prio) {
prio += prio;
#ifdef CONFIG_ICONV
- if (i < 3) // prefer UTF-8 coded
+ if (i < 4) // prefer UTF-8 coded, or idx over sub (vobsubs)
prio++;
#endif
char *subpath = mp_path_join(*slist, path, dename);
@@ -241,38 +227,3 @@ char **find_text_subtitles(struct MPOpts *opts, const char *fname)
talloc_free(slist);
return subnames;
}
-
-char **find_vob_subtitles(struct MPOpts *opts, const char *fname)
-{
- char **vobs = talloc_array_ptrtype(NULL, vobs, 1);
- int n = 0;
-
- // Potential vobsub in the media directory
- struct bstr bname = bstr0(mp_basename(fname));
- int pdot = bstrrchr(bname, '.');
- if (pdot >= 0)
- bname.len = pdot;
- vobs[n++] = mp_path_join(vobs, mp_dirname(fname), bname);
-
- // Potential vobsubs in directories specified by sub-paths option
- if (opts->sub_paths) {
- for (int i = 0; opts->sub_paths[i]; i++) {
- char *path = mp_path_join(NULL, mp_dirname(fname),
- bstr0(opts->sub_paths[i]));
- MP_GROW_ARRAY(vobs, n);
- vobs[n++] = mp_path_join(vobs, bstr0(path), bname);
- talloc_free(path);
- }
- }
-
- // Potential vobsub in ~/.mplayer/sub
- char *mp_subdir = get_path("sub/");
- if (mp_subdir) {
- MP_GROW_ARRAY(vobs, n);
- vobs[n++] = mp_path_join(vobs, bstr0(mp_subdir), bname);
- }
-
- free(mp_subdir);
- MP_RESIZE_ARRAY(NULL, vobs, n);
- return vobs;
-}
diff --git a/sub/find_subfiles.h b/sub/find_subfiles.h
index c93164c6f8..6d68d6140c 100644
--- a/sub/find_subfiles.h
+++ b/sub/find_subfiles.h
@@ -24,6 +24,5 @@
struct MPOpts;
char **find_text_subtitles(struct MPOpts *opts, const char *fname);
-char **find_vob_subtitles(struct MPOpts *opts, const char *fname);
#endif /* MPLAYER_FINDFILES_H */
diff --git a/sub/spudec.c b/sub/spudec.c
index 22f121e92c..59c3058251 100644
--- a/sub/spudec.c
+++ b/sub/spudec.c
@@ -43,7 +43,6 @@
#include "core/mp_msg.h"
#include "spudec.h"
-#include "vobsub.h"
#include "sub.h"
#include "core/mp_common.h"
#include "video/csputils.h"
@@ -659,6 +658,33 @@ void spudec_get_indexed(void *this, struct mp_osd_res *dim,
}
}
+static unsigned int vobsub_palette_to_yuv(unsigned int pal)
+{
+ int r, g, b, y, u, v;
+ // Palette in idx file is not rgb value, it was calculated by wrong formula.
+ // Here's reversed formula of the one used to generate palette in idx file.
+ r = pal >> 16 & 0xff;
+ g = pal >> 8 & 0xff;
+ b = pal & 0xff;
+ y = av_clip_uint8( 0.1494 * r + 0.6061 * g + 0.2445 * b);
+ u = av_clip_uint8( 0.6066 * r - 0.4322 * g - 0.1744 * b + 128);
+ v = av_clip_uint8(-0.08435 * r - 0.3422 * g + 0.4266 * b + 128);
+ y = y * 219 / 255 + 16;
+ return y << 16 | u << 8 | v;
+}
+
+static unsigned int vobsub_rgb_to_yuv(unsigned int rgb)
+{
+ int r, g, b, y, u, v;
+ r = rgb >> 16 & 0xff;
+ g = rgb >> 8 & 0xff;
+ b = rgb & 0xff;
+ y = ( 0.299 * r + 0.587 * g + 0.114 * b) * 219 / 255 + 16.5;
+ u = (-0.16874 * r - 0.33126 * g + 0.5 * b) * 224 / 255 + 128.5;
+ v = ( 0.5 * r - 0.41869 * g - 0.08131 * b) * 224 / 255 + 128.5;
+ return y << 16 | u << 8 | v;
+}
+
static void spudec_parse_extradata(spudec_handle_t *this,
uint8_t *extradata, int extradata_len)
{
diff --git a/sub/vobsub.c b/sub/vobsub.c
deleted file mode 100644
index 5ae7e6cf1a..0000000000
--- a/sub/vobsub.c
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Some code freely inspired from VobSub <URL:http://vobsub.edensrising.com>,
- * with kind permission from Gabest <gabest@freemail.hu>
- *
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "config.h"
-#include "core/mp_common.h"
-#include "vobsub.h"
-#include "spudec.h"
-#include "core/mp_msg.h"
-#include "core/path.h"
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-
-extern int vobsub_id;
-// Record the original -vobsubid set by commandline, since vobsub_id will be
-// overridden if slang match any of vobsub streams.
-static int vobsubid = -2;
-
-typedef FILE rar_stream_t;
-#define rar_open fopen
-#define rar_close fclose
-#define rar_eof feof
-#define rar_tell ftell
-#define rar_seek fseek
-#define rar_getc getc
-#define rar_read fread
-
-/**********************************************************************/
-
-static ssize_t vobsub_getline(char **lineptr, size_t *n, rar_stream_t *stream)
-{
- size_t res = 0;
- int c;
- if (*lineptr == NULL) {
- *lineptr = malloc(4096);
- if (*lineptr)
- *n = 4096;
- } else if (*n == 0) {
- char *tmp = realloc(*lineptr, 4096);
- if (tmp) {
- *lineptr = tmp;
- *n = 4096;
- }
- }
- if (*lineptr == NULL || *n == 0)
- return -1;
-
- for (c = rar_getc(stream); c != EOF; c = rar_getc(stream)) {
- if (res + 1 >= *n) {
- char *tmp = realloc(*lineptr, *n * 2);
- if (tmp == NULL)
- return -1;
- *lineptr = tmp;
- *n *= 2;
- }
- (*lineptr)[res++] = c;
- if (c == '\n') {
- (*lineptr)[res] = 0;
- return res;
- }
- }
- if (res == 0)
- return -1;
- (*lineptr)[res] = 0;
- return res;
-}
-
-/**********************************************************************
- * MPEG parsing
- **********************************************************************/
-
-typedef struct {
- rar_stream_t *stream;
- unsigned int pts;
- int aid;
- unsigned char *packet;
- unsigned int packet_reserve;
- unsigned int packet_size;
- int padding_was_here;
- int merge;
-} mpeg_t;
-
-static mpeg_t *mpeg_open(const char *filename)
-{
- mpeg_t *res = malloc(sizeof(mpeg_t));
- int err = res == NULL;
- if (!err) {
- res->pts = 0;
- res->aid = -1;
- res->packet = NULL;
- res->packet_size = 0;
- res->packet_reserve = 0;
- res->padding_was_here = 1;
- res->merge = 0;
- res->stream = rar_open(filename, "rb");
- err = res->stream == NULL;
- if (err)
- perror("fopen Vobsub file failed");
- if (err)
- free(res);
- }
- return err ? NULL : res;
-}
-
-static void mpeg_free(mpeg_t *mpeg)
-{
- free(mpeg->packet);
- if (mpeg->stream)
- rar_close(mpeg->stream);
- free(mpeg);
-}
-
-static int mpeg_eof(mpeg_t *mpeg)
-{
- return rar_eof(mpeg->stream);
-}
-
-static off_t mpeg_tell(mpeg_t *mpeg)
-{
- return rar_tell(mpeg->stream);
-}
-
-static int mpeg_run(mpeg_t *mpeg)
-{
- unsigned int len, idx, version;
- int c;
- /* Goto start of a packet, it starts with 0x000001?? */
- const unsigned char wanted[] = { 0, 0, 1 };
- unsigned char buf[5];
-
- mpeg->aid = -1;
- mpeg->packet_size = 0;
- if (rar_read(buf, 4, 1, mpeg->stream) != 1)
- return -1;
- while (memcmp(buf, wanted, sizeof(wanted)) != 0) {
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- memmove(buf, buf + 1, 3);
- buf[3] = c;
- }
- switch (buf[3]) {
- case 0xb9: /* System End Code */
- break;
- case 0xba: /* Packet start code */
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- if ((c & 0xc0) == 0x40)
- version = 4;
- else if ((c & 0xf0) == 0x20)
- version = 2;
- else {
- mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Unsupported MPEG version: 0x%02x\n", c);
- return -1;
- }
- if (version == 4) {
- if (rar_seek(mpeg->stream, 9, SEEK_CUR))
- return -1;
- } else if (version == 2) {
- if (rar_seek(mpeg->stream, 7, SEEK_CUR))
- return -1;
- } else
- abort();
- if (!mpeg->padding_was_here)
- mpeg->merge = 1;
- break;
- case 0xbd: /* packet */
- if (rar_read(buf, 2, 1, mpeg->stream) != 1)
- return -1;
- mpeg->padding_was_here = 0;
- len = buf[0] << 8 | buf[1];
- idx = mpeg_tell(mpeg);
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- if ((c & 0xC0) == 0x40) { /* skip STD scale & size */
- if (rar_getc(mpeg->stream) < 0)
- return -1;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- }
- if ((c & 0xf0) == 0x20) { /* System-1 stream timestamp */
- /* Do we need this? */
- abort();
- } else if ((c & 0xf0) == 0x30) {
- /* Do we need this? */
- abort();
- } else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */
- unsigned int pts_flags, hdrlen, dataidx;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- pts_flags = c;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- hdrlen = c;
- dataidx = mpeg_tell(mpeg) + hdrlen;
- if (dataidx > idx + len) {
- mp_msg(MSGT_VOBSUB, MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
- hdrlen, len, idx, dataidx);
- return -1;
- }
- if ((pts_flags & 0xc0) == 0x80) {
- if (rar_read(buf, 5, 1, mpeg->stream) != 1)
- return -1;
- if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) && (buf[4] & 1))) {
- mp_msg(MSGT_VOBSUB, MSGL_ERR, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
- buf[0], buf[1], buf[2], buf[3], buf[4]);
- mpeg->pts = 0;
- } else
- mpeg->pts = ((buf[0] & 0x0e) << 29 | buf[1] << 22 | (buf[2] & 0xfe) << 14
- | buf[3] << 7 | (buf[4] >> 1));
- } else /* if ((pts_flags & 0xc0) == 0xc0) */ {
- /* what's this? */
- /* abort(); */
- }
- rar_seek(mpeg->stream, dataidx, SEEK_SET);
- mpeg->aid = rar_getc(mpeg->stream);
- if (mpeg->aid < 0) {
- mp_msg(MSGT_VOBSUB, MSGL_ERR, "Bogus aid %d\n", mpeg->aid);
- return -1;
- }
- mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx);
- if (mpeg->packet_reserve < mpeg->packet_size) {
- free(mpeg->packet);
- mpeg->packet = malloc(mpeg->packet_size);
- if (mpeg->packet)
- mpeg->packet_reserve = mpeg->packet_size;
- }
- if (mpeg->packet == NULL) {
- mp_msg(MSGT_VOBSUB, MSGL_FATAL, "malloc failure");
- mpeg->packet_reserve = 0;
- mpeg->packet_size = 0;
-