summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-11 21:41:50 +0200
committerwm4 <wm4@nowhere>2013-06-23 22:33:59 +0200
commit64b1374a4456435cc4486a8153703fa89af58e31 (patch)
treede0a0d9a04431856544ef1dc47398ca75f0ad383
parenta70d575291d48289669ee8989e0597a94189dd8d (diff)
downloadmpv-64b1374a4456435cc4486a8153703fa89af58e31.tar.bz2
mpv-64b1374a4456435cc4486a8153703fa89af58e31.tar.xz
sub: do some timing postprocessing on preloaded subs
This fixes the -subfps option (which unfortunately is still useful), and fixes minor annoying timing errors (which unfortunately still happen). Note that none of these affect ASS or image subtitles. ASS is specially handled: libass loads subtitles as ASS_Track. There are no actual packets passed around, and sd_ass just uses the ASS_Track. Disable the --sub-no-text-pp option. It's misleading now and always was completely useless.
-rw-r--r--DOCS/man/en/options.rst15
-rw-r--r--core/options.c6
-rw-r--r--sub/dec_sub.c45
3 files changed, 53 insertions, 13 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index 304eeba464..b9068b1562 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -1447,11 +1447,6 @@
``show_progress`` command (by default mapped to ``P``), or in some
non-default cases when seeking. Expands properties. See property_expansion_.
---overlapsub
- Allows the next subtitle to be displayed while the current one is still
- visible (default is to enable the support only for specific formats). This
- only matters for subtitles loaded with ``-sub``.
-
--panscan=<0.0-1.0>
Enables pan-and-scan functionality (cropping the sides of e.g. a 16:9
movie to make it fit a 4:3 display without black bands). The range
@@ -1996,15 +1991,17 @@
Use/display these subtitle files. Only one file can be displayed at the
same time.
+--sub-fix-timing, --no-sub-fix-timing
+ By default, external text subtitles are preprocessed to remove minor gaps
+ or overlaps between subtitles (if the difference is smaller than 200 ms,
+ the gap or overlap is removed). This does not affect image subtitles,
+ subtitles muxed with audio/video, or subtitles in the ASS format.
+
--sub-demuxer=<[+]name>
Force subtitle demuxer type for ``--subfile``. Using a '+' before the name
will force it, this will skip some checks! Give the demuxer name as
printed by ``--sub-demuxer=help``.
---sub-no-text-pp
- Disables any kind of text post processing done after loading the
- subtitles. Used for debug purposes.
-
--sub-paths=<path1:path2:...>
Specify extra directories where to search for subtitles matching the
video. Multiple directories can be separated by ":" (";" on Windows).
diff --git a/core/options.c b/core/options.c
index f3e262fc17..2e0d32bb60 100644
--- a/core/options.c
+++ b/core/options.c
@@ -496,9 +496,7 @@ const m_option_t mp_opts[] = {
OPT_FLAG("autosub", sub_auto, 0),
OPT_FLAG("sub-visibility", sub_visibility, 0),
OPT_FLAG("sub-forced-only", forced_subs_only, 0),
- // enable Closed Captioning display
- OPT_FLAG_CONSTANTS("overlapsub", suboverlap_enabled, 0, 0, 2),
- OPT_FLAG_STORE("sub-no-text-pp", sub_no_text_pp, 0, 1),
+ OPT_FLAG_CONSTANTS("sub-fix-timing", suboverlap_enabled, 0, 1, 0),
OPT_CHOICE("autosub-match", sub_match_fuzziness, 0,
({"exact", 0}, {"fuzzy", 1}, {"all", 2})),
OPT_INTRANGE("sub-pos", sub_pos, 0, 0, 100),
@@ -804,7 +802,7 @@ const struct MPOpts mp_default_opts = {
.ass_vsfilter_aspect_compat = 1,
.ass_style_override = 1,
.use_embedded_fonts = 1,
- .suboverlap_enabled = 1,
+ .suboverlap_enabled = 0,
.hwdec_codecs = "all",
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 187ae5f22c..230dfa2f55 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -261,6 +261,43 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh)
sh->gsh->codec ? sh->gsh->codec : "<unknown>");
}
+static void multiply_timings(struct packet_list *subs, double factor)
+{
+ for (int n = 0; n < subs->num_packets; n++) {
+ struct demux_packet *pkt = subs->packets[n];
+ if (pkt->pts != MP_NOPTS_VALUE)
+ pkt->pts *= factor;
+ if (pkt->duration > 0)
+ pkt->duration *= factor;
+ }
+}
+
+// Remove overlaps and fill gaps between adjacent subtitle packets. This is done
+// by adjusting the duration of the earlier packet. If the gaps or overlap are
+// larger than the threshold, or if the durations are close to the threshold,
+// don't change the events.
+// The algorithm is maximally naive and doesn't work if there are multiple
+// overlapping lines. (It's not worth the trouble.)
+static void fix_overlaps_and_gaps(struct packet_list *subs)
+{
+ double threshold = 0.2; // up to 200 ms overlaps or gaps are removed
+ double keep = threshold * 2;// don't change timings if durations are smaller
+ for (int i = 0; i < subs->num_packets - 1; i++) {
+ struct demux_packet *cur = subs->packets[i];
+ struct demux_packet *next = subs->packets[i + 1];
+ if (cur->pts != MP_NOPTS_VALUE && cur->duration > 0 &&
+ next->pts != MP_NOPTS_VALUE && next->duration > 0)
+ {
+ double end = cur->pts + cur->duration;
+ if (fabs(next->pts - end) <= threshold && cur->duration >= keep &&
+ next->duration >= keep)
+ {
+ cur->duration = next->pts - cur->pts;
+ }
+ }
+ }
+}
+
static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
{
struct sd *sd = sub_get_last_sd(sub);
@@ -285,6 +322,8 @@ static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
// there are circumstances which makes this not possible.
bool sub_read_all_packets(struct dec_sub *sub, struct sh_sub *sh)
{
+ struct MPOpts *opts = sub->opts;
+
if (!sub_accept_packets_in_advance(sub) || sh->track)
return false;
@@ -301,6 +340,12 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_sub *sh)
MP_TARRAY_APPEND(tmp, subs.packets, subs.num_packets, pkt);
}
+ if (opts->sub_fps && sub->video_fps)
+ multiply_timings(&subs, opts->sub_fps / sub->video_fps);
+
+ if (!opts->suboverlap_enabled)
+ fix_overlaps_and_gaps(&subs);
+
add_sub_list(sub, &subs);
talloc_free(tmp);