[MPlayer-dev-eng] [PATCH] sub: add -sub-extend-* options.

Nicolas George george at nsup.org
Sun Aug 9 11:42:18 CEST 2015


These options extend the duration of subtitles without
causing overlapping.
They can add a little comfort to people who are slow readers,
although the effect is limited in fast dialog scenes since
the room for extending is small.
---
 DOCS/man/en/mplayer.1 | 14 ++++++++++++++
 cfg-common.h          |  2 ++
 mencoder.c            |  2 ++
 mpcommon.h            |  2 ++
 mplayer.c             |  2 ++
 sub/ass_mp.c          | 26 ++++++++++++++++++++++++++
 sub/subreader.c       | 27 +++++++++++++++++++++++----
 7 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 2b90878..cfba9d1 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -2869,6 +2869,20 @@ Delays subtitles by <sec> seconds.
 Can be negative.
 .
 .TP
+.B \-sub\-extend\-after <sec>
+Extend subtitles by delaying their disappearance by at most <sec> seconds.
+It does not cause overlap if the next subtitle is less than <sec> away
+and does not apply to already overlapping subtitles.
+It does not work with subtitles embedded in the stream nor with bitmap
+subtitles.
+.
+.TP
+.B \-sub\-extend\-before <sec>
+Extend subtitles by making them appear by at most <sec> seconds early.
+See \-sub\-extend\-after for details.
+If both options are specified, \-sub\-extend\-after has precedence.
+.
+.TP
 .B \-subfile <filename> (BETA CODE)
 Currently useless.
 Same as \-audiofile, but for subtitle streams (OggDS?).
diff --git a/cfg-common.h b/cfg-common.h
index 58748ff..e498a95 100644
--- a/cfg-common.h
+++ b/cfg-common.h
@@ -572,6 +572,8 @@ const m_option_t common_opts[] = {
 #endif
     {"subdelay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
     {"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
+    {"sub-extend-after", &sub_extend_after, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
+    {"sub-extend-before", &sub_extend_before, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
     {"autosub", &sub_auto, CONF_TYPE_FLAG, 0, 0, 1, NULL},
     {"noautosub", &sub_auto, CONF_TYPE_FLAG, 0, 1, 0, NULL},
     {"unicode", &sub_unicode, CONF_TYPE_FLAG, 0, 0, 1, NULL},
diff --git a/mencoder.c b/mencoder.c
index 1c34457..2548028 100644
--- a/mencoder.c
+++ b/mencoder.c
@@ -180,6 +180,8 @@ char **sub_name=NULL;
 char **sub_paths = NULL;
 float sub_delay=0;
 float sub_fps=0;
+float sub_extend_after = 0;
+float sub_extend_before = 0;
 int   sub_auto = 0;
 char *vobsub_name = NULL;
 int   subcc_enabled=0;
diff --git a/mpcommon.h b/mpcommon.h
index 8a7a334..38ee871 100644
--- a/mpcommon.h
+++ b/mpcommon.h
@@ -41,6 +41,8 @@ extern int forced_subs_only;
 extern int sub_auto;
 extern float sub_delay;
 extern float sub_fps;
+extern float sub_extend_after;
+extern float sub_extend_before;
 extern char **sub_name;
 extern char **sub_paths;
 extern char  *font_name;
diff --git a/mplayer.c b/mplayer.c
index 527bc40..40d8bda 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -282,6 +282,8 @@ char **sub_name;
 char **sub_paths;
 float sub_delay;
 float sub_fps;
+float sub_extend_after = 0;
+float sub_extend_before = 0;
 int sub_auto = 1;
 char *vobsub_name;
 int subcc_enabled;
diff --git a/sub/ass_mp.c b/sub/ass_mp.c
index 60f464f..eed118b 100644
--- a/sub/ass_mp.c
+++ b/sub/ass_mp.c
@@ -212,6 +212,31 @@ ASS_Track* ass_read_subdata(ASS_Library* library, sub_data* subdata, double fps)
 	return track;
 }
 
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+static void ass_extend_subs_time(ASS_Track *track)
+{
+	ASS_Event *ev = track->events;
+	long long ext_after = sub_extend_after * 1000;
+	long long ext_before = sub_extend_before * 1000;
+	long long start, end, bound;
+	int i;
+
+	for (i = 0; i < track->n_events; i++) {
+		start = ev[i].Start;
+		end = start + ev[i].Duration;
+		bound = i < track->n_events + 1 ? ev[i + 1].Start : LLONG_MAX;
+		if (end < bound)
+			end = MIN(bound, end + ext_after);
+		bound = i > 0 ? ev[i - 1].Start + ev[i - 1].Duration : LLONG_MIN;
+		if (start > bound)
+			start = MAX(bound, start - ext_before);
+		ev[i].Start = start;
+		ev[i].Duration = end - start;
+	}
+}
+
 ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charset) {
 	char *buf = NULL;
 	ASS_Track *track;
@@ -254,6 +279,7 @@ ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charse
 		track->name = strdup(fname);
 	}
 	free(buf);
+	ass_extend_subs_time(track);
 	return track;
 }
 
diff --git a/sub/subreader.c b/sub/subreader.c
index ecc5ff5..15afa87 100644
--- a/sub/subreader.c
+++ b/sub/subreader.c
@@ -1352,13 +1352,31 @@ static int sub_fribidi (subtitle *sub, int av_unused sub_utf8, int av_unused fro
   return 1;
 }
 
-static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block,
+static void extend_subs_time(subtitle *sub, int nb_sub, double one_second)
+{
+    unsigned long ext_after = sub_extend_after * one_second;
+    unsigned long ext_before = sub_extend_before * one_second;
+    unsigned long bound;
+    int i;
+
+    for (i = 0; i < nb_sub; i++) {
+        bound = i < nb_sub + 1 ? sub[i + 1].start : ULONG_MAX;
+        if (sub[i].end < bound)
+            sub[i].end = FFMIN(bound, sub[i].end + ext_after);
+        bound = i > 0 ? sub[i - 1].end : 0;
+        if (sub[i].start > bound)
+            sub[i].start = FFMAX(bound, FFMAX(sub[i].start, ext_before) - ext_before);
+    }
+}
+
+static void adjust_subs_time(subtitle *firstsub, float subtime, float fps, int block,
                              int sub_num, int sub_uses_time) {
 	int n,m;
-	subtitle* nextsub;
+	subtitle *sub = firstsub, *nextsub;
 	int i = sub_num;
-	unsigned long subfms = (sub_uses_time ? 100 : fps) * subtime;
-	unsigned long overlap = (sub_uses_time ? 100 : fps) / 5; // 0.2s
+	double one_second = sub_uses_time ? 100 : fps;
+	unsigned long subfms = one_second * subtime;
+	unsigned long overlap = one_second / 5; // 0.2s
 
 	n=m=0;
 	if (i)	for (;;){
@@ -1409,6 +1427,7 @@ static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block,
 		m = 0;
 	}
 	if (n) mp_msg(MSGT_SUBREADER,MSGL_V,"SUB: Adjusted %d subtitle(s).\n", n);
+	extend_subs_time(firstsub, sub_num, one_second);
 }
 
 struct subreader {
-- 
2.5.0



More information about the MPlayer-dev-eng mailing list