summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-01 19:44:12 +0200
committerwm4 <wm4@nowhere>2013-06-01 19:44:16 +0200
commit02ce316ade9ba932ad405383278d6b01c54e5fc4 (patch)
tree4151e307fafc30a4079d4cd79c3d85d92df35105 /sub
parent27d383918a3d63559c85ca96b2162a13234f2abc (diff)
downloadmpv-02ce316ade9ba932ad405383278d6b01c54e5fc4.tar.bz2
mpv-02ce316ade9ba932ad405383278d6b01c54e5fc4.tar.xz
sub: refactor
Make the sub decoder stuff independent from sh_sub (except for initialization of course). Sub decoders now access a struct sd only, instead of getting access to sh_sub. The glue code in dec_sub.c is similarily independent from osd. Some simplifications are made. For example, the switch_id stuff is unneeded: the frontend code just has to make sure to call osd_changed() any time subtitles are switched. This is also preparation for introducing subtitle converters. It's much cleaner to completely separate demuxer header/renderer glue/decoders for this purpose, especially since sub converters might completely change how demuxer headers have to be interpreted. Also pass data as demux_packets. Currently, this doesn't help much, but libavcodec converters might need scary stuff like packet side data, so it's perhaps better to go with passing packets.
Diffstat (limited to 'sub')
-rw-r--r--sub/dec_sub.c163
-rw-r--r--sub/dec_sub.h36
-rw-r--r--sub/sd.h40
-rw-r--r--sub/sd_ass.c80
-rw-r--r--sub/sd_lavc.c37
-rw-r--r--sub/sd_spu.c36
-rw-r--r--sub/sub.c4
-rw-r--r--sub/sub.h9
8 files changed, 235 insertions, 170 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 2cc02efb79..67828921b4 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -40,95 +40,136 @@ static const struct sd_functions *sd_list[] = {
NULL
};
-void sub_init(struct sh_sub *sh, struct osd_state *osd)
+struct dec_sub {
+ struct MPOpts *opts;
+ struct sd init_sd;
+
+ struct sd *sd;
+};
+
+struct dec_sub *sub_create(struct MPOpts *opts)
+{
+ struct dec_sub *sub = talloc_zero(NULL, struct dec_sub);
+ sub->opts = opts;
+ return sub;
+}
+
+void sub_destroy(struct dec_sub *sub)
+{
+ if (!sub)
+ return;
+ if (sub->sd && sub->sd->driver->uninit)
+ sub->sd->driver->uninit(sub->sd);
+ talloc_free(sub->sd);
+ talloc_free(sub);
+}
+
+bool sub_is_initialized(struct dec_sub *sub)
+{
+ return !!sub->sd;
+}
+
+struct sd *sub_get_sd(struct dec_sub *sub)
+{
+ return sub->sd;
+}
+
+void sub_set_video_res(struct dec_sub *sub, int w, int h)
+{
+ sub->init_sd.sub_video_w = w;
+ sub->init_sd.sub_video_h = h;
+}
+
+void sub_set_extradata(struct dec_sub *sub, void *data, int data_len)
+{
+ sub->init_sd.extradata = data_len ? talloc_memdup(sub, data, data_len) : NULL;
+ sub->init_sd.extradata_len = data_len;
+}
+
+void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library,
+ struct ass_renderer *ass_renderer)
+{
+ sub->init_sd.ass_library = ass_library;
+ sub->init_sd.ass_renderer = ass_renderer;
+}
+
+static int sub_init_decoder(struct dec_sub *sub, struct sd *sd)
{
- sh->sd_driver = NULL;
+ sd->driver = NULL;
for (int n = 0; sd_list[n]; n++) {
- if (sd_list[n]->supports_format(sh->gsh->codec)) {
- sh->sd_driver = sd_list[n];
+ if (sd_list[n]->supports_format(sd->codec)) {
+ sd->driver = sd_list[n];
break;
}
}
- if (sh->sd_driver) {
- if (sh->sd_driver->init(sh, osd) < 0)
- return;
- osd->sh_sub = sh;
- osd->switch_sub_id++;
- sh->initialized = true;
- sh->active = true;
+ if (!sd->driver)
+ return -1;
+
+ if (sd->driver->init(sd) < 0)
+ return -1;
+
+ return 0;
+}
+
+void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh)
+{
+ assert(!sub->sd);
+ if (sh->extradata && !sub->init_sd.extradata)
+ sub_set_extradata(sub, sh->extradata, sh->extradata_len);
+ struct sd *sd = talloc(NULL, struct sd);
+ *sd = sub->init_sd;
+ sd->opts = sub->opts;
+ sd->codec = sh->gsh->codec;
+ sd->ass_track = sh->track;
+ if (sub_init_decoder(sub, sd) < 0) {
+ talloc_free(sd);
+ sd = NULL;
}
+ sub->sd = sd;
}
-bool sub_accept_packets_in_advance(struct sh_sub *sh)
+bool sub_accept_packets_in_advance(struct dec_sub *sub)
{
- return sh->active && sh->sd_driver->accept_packets_in_advance;
+ return sub->sd && sub->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)
+void sub_decode(struct dec_sub *sub, struct demux_packet *packet)
{
- if (sh->active && sh->sd_driver->decode)
- sh->sd_driver->decode(sh, osd, data, data_len, pts, duration);
+ if (sub->sd)
+ sub->sd->driver->decode(sub->sd, packet);
}
-void sub_get_bitmaps(struct osd_state *osd, struct mp_osd_res dim, double pts,
+void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts,
struct sub_bitmaps *res)
{
- struct MPOpts *opts = osd->opts;
+ struct MPOpts *opts = sub->opts;
*res = (struct sub_bitmaps) {0};
- if (!opts->sub_visibility || !osd->sh_sub || !osd->sh_sub->active) {
- /* Change ID in case we just switched from visible subtitles
- * to current state. Hopefully, unnecessarily claiming that
- * things may have changed is harmless for empty contents.
- * Increase osd-> values ahead so that _next_ returned id
- * is also guaranteed to differ from this one.
- */
- osd->switch_sub_id++;
- } else {
- if (osd->sh_sub->sd_driver->get_bitmaps)
- osd->sh_sub->sd_driver->get_bitmaps(osd->sh_sub, osd, dim, pts, res);
+ if (sub->sd && opts->sub_visibility) {
+ if (sub->sd->driver->get_bitmaps)
+ sub->sd->driver->get_bitmaps(sub->sd, dim, pts, res);
}
-
- res->bitmap_id += osd->switch_sub_id;
- res->bitmap_pos_id += osd->switch_sub_id;
- osd->switch_sub_id = 0;
}
-char *sub_get_text(struct osd_state *osd, double pts)
+bool sub_has_get_text(struct dec_sub *sub)
{
- 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;
+ return sub->sd && sub->sd->driver->get_text;
}
-void sub_reset(struct sh_sub *sh, struct osd_state *osd)
+char *sub_get_text(struct dec_sub *sub, double pts)
{
- if (sh->active && sh->sd_driver->reset)
- sh->sd_driver->reset(sh, osd);
-}
-
-void sub_switchoff(struct sh_sub *sh, struct osd_state *osd)
-{
- if (sh->active && sh->sd_driver->switch_off) {
- assert(osd->sh_sub == sh);
- sh->sd_driver->switch_off(sh, osd);
- osd->sh_sub = NULL;
+ struct MPOpts *opts = sub->opts;
+ char *text = NULL;
+ if (sub->sd && opts->sub_visibility) {
+ if (sub->sd->driver->get_text)
+ text = sub->sd->driver->get_text(sub->sd, pts);
}
- sh->active = false;
+ return text;
}
-void sub_uninit(struct sh_sub *sh)
+void sub_reset(struct dec_sub *sub)
{
- assert (!sh->active);
- if (sh->initialized && sh->sd_driver->uninit)
- sh->sd_driver->uninit(sh);
- sh->initialized = false;
+ if (sub->sd && sub->sd->driver->reset)
+ sub->sd->driver->reset(sub->sd);
}
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index 4eb833c52b..39632d21a9 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -9,20 +9,36 @@
struct sh_sub;
struct ass_track;
struct MPOpts;
+struct demux_packet;
+struct ass_library;
+struct ass_renderer;
-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 dec_sub;
+struct sd;
+
+struct dec_sub *sub_create(struct MPOpts *opts);
+void sub_destroy(struct dec_sub *sub);
+
+void sub_set_video_res(struct dec_sub *sub, int w, int h);
+void sub_set_extradata(struct dec_sub *sub, void *data, int data_len);
+void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library,
+ struct ass_renderer *ass_renderer);
+void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh);
+
+bool sub_is_initialized(struct dec_sub *sub);
+
+bool sub_accept_packets_in_advance(struct dec_sub *sub);
+void sub_decode(struct dec_sub *sub, struct demux_packet *packet);
+void sub_get_bitmaps(struct dec_sub *sub, 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);
+bool sub_has_get_text(struct dec_sub *sub);
+char *sub_get_text(struct dec_sub *sub, double pts);
+void sub_reset(struct dec_sub *sub);
+
+struct sd *sub_get_sd(struct dec_sub *sub);
#ifdef CONFIG_ASS
-struct ass_track *sub_get_ass_track(struct osd_state *osd);
+struct ass_track *sub_get_ass_track(struct dec_sub *sub);
#endif
#endif
diff --git a/sub/sd.h b/sub/sd.h
index 123a9bc45d..42f7b8a445 100644
--- a/sub/sd.h
+++ b/sub/sd.h
@@ -2,20 +2,42 @@
#define MPLAYER_SD_H
#include "dec_sub.h"
+#include "demux/demux_packet.h"
+
+struct sd {
+ struct MPOpts *opts;
+
+ const struct sd_functions *driver;
+ void *priv;
+
+ const char *codec;
+
+ // Extra header data passed from demuxer
+ char *extradata;
+ int extradata_len;
+
+ // Video resolution used for subtitle decoding. Doesn't necessarily match
+ // the resolution of the VO, nor does it have to be the OSD resolution.
+ int sub_video_w, sub_video_h;
+
+ // Make sd_ass use an existing track
+ struct ass_track *ass_track;
+
+ // Shared renderer for ASS - done to avoid reloading embedded fonts.
+ struct ass_library *ass_library;
+ struct ass_renderer *ass_renderer;
+};
struct sd_functions {
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,
+ int (*init)(struct sd *sd);
+ void (*decode)(struct sd *sd, struct demux_packet *packet);
+ void (*get_bitmaps)(struct sd *sd, 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);
+ char *(*get_text)(struct sd *sd, double pts);
+ void (*reset)(struct sd *sd);
+ void (*uninit)(struct sd *sd);
};
#endif
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index b107e0438f..2ebd2164be 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -69,39 +69,39 @@ static void free_last_event(ASS_Track *track)
track->n_events--;
}
-static int init(struct sh_sub *sh, struct osd_state *osd)
+static int init(struct sd *sd)
{
- struct sd_ass_priv *ctx;
- bool ass = is_ass_sub(sh->gsh->codec);
-
- if (sh->initialized) {
- ctx = sh->context;
- } else {
- ctx = talloc_zero(NULL, struct sd_ass_priv);
- sh->context = ctx;
- if (sh->track) {
- ctx->ass_track = sh->track;
- } else if (ass) {
- ctx->ass_track = ass_new_track(osd->ass_library);
- if (sh->extradata)
- ass_process_codec_private(ctx->ass_track, sh->extradata,
- sh->extradata_len);
- } else
- ctx->ass_track = mp_ass_default_track(osd->ass_library, sh->opts);
- }
+ if (!sd->ass_library || !sd->ass_renderer)
+ return -1;
+
+ bool ass = is_ass_sub(sd->codec);
+ struct sd_ass_priv *ctx = talloc_zero(NULL, struct sd_ass_priv);
+ sd->priv = ctx;
+ if (sd->ass_track) {
+ ctx->ass_track = sd->ass_track;
+ } else if (ass) {
+ ctx->ass_track = ass_new_track(sd->ass_library);
+ if (sd->extradata)
+ ass_process_codec_private(ctx->ass_track, sd->extradata,
+ sd->extradata_len);
+ } else
+ ctx->ass_track = mp_ass_default_track(sd->ass_library, sd->opts);
ctx->vsfilter_aspect = ass;
return 0;
}
-static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
- int data_len, double pts, double duration)
+static void decode(struct sd *sd, struct demux_packet *packet)
{
+ void *data = packet->buffer;
+ int data_len = packet->len;
+ double pts = packet->pts;
+ double duration = packet->duration;
unsigned char *text = data;
- struct sd_ass_priv *ctx = sh->context;
+ struct sd_ass_priv *ctx = sd->priv;
ASS_Track *track = ctx->ass_track;
- if (is_ass_sub(sh->gsh->codec)) {
+ if (is_ass_sub(sd->codec)) {
if (bstr_startswith0((bstr){data, data_len}, "Dialogue: ")) {
// broken ffmpeg ASS packet format
ctx->flush_on_seek = true;
@@ -158,14 +158,13 @@ static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
event->Text = strdup(buf);
}
-static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
- struct mp_osd_res dim, double pts,
+static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, double pts,
struct sub_bitmaps *res)
{
- struct sd_ass_priv *ctx = sh->context;
- struct MPOpts *opts = osd->opts;
+ struct sd_ass_priv *ctx = sd->priv;
+ struct MPOpts *opts = sd->opts;
- if (pts == MP_NOPTS_VALUE)
+ if (pts == MP_NOPTS_VALUE || !sd->ass_renderer)
return;
double scale = dim.display_par;
@@ -173,7 +172,7 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
? opts->ass_vsfilter_aspect_compat : 1;
if (ctx->vsfilter_aspect && use_vs_aspect)
scale = scale * dim.video_par;
- ASS_Renderer *renderer = osd->ass_renderer;
+ ASS_Renderer *renderer = sd->ass_renderer;
mp_ass_configure(renderer, opts, &dim);
ass_set_aspect_ratio(renderer, scale, 1);
mp_ass_render_frame(renderer, ctx->ass_track, pts * 1000 + .5,
@@ -234,9 +233,9 @@ static void ass_to_plaintext(struct buf *b, const char *in)
}
}
-static char *get_text(struct sh_sub *sh, struct osd_state *osd, double pts)
+static char *get_text(struct sd *sd, double pts)
{
- struct sd_ass_priv *ctx = sh->context;
+ struct sd_ass_priv *ctx = sd->priv;
ASS_Track *track = ctx->ass_track;
if (pts == MP_NOPTS_VALUE)
@@ -264,9 +263,9 @@ static char *get_text(struct sh_sub *sh, struct osd_state *osd, double pts)
return ctx->last_text;
}
-static void reset(struct sh_sub *sh, struct osd_state *osd)
+static void reset(struct sd *sd)
{
- struct sd_ass_priv *ctx = sh->context;
+ struct sd_ass_priv *ctx = sd->priv;
if (ctx->incomplete_event)
free_last_event(ctx->ass_track);
ctx->incomplete_event = false;
@@ -275,11 +274,11 @@ static void reset(struct sh_sub *sh, struct osd_state *osd)
ctx->flush_on_seek = false;
}
-static void uninit(struct sh_sub *sh)
+static void uninit(struct sd *sd)
{
- struct sd_ass_priv *ctx = sh->context;
+ struct sd_ass_priv *ctx = sd->priv;
- if (sh->track != ctx->ass_track)
+ if (sd->ass_track != ctx->ass_track)
ass_free_track(ctx->ass_track);
talloc_free(ctx);
}
@@ -292,15 +291,14 @@ const struct sd_functions sd_ass = {
.get_bitmaps = get_bitmaps,
.get_text = get_text,
.reset = reset,
- .switch_off = reset,
.uninit = uninit,
};
-struct ass_track *sub_get_ass_track(struct osd_state *osd)
+struct ass_track *sub_get_ass_track(struct dec_sub *sub)
{
- struct sh_sub *sh = osd ? osd->sh_sub : NULL;
- if (sh && sh->sd_driver == &sd_ass && sh->context) {
- struct sd_ass_priv *ctx = sh->context;
+ struct sd *sd = sub_get_sd(sub);
+ if (sd && sd->driver == &sd_ass && sd->priv) {
+ struct sd_ass_priv *ctx = sd->priv;
return ctx->ass_track;
}
return NULL;
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 4c7dfd12a5..9f8db2d877 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -81,12 +81,10 @@ static void guess_resolution(enum AVCodecID type, int *w, int *h)
}
}
-static int init(struct sh_sub *sh, struct osd_state *osd)
+static int init(struct sd *sd)
{
- if (sh->initialized)
- return 0;
struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
- enum AVCodecID cid = mp_codec_to_av_codec_id(sh->gsh->codec);
+ enum AVCodecID cid = mp_codec_to_av_codec_id(sd->codec);
AVCodecContext *ctx = NULL;
AVCodec *sub_codec = avcodec_find_decoder(cid);
if (!sub_codec)
@@ -94,12 +92,12 @@ static int init(struct sh_sub *sh, struct osd_state *osd)
ctx = avcodec_alloc_context3(sub_codec);
if (!ctx)
goto error;
- ctx->extradata_size = sh->extradata_len;
- ctx->extradata = sh->extradata;
+ ctx->extradata_size = sd->extradata_len;
+ ctx->extradata = sd->extradata;
if (avcodec_open2(ctx, sub_codec, NULL) < 0)
goto error;
priv->avctx = ctx;
- sh->context = priv;
+ sd->priv = priv;
return 0;
error:
@@ -126,18 +124,19 @@ static void clear(struct sd_lavc_priv *priv)
priv->have_sub = false;
}
-static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
- int data_len, double pts, double duration)
+static void decode(struct sd *sd, struct demux_packet *packet)
{
- struct sd_lavc_priv *priv = sh->context;
+ struct sd_lavc_priv *priv = sd->priv;
AVCodecContext *ctx = priv->avctx;
+ double pts = packet->pts;
+ double duration = packet->duration;
AVSubtitle sub;
AVPacket pkt;
clear(priv);
av_init_packet(&pkt);
- pkt.data = data;
- pkt.size = data_len;
+ pkt.data = packet->buffer;
+ pkt.size = packet->len;
pkt.pts = pts * 1000;
if (duration >= 0)
pkt.convergence_duration = duration * 1000;
@@ -189,11 +188,10 @@ static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
}
}
-static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
- struct mp_osd_res d, double pts,
+static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
struct sub_bitmaps *res)
{
- struct sd_lavc_priv *priv = sh->context;
+ struct sd_lavc_priv *priv = sd->priv;
if (priv->pts != MP_NOPTS_VALUE && pts < priv->pts)
return;
@@ -225,9 +223,9 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
res->scaled = xscale != 1 || yscale != 1;
}
-static void reset(struct sh_sub *sh, struct osd_state *osd)
+static void reset(struct sd *sd)
{
- struct sd_lavc_priv *priv = sh->context;
+ struct sd_lavc_priv *priv = sd->priv;
if (priv->pts == MP_NOPTS_VALUE)
clear(priv);
@@ -235,9 +233,9 @@ static void reset(struct sh_sub *sh, struct osd_state *osd)
avcodec_flush_buffers(priv->avctx);
}
-static void uninit(struct sh_sub *sh)
+static void uninit(struct sd *sd)
{
- struct sd_lavc_priv *priv = sh->context;
+ struct sd_lavc_priv *priv = sd->priv;
clear(priv);
avcodec_close(priv->avctx);
@@ -251,6 +249,5 @@ const struct sd_functions sd_lavc = {
.decode = decode,
.get_bitmaps = get_bitmaps,
.reset = reset,
- .switch_off = reset,
.uninit = uninit,
};
diff --git a/sub/sd_spu.c b/sub/sd_spu.c
index 8b87b7a0dc..d2dd5f56e0 100644
--- a/sub/sd_spu.c
+++ b/sub/sd_spu.c
@@ -40,37 +40,34 @@ static bool supports_format(const char *format)
return is_dvd_sub(format);
}
-static int init(struct sh_sub *sh, struct osd_state *osd)
+static int init(struct sd *sd)
{
- if (sh->initialized)
- return 0;
- void *spudec = spudec_new_scaled(osd->sub_video_w, osd->sub_video_h,
- sh->extradata, sh->extradata_len);
+ void *spudec = spudec_new_scaled(sd->sub_video_w, sd->sub_video_h,
+ sd->extradata, sd->extradata_len);
if (!spudec)
return -1;
struct sd_spu_priv *priv = talloc_zero(NULL, struct sd_spu_priv);
priv->spudec = spudec;
- sh->context = priv;
+ sd->priv = priv;
return 0;
}
-static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
- int data_len, double pts, double duration)
+static void decode(struct sd *sd, struct demux_packet *packet)
{
- struct sd_spu_priv *priv = sh->context;
+ struct sd_spu_priv *priv = sd->priv;
- if (pts < 0 || data_len == 0)
+ if (packet->pts < 0 || packet->len == 0)
return;
- spudec_assemble(priv->spudec, data, data_len, pts * 90000);
+ spudec_assemble(priv->spudec, packet->buffer, packet->len,
+ packet->pts * 90000);
}
-static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
- struct mp_osd_res d, double pts,
+static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
struct sub_bitmaps *res)
{
- struct MPOpts *opts = sh->opts;
- struct sd_spu_priv *priv = sh->context;
+ struct MPOpts *opts = sd->opts;
+ struct sd_spu_priv *priv = sd->priv;
spudec_set_forced_subs_only(priv->spudec, opts->forced_subs_only);
spudec_heartbeat(priv->spudec, pts * 90000);
@@ -79,16 +76,16 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
spudec_get_indexed(priv->spudec, &d, res);
}
-static void reset(struct sh_sub *sh, struct osd_state *osd)
+static void reset(struct sd *sd)
{
- struct sd_spu_priv *priv = sh->context;
+ struct sd_spu_priv *priv = sd->priv;
spudec_reset(priv->spudec);
}
-static void uninit(struct sh_sub *sh)
+static void uninit(struct sd *sd)
{
- struct sd_spu_priv *priv = sh->context;
+ struct sd_spu_priv *priv = sd->priv;
spudec_free(priv->spudec);
talloc_free(priv);
@@ -100,6 +97,5 @@ const struct sd_functions sd_spu = {
.decode = decode,
.get_bitmaps = get_bitmaps,
.reset = reset,
- .switch_off = reset,
.uninit = uninit,
};
diff --git a/sub/sub.c b/sub/sub.c
index 9dc5722469..a0965dc1ec 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -159,11 +159,11 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
obj->vo_res = res;
if (obj->type == OSDTYPE_SUB) {
- if (osd->render_bitmap_subs) {
+ if (osd->render_bitmap_subs && osd->dec_sub) {
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);
+ sub_get_bitmaps(osd->dec_sub, 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 fae7202ed5..a13d3ca6f8 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -120,7 +120,6 @@ struct osd_state {
struct ass_library *ass_library;
struct ass_renderer *ass_renderer;
- struct sh_sub *sh_sub;
double sub_offset;
double vo_pts;
@@ -138,15 +137,11 @@ struct osd_state {
float progbar_value; // range 0.0-1.0
float *progbar_stops; // used for chapter indicators (0.0-1.0 each)
int progbar_num_stops;
-
- int switch_sub_id;
+ // OSDTYPE_SUB
+ struct dec_sub *dec_sub;
struct MPOpts *opts;
- // Video resolution used for subtitle decoding. Doesn't necessarily match
- // the resolution of the VO, nor does it have to be the OSD resolution.
- int sub_video_w, sub_video_h;
-
// Internal to sub.c
struct mp_draw_sub_cache *draw_cache;