summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-28 21:12:11 +0200
committerwm4 <wm4@nowhere>2013-05-30 22:20:02 +0200
commitb44202b69fc4a1dd1659f7940c5f8846d316e0ff (patch)
treecba363991fc52000ec3f02b9ade2d94e56af873e /sub
parentf7ad81c0f5905637c16480b2e44dd41f2839293a (diff)
downloadmpv-b44202b69fc4a1dd1659f7940c5f8846d316e0ff.tar.bz2
mpv-b44202b69fc4a1dd1659f7940c5f8846d316e0ff.tar.xz
sub: redo how -no-ass is handled
The -no-ass switch used to disable any use of libass for text subtitles. This is not really the case anymore, because libass is now always involved when rendering text. The only remaining use of -no-ass is disabling styling or showing subtitles on the terminal. On the other hand, the old subtitle rendering path is a big reason why the subtitle code is still a big mess with an awful number of obscure special cases. In order to simplify it, remove the old subtitle rendering code, and always go through sd_ass.c. Basically, we use ASS_Track as central data structure for storing text subtitles instead of struct sub_data. This also makes libass mandatory for all text subs, even if they are printed to the terminal in -no-video mode. (We could add something like sd_text to avoid this, but it's not worth the trouble.) struct sub_data and subreader.c are still around, even its ASS/SSA reader. But struct sub_data is freed right after converting it to ASS_Track. The internal ASS reader actually can handle some obscure cases libass can't, like files encoded in UTF-16.
Diffstat (limited to 'sub')
-rw-r--r--sub/dec_sub.c24
-rw-r--r--sub/dec_sub.h5
-rw-r--r--sub/find_sub.c174
-rw-r--r--sub/osd_libass.c12
-rw-r--r--sub/sd.h4
-rw-r--r--sub/sd_ass.c102
-rw-r--r--sub/sd_lavc.c6
-rw-r--r--sub/sub.c39
-rw-r--r--sub/sub.h8
-rw-r--r--sub/subreader.c102
-rw-r--r--sub/subreader.h6
11 files changed, 159 insertions, 323 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index d3cedea80d..3de7d1223d 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -51,13 +51,13 @@ bool is_dvd_sub(const char *t)
void sub_init(struct sh_sub *sh, struct osd_state *osd)
{
- struct MPOpts *opts = sh->opts;
+ const char *format = sh->gsh->codec;
assert(!osd->sh_sub);
- if (sd_lavc.probe(sh))
+ if (sd_lavc.supports_format(format))
sh->sd_driver = &sd_lavc;
#ifdef CONFIG_ASS
- if (opts->ass_enabled && sd_ass.probe(sh))
+ if (sd_ass.supports_format(format))
sh->sd_driver = &sd_ass;
#endif
if (sh->sd_driver) {
@@ -70,6 +70,11 @@ void sub_init(struct sh_sub *sh, struct osd_state *osd)
}
}
+bool sub_accept_packets_in_advance(struct sh_sub *sh)
+{
+ return sh->active && sh->sd_driver->accept_packets_in_advance;
+}
+
void sub_decode(struct sh_sub *sh, struct osd_state *osd, void *data,
int data_len, double pts, double duration)
{
@@ -101,6 +106,19 @@ void sub_get_bitmaps(struct osd_state *osd, struct mp_osd_res dim, double pts,
osd->switch_sub_id = 0;
}
+char *sub_get_text(struct osd_state *osd, double pts)
+{
+ struct MPOpts *opts = osd->opts;
+ char *text = NULL;
+ if (!opts->sub_visibility || !osd->sh_sub || !osd->sh_sub->active) {
+ // -
+ } else {
+ if (osd->sh_sub->sd_driver->get_text)
+ text = osd->sh_sub->sd_driver->get_text(osd->sh_sub, osd, pts);
+ }
+ return text;
+}
+
void sub_reset(struct sh_sub *sh, struct osd_state *osd)
{
if (sh->active && sh->sd_driver->reset)
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index 593eac1e03..52fa05eebc 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -14,18 +14,19 @@ bool is_text_sub(const char *t);
bool is_ass_sub(const char *t);
bool is_dvd_sub(const char *t);
+bool sub_accept_packets_in_advance(struct sh_sub *sh);
void sub_decode(struct sh_sub *sh, struct osd_state *osd, void *data,
int data_len, double pts, double duration);
void sub_get_bitmaps(struct osd_state *osd, struct mp_osd_res dim, double pts,
struct sub_bitmaps *res);
+char *sub_get_text(struct osd_state *osd, double pts);
void sub_init(struct sh_sub *sh, struct osd_state *osd);
void sub_reset(struct sh_sub *sh, struct osd_state *osd);
void sub_switchoff(struct sh_sub *sh, struct osd_state *osd);
void sub_uninit(struct sh_sub *sh);
struct sh_sub *sd_ass_create_from_track(struct ass_track *track,
- bool vsfilter_aspect,
- struct MPOpts *opts);
+ const char *codec, struct MPOpts *opts);
#ifdef CONFIG_ASS
struct ass_track *sub_get_ass_track(struct osd_state *osd);
diff --git a/sub/find_sub.c b/sub/find_sub.c
deleted file mode 100644
index 5feef2a3e9..0000000000
--- a/sub/find_sub.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * .SUB
- *
- * 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 "config.h"
-
-#include <stdio.h>
-
-#include "sub.h"
-#include "subreader.h"
-
-#include "core/mp_msg.h"
-#include "core/mp_common.h"
-#include "core/mplayer.h"
-
-static int current_sub=0;
-
-//static subtitle* subtitles=NULL;
-static int nosub_range_start=-1;
-static int nosub_range_end=-1;
-static const sub_data *last_sub_data = NULL;
-
-void step_sub(sub_data *subd, float pts, int movement) {
- subtitle *subs;
- int key;
-
- if (subd == NULL) return;
- subs = subd->subtitles;
- key = (pts+sub_delay) * (subd->sub_uses_time ? 100 : sub_fps);
-
- /* Tell the OSD subsystem that the OSD contents will change soon */
- vo_osd_changed(OSDTYPE_SUBTITLE);
-
- /* If we are moving forward, don't count the next (current) subtitle
- * if we haven't displayed it yet. Same when moving other direction.
- */
- if (movement > 0 && key < subs[current_sub].start)
- movement--;
- if (movement < 0 && key >= subs[current_sub].end)
- movement++;
-
- /* Never move beyond first or last subtitle. */
- if (current_sub+movement < 0)
- movement = 0-current_sub;
- if (current_sub+movement >= subd->sub_num)
- movement = subd->sub_num - current_sub - 1;
-
- current_sub += movement;
- sub_delay = subs[current_sub].start / (subd->sub_uses_time ? 100 : sub_fps) - pts;
-}
-
-void find_sub(struct MPContext *mpctx, sub_data* subd,int key){
- subtitle *subs;
- subtitle *new_sub = NULL;
- int i,j;
-
- if ( !subd || subd->sub_num == 0) return;
- subs = subd->subtitles;
-
- if (last_sub_data != subd) {
- // Sub data changed, reset nosub range.
- last_sub_data = subd;
- nosub_range_start = -1;
- nosub_range_end = -1;
- }
-
- if(vo_sub){
- if(key>=vo_sub->start && key<=vo_sub->end) return; // OK!
- } else {
- if(key>nosub_range_start && key<nosub_range_end) return; // OK!
- }
- // sub changed!
-
- /* Tell the OSD subsystem that the OSD contents will change soon */
- vo_osd_changed(OSDTYPE_SUBTITLE);
-
- if(key<=0){
- // no sub here
- goto update;
- }
-
-// printf("\r---- sub changed ----\n");
-
- // check next sub.
- if(current_sub>=0 && current_sub+1 < subd->sub_num){
- if(key>subs[current_sub].end && key<subs[current_sub+1].start){
- // no sub
- nosub_range_start=subs[current_sub].end;
- nosub_range_end=subs[current_sub+1].start;
- goto update;
- }
- // next sub?
- ++current_sub;
- new_sub=&subs[current_sub];
- if(key>=new_sub->start && key<=new_sub->end) goto update; // OK!
- }
-
-// printf("\r---- sub log search... ----\n");
-
- // use logarithmic search:
- i=0;
- j = subd->sub_num - 1;
-// printf("Searching %d in %d..%d\n",key,subs[i].start,subs[j].end);
- while(j>=i){
- current_sub=(i+j+1)/2;
- new_sub=&subs[current_sub];
- if(key<new_sub->start) j=current_sub-1;
- else if(key>new_sub->end) i=current_sub+1;
- else goto update; // found!
- }
-// if(key>=new_sub->start && key<=new_sub->end) return; // OK!
-
- // check where are we...
- if(key<new_sub->start){
- if(current_sub<=0){
- // before the first sub
- nosub_range_start=key-1; // tricky
- nosub_range_end=new_sub->start;
-// printf("FIRST... key=%d end=%d \n",key,new_sub->start);
- new_sub=NULL;
- goto update;
- }
- --current_sub;
- if(key>subs[current_sub].end && key<subs[current_sub+1].start){
- // no sub
- nosub_range_start=subs[current_sub].end;
- nosub_range_end=subs[current_sub+1].start;
-// printf("No sub... 1 \n");
- new_sub=NULL;
- goto update;
- }
- printf("HEH???? ");
- } else {
- if(key<=new_sub->end) printf("JAJJ! "); else
- if(current_sub+1 >= subd->sub_num){
- // at the end?
- nosub_range_start=new_sub->end;
- nosub_range_end=0x7FFFFFFF; // MAXINT
-// printf("END!?\n");
- new_sub=NULL;
- goto update;
- } else
- if(key>subs[current_sub].end && key<subs[current_sub+1].start){
- // no sub
- nosub_range_start=subs[current_sub].end;
- nosub_range_end=subs[current_sub+1].start;
-// printf("No sub... 2 \n");
- new_sub=NULL;
- goto update;
- }
- }
-
- mp_msg(MSGT_FIXME,MSGL_FIXME,"SUB ERROR: %d ? %d --- %d [%d] \n",key,(int)new_sub->start,(int)new_sub->end,current_sub);
-
- new_sub=NULL; // no sub here
-update:
- set_osd_subtitle(mpctx, new_sub);
-}
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index d157f7925c..d8496c2f3b 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -354,7 +354,7 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj)
clear_obj(obj);
- if (!(vo_sub && opts->sub_visibility))
+ if (!osd->sub_text || !osd->sub_text[0])
return;
if (!obj->osd_track)
@@ -370,15 +370,9 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj)
ass_set_line_position(osd->osd_render, 100 - sub_pos);
#endif
- char *text = talloc_strdup(NULL, "");
-
- for (int n = 0; n < vo_sub->lines; n++)
- text = talloc_asprintf_append_buffer(text, "%s\n", vo_sub->text[n]);
-
- char *escaped_text = mangle_ass(text);
+ char *escaped_text = mangle_ass(osd->sub_text);
add_osd_ass_event(obj->osd_track, escaped_text);
talloc_free(escaped_text);
- talloc_free(text);
}
static void update_object(struct osd_state *osd, struct osd_object *obj)
@@ -387,7 +381,7 @@ static void update_object(struct osd_state *osd, struct osd_object *obj)
case OSDTYPE_OSD:
update_osd(osd, obj);
break;
- case OSDTYPE_SUBTITLE:
+ case OSDTYPE_SUBTEXT:
update_sub(osd, obj);
break;
case OSDTYPE_PROGBAR:
diff --git a/sub/sd.h b/sub/sd.h
index 881c429689..123a9bc45d 100644
--- a/sub/sd.h
+++ b/sub/sd.h
@@ -4,13 +4,15 @@
#include "dec_sub.h"
struct sd_functions {
- bool (*probe)(struct sh_sub *sh);
+ bool accept_packets_in_advance;
+ bool (*supports_format)(const char *format);
int (*init)(struct sh_sub *sh, struct osd_state *osd);
void (*decode)(struct sh_sub *sh, struct osd_state *osd,
void *data, int data_len, double pts, double duration);
void (*get_bitmaps)(struct sh_sub *sh, struct osd_state *osd,
struct mp_osd_res dim, double pts,
struct sub_bitmaps *res);
+ char *(*get_text)(struct sh_sub *sh, struct osd_state *osd, double pts);
void (*reset)(struct sh_sub *sh, struct osd_state *osd);
void (*switch_off)(struct sh_sub *sh, struct osd_state *osd);
void (*uninit)(struct sh_sub *sh);
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 8d17835809..1501f5da54 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -17,10 +17,11 @@
*/
#include <stdlib.h>
-#include <ass/ass.h>
#include <assert.h>
#include <string.h>
+#include <ass/ass.h>
+
#include "talloc.h"
#include "core/options.h"
@@ -39,11 +40,12 @@ struct sd_ass_priv {
bool incomplete_event;
struct sub_bitmap *parts;
bool flush_on_seek;
+ char last_text[500];
};
-static bool probe(struct sh_sub *sh)
+static bool supports_format(const char *format)
{
- return is_text_sub(sh->gsh->codec);
+ return is_text_sub(format);
}
static void free_last_event(ASS_Track *track)
@@ -163,6 +165,89 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
talloc_steal(ctx, ctx->parts);
}
+struct buf {
+ char *start;
+ int size;
+ int len;
+};
+
+static void append(struct buf *b, char c)
+{
+ if (b->len < b->size) {
+ b->start[b->len] = c;
+ b->len++;
+ }
+}
+
+static void ass_to_plaintext(struct buf *b, const char *in)
+{
+ bool in_tag = false;
+ bool in_drawing = false;
+ while (*in) {
+ if (in_tag) {
+ if (in[0] == '}') {
+ in += 1;
+ in_tag = false;
+ } else if (in[0] == '\\' && in[1] == 'p') {
+ in += 2;
+ // skip text between \pN and \p0 tags
+ if (in[0] == '0') {
+ in_drawing = false;
+ } else if (in[0] >= '1' && in[0] <= '9') {
+ in_drawing = true;
+ }
+ } else {
+ in += 1;
+ }
+ } else {
+ if (in[0] == '\\' && (in[1] == 'N' || in[1] == 'n')) {
+ in += 2;
+ append(b, '\n');
+ } else if (in[0] == '\\' && in[1] == 'h') {
+ in += 2;
+ append(b, ' ');
+ } else if (in[0] == '{') {
+ in += 1;
+ in_tag = true;
+ } else {
+ if (!in_drawing)
+ append(b, in[0]);
+ in += 1;
+ }
+ }
+ }
+}
+
+static char *get_text(struct sh_sub *sh, struct osd_state *osd, double pts)
+{
+ struct sd_ass_priv *ctx = sh->context;
+ ASS_Track *track = ctx->ass_track;
+
+ if (pts == MP_NOPTS_VALUE)
+ return NULL;
+
+ struct buf b = {ctx->last_text, sizeof(ctx->last_text) - 1};
+
+ for (int i = 0; i < track->n_events; ++i) {
+ ASS_Event *event = track->events + i;
+ double start = event->Start / 1000.0;
+ double end = (event->Start + event->Duration) / 1000.0;
+ if (pts >= start && pts < end) {
+ if (event->Text) {
+ ass_to_plaintext(&b, event->Text);
+ append(&b, '\n');
+ }
+ }
+ }
+
+ b.start[b.len] = '\0';
+
+ if (b.len > 0 && b.start[b.len - 1] == '\n')
+ b.start[b.len - 1] = '\0';
+
+ return ctx->last_text;
+}
+
static void reset(struct sh_sub *sh, struct osd_state *osd)
{
struct sd_ass_priv *ctx = sh->context;
@@ -183,10 +268,12 @@ static void uninit(struct sh_sub *sh)
}
const struct sd_functions sd_ass = {
- .probe = probe,
+ .accept_packets_in_advance = true,
+ .supports_format = supports_format,
.init = init,
.decode = decode,
.get_bitmaps = get_bitmaps,
+ .get_text = get_text,
.reset = reset,
.switch_off = reset,
.uninit = uninit,
@@ -199,20 +286,19 @@ static int sd_ass_track_destructor(void *ptr)
}
struct sh_sub *sd_ass_create_from_track(struct ass_track *track,
- bool vsfilter_aspect,
- struct MPOpts *opts)
+ const char *codec, struct MPOpts *opts)
{
struct sh_sub *sh = talloc(NULL, struct sh_sub);
talloc_set_destructor(sh, sd_ass_track_destructor);
*sh = (struct sh_sub) {
.opts = opts,
.gsh = talloc_struct(sh, struct sh_stream, {
- .codec = "ass",
+ .codec = codec,
}),
.sd_driver = &sd_ass,
.context = talloc_struct(sh, struct sd_ass_priv, {
.ass_track = track,
- .vsfilter_aspect = vsfilter_aspect,
+ .vsfilter_aspect = is_ass_sub(codec),
}),
.initialized = true,
};
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 1665e36749..e067da6a43 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -41,9 +41,9 @@ struct sd_lavc_priv {
double endpts;
};
-static bool probe(struct sh_sub *sh)
+static bool supports_format(const char *format)
{
- enum AVCodecID cid = mp_codec_to_av_codec_id(sh->gsh->codec);
+ enum AVCodecID cid = mp_codec_to_av_codec_id(format);
// Supported codecs must be known to decode to paletted bitmaps
switch (cid) {
case AV_CODEC_ID_DVB_SUBTITLE:
@@ -241,7 +241,7 @@ static void uninit(struct sh_sub *sh)
}
const struct sd_functions sd_lavc = {
- .probe = probe,
+ .supports_format = supports_format,
.init = init,
.decode = decode,
.get_bitmaps = get_bitmaps,
diff --git a/sub/sub.c b/sub/sub.c
index 7111f39434..4e5420627c 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -45,8 +45,6 @@
int sub_pos=100;
int sub_visibility=1;
-subtitle* vo_sub=NULL;
-
float sub_delay = 0;
float sub_fps = 0;
@@ -103,6 +101,7 @@ struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib)
.opts = opts,
.ass_library = asslib,
.osd_text = talloc_strdup(osd, ""),
+ .sub_text = talloc_strdup(osd, ""),
.progbar_type = -1,
};
@@ -117,7 +116,7 @@ struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib)
osd->objs[OSDTYPE_SPU]->is_sub = true; // spudec.c
osd->objs[OSDTYPE_SUB]->is_sub = true; // dec_sub.c
- osd->objs[OSDTYPE_SUBTITLE]->is_sub = true; // osd_libass.c
+ osd->objs[OSDTYPE_SUBTEXT]->is_sub = true; // osd_libass.c
osd_init_backend(osd);
global_osd = osd;
@@ -133,15 +132,27 @@ void osd_free(struct osd_state *osd)
global_osd = NULL;
}
-void osd_set_text(struct osd_state *osd, const char *text)
+static bool set_text(void *talloc_ctx, char **var, const char *text)
{
if (!text)
text = "";
- if (strcmp(osd->osd_text, text) == 0)
- return;
- talloc_free(osd->osd_text);
- osd->osd_text = talloc_strdup(osd, text);
- vo_osd_changed(OSDTYPE_OSD);
+ if (strcmp(*var, text) == 0)
+ return true;
+ talloc_free(*var);
+ *var = talloc_strdup(talloc_ctx, text);
+ return false;
+}
+
+void osd_set_text(struct osd_state *osd, const char *text)
+{
+ if (!set_text(osd, &osd->osd_text, text))
+ vo_osd_changed(OSDTYPE_OSD);
+}
+
+void osd_set_sub(struct osd_state *osd, const char *text)
+{
+ if (!set_text(osd, &osd->sub_text, text))
+ vo_osd_changed(OSDTYPE_SUBTEXT);
}
static bool spu_visible(struct osd_state *osd, struct osd_object *obj)
@@ -172,10 +183,12 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
if (spu_visible(osd, obj))
spudec_get_indexed(vo_spudec, &obj->vo_res, out_imgs);
} else if (obj->type == OSDTYPE_SUB) {
- double sub_pts = video_pts;
- if (sub_pts != MP_NOPTS_VALUE)
- sub_pts += sub_delay - osd->sub_offset;
- sub_get_bitmaps(osd, obj->vo_res, sub_pts, out_imgs);
+ if (osd->render_bitmap_subs) {
+ double sub_pts = video_pts;
+ if (sub_pts != MP_NOPTS_VALUE)
+ sub_pts -= osd->sub_offset;
+ sub_get_bitmaps(osd, obj->vo_res, sub_pts, out_imgs);
+ }
} else {
osd_object_get_bitmaps(osd, obj, out_imgs);
}
diff --git a/sub/sub.h b/sub/sub.h
index 779d46c869..a922d2b162 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -85,7 +85,7 @@ struct mp_osd_res {
enum mp_osdtype {
OSDTYPE_SUB,
- OSDTYPE_SUBTITLE,
+ OSDTYPE_SUBTEXT,
OSDTYPE_SPU,
OSDTYPE_PROGBAR,
@@ -126,11 +126,14 @@ struct osd_state {
double vo_pts;
bool render_subs_in_filter;
+ bool render_bitmap_subs;
bool want_redraw;
// OSDTYPE_OSD
char *osd_text;
+ // OSDTYPE_SUBTEXT
+ char *sub_text;
// OSDTYPE_PROGBAR
int progbar_type; // <0: disabled, 1-255: symbol, else: no symbol
float progbar_value; // range 0.0-1.0
@@ -149,8 +152,6 @@ struct osd_state {
struct ass_library *osd_ass_library;
};
-extern struct subtitle* vo_sub;
-
extern void* vo_spudec;
extern void* vo_vobsub;
@@ -206,6 +207,7 @@ extern float sub_fps;
struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib);
void osd_set_text(struct osd_state *osd, const char *text);
+void osd_set_sub(struct osd_state *osd, const char *text);
void vo_osd_changed(int new_value);
void osd_changed_all(struct osd_state *osd);
void osd_free(struct osd_state *osd);
diff --git a/sub/subreader.c b/sub/subreader.c
index 090cd0a8b4..365f8aa532 100644
--- a/sub/subreader.c
+++ b/sub/subreader.c
@@ -1684,7 +1684,7 @@ if ((suboverlap_enabled == 2) ||
if (return_sub == NULL) return NULL;
subt_data = talloc_zero(NULL, sub_data);
talloc_set_destructor(subt_data, sub_destroy);
- subt_data->codec = srp->name;
+ subt_data->codec = "text"; //srp->name;
subt_data->filename = strdup(filename);
subt_data->sub_uses_time = uses_time;
subt_data->sub_num = sub_num;
@@ -1704,103 +1704,3 @@ static int sub_destroy(void *ptr)
free( subd->filename );
return 0;
}
-
-#define MAX_SUBLINE 512
-/**
- * \brief parse text and append it to subtitle in sub
- * \param sub subtitle struct to add text to
- * \param txt text to parse
- * \param len length of text in txt
- * \param endpts pts at which this subtitle text should be removed again
- *
- * <> and {} are interpreted as comment delimiters, "\n", "\N", '\n', '\r'
- * and '\0' are interpreted as newlines, duplicate, leading and trailing
- * newlines are ignored.
- */
-void sub_add_text(subtitle *sub, const char *txt, int len, double endpts) {
- int comment = 0;
- int double_newline = 1; // ignore newlines at the beginning
- int i, pos;
- char *buf;
- if (sub->lines >= SUB_MAX_TEXT) return;
- pos = 0;
- buf = malloc(MAX_SUBLINE + 1);
- sub->text[sub->lines] = buf;
- sub->endpts[sub->lines] = endpts;
- for (i = 0; i < len && pos < MAX_SUBLINE; i++) {
- char c = txt[i];
- if (c == '<') comment |= 1;
- if (c == '{') comment |= 2;
- if (comment) {
- if (c == '}') comment &= ~2;
- if (c == '>') comment &= ~1;
- continue;
- }
- if (pos == MAX_SUBLINE - 1) {
- i--;
- c = 0;
- }
- if (c == '\\' && i + 1 < len) {
- c = txt[++i];
- if (c == 'n' || c == 'N') c = 0;
- }
- if (c == '\n' || c == '\r') c = 0;
- if (c) {
- double_newline = 0;
- buf[pos++] = c;
- } else if (!double_newline) {
- if (sub->lines >= SUB_MAX_TEXT - 1) {
- mp_msg(MSGT_VO, MSGL_WARN, "Too many subtitle lines\n");
- break;
- }
- double_newline = 1;
- buf[pos] = 0;
- sub->lines++;
- pos = 0;
- buf = malloc(MAX_SUBLINE + 1);
- sub->text[sub->lines] = buf;
- sub->endpts[sub->lines] = endpts;
- }
- }
- buf[pos] = 0;
- if (sub->lines < SUB_MAX_TEXT &&
- strlen(sub->text[sub->lines]))
- sub->lines++;
- if (sub->lines > 1 &&
- strcmp(sub->text[sub->lines-1], sub->text[sub->lines-2]) == 0) {
- // remove duplicate lines. These can happen with some
- // "clever" ASS effects.
- sub->lines--;
- sub->endpts[sub->lines-1] =
- FFMAX(sub->endpts[sub->lines-1],
- sub->endpts[sub->lines]);
- free(sub->text[sub->lines]);
- }
-}
-
-/**
- * \brief remove outdated subtitle lines.
- * \param sub subtitle struct to modify
- * \param pts current pts. All lines with endpts <= this will be removed.
- * Use MP_NOPTS_VALUE to remove all lines
- * \return 1 if sub was modified, 0 otherwise.
- */
-int sub_clear_text(subtitle *sub, double pts) {
- int i = 0;
- int changed = 0;
- while (i < sub->lines) {
- double endpts = sub->endpts[i];
- if (pts == MP_NOPTS_VALUE || (endpts != MP_NOPTS_VALUE && pts >= endpts)) {
- int j;
- free(sub->text[i]);
- for (j = i + 1; j < sub->lines; j++) {
- sub->text[j - 1] = sub->text[j];
- sub->endpts[j - 1] = sub->endpts[j];
- }
- sub->lines--;
- changed = 1;
- } else
- i++;
- }
- return changed;
-}
diff --git a/sub/subreader.h b/sub/subreader.h
index 7a2316bdf1..ab4763cefe 100644
--- a/sub/subreader.h
+++ b/sub/subreader.h
@@ -67,7 +67,6 @@ typedef struct subtitle {
unsigned long end;
char *text[SUB_MAX_TEXT];
- double endpts[SUB_MAX_TEXT];
unsigned char alignment;
} subtitle;
@@ -92,10 +91,5 @@ void subcp_close (void); /* for demux_ogg.c */
const char* guess_buffer_cp(unsigned char* buffer, int buflen, const char *preferred_language, const char *fallback);
const char* guess_cp(struct stream *st, const char *preferred_language, const char *fallback);
#endif
-struct MPContext;
-void find_sub(struct MPContext *mpctx, sub_data* subd,int key);
-void step_sub(sub_data *subd, float pts, int movement);
-void sub_add_text(subtitle *sub, const char *txt, int len, double endpts);
-int sub_clear_text(subtitle *sub, double pts);
#endif /* MPLAYER_SUBREADER_H */