summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-08-25 21:22:39 +0300
committerwm4 <wm4@nowhere>2012-09-18 21:04:46 +0200
commit89a57148934ec7f150a6170ac1313f6f5c636596 (patch)
treeacff6dbda4ea8623ea4ce4d86834fe74f015653e
parent9bb03b7db40408b9dc4a0e1405a5bac754893e2b (diff)
downloadmpv-89a57148934ec7f150a6170ac1313f6f5c636596.tar.bz2
mpv-89a57148934ec7f150a6170ac1313f6f5c636596.tar.xz
subs: always use sub decoder framework for libass rendering
Remove subtitle selection code setting osd->ass_track directly and vf_ass/vf_vo code rendering the track directly with libass. Instead, do track selection and rendering with dec_sub.c functions. Before, mpctx->set_of_ass_tracks[] contained bare libass tracks generated from external subtitle files. For use with dec_sub.c, it now contains struct sh_sub instances with decoder already initialized. This commit breaks the sub_step command ('g' and 'y' keys) for libass-rendered subtitles. It could be fixed, but it's so useless - especially as with the existing implementation there's no practical way to get subtitle delay back to normal after using it - that I didn't bother. Conflicts: command.c mp_core.h mplayer.c
-rw-r--r--command.c17
-rw-r--r--defaultopts.c1
-rw-r--r--libmpcodecs/vf_ass.c26
-rw-r--r--libmpcodecs/vf_vo.c34
-rw-r--r--libvo/eosd_packer.h1
-rw-r--r--mp_core.h4
-rw-r--r--mplayer.c60
-rw-r--r--options.h1
-rw-r--r--sub/ass_mp.h6
-rw-r--r--sub/dec_sub.c29
-rw-r--r--sub/dec_sub.h11
-rw-r--r--sub/osd_libass.c4
-rw-r--r--sub/sd.h3
-rw-r--r--sub/sd_ass.c53
-rw-r--r--sub/sub.c4
-rw-r--r--sub/sub.h15
16 files changed, 164 insertions, 105 deletions
diff --git a/command.c b/command.c
index f733bbc0f0..cbac7ebb1a 100644
--- a/command.c
+++ b/command.c
@@ -1487,6 +1487,8 @@ static int mp_property_sub_alignment(m_option_t *prop, int action,
static int mp_property_sub_visibility(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
+ struct MPOpts *opts = &mpctx->opts;
+
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
@@ -1500,7 +1502,7 @@ static int mp_property_sub_visibility(m_option_t *prop, int action,
if (vo_spudec)
vo_osd_changed(OSDTYPE_SPU);
default:
- return m_property_flag(prop, action, arg, &sub_visibility);
+ return m_property_flag(prop, action, arg, &opts->sub_visibility);
}
}
@@ -1579,34 +1581,28 @@ static int mp_property_sub_scale(m_option_t *prop, int action, void *arg,
if (!arg)
return M_PROPERTY_ERROR;
M_PROPERTY_CLAMP(prop, *(float *) arg);
-#ifdef CONFIG_ASS
if (opts->ass_enabled)
opts->ass_font_scale = *(float *) arg;
-#endif
text_font_scale_factor = *(float *) arg;
vo_osd_resized();
return M_PROPERTY_OK;
case M_PROPERTY_STEP_UP:
case M_PROPERTY_STEP_DOWN:
-#ifdef CONFIG_ASS
if (opts->ass_enabled) {
opts->ass_font_scale += (arg ? *(float *) arg : 0.1) *
(action == M_PROPERTY_STEP_UP ? 1.0 : -1.0);
M_PROPERTY_CLAMP(prop, opts->ass_font_scale);
}
-#endif
text_font_scale_factor += (arg ? *(float *) arg : 0.1) *
(action == M_PROPERTY_STEP_UP ? 1.0 : -1.0);
M_PROPERTY_CLAMP(prop, text_font_scale_factor);
vo_osd_resized();
return M_PROPERTY_OK;
default:
-#ifdef CONFIG_ASS
if (opts->ass_enabled)
return m_property_float_ro(prop, action, arg, opts->ass_font_scale);
else
-#endif
- return m_property_float_ro(prop, action, arg, text_font_scale_factor);
+ return m_property_float_ro(prop, action, arg, text_font_scale_factor);
}
}
@@ -2371,7 +2367,8 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
struct track *track = mpctx->current_track[STREAM_SUB];
if (track && track->subdata)
step_sub(track->subdata, mpctx->video_pts, movement);
-#ifdef CONFIG_ASS
+#if 0
+ // currently not implemented with libass
if (mpctx->osd->ass_track)
sub_delay +=
ass_step_sub(mpctx->osd->ass_track,
@@ -2677,7 +2674,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
case MP_CMD_GET_SUB_VISIBILITY:
if (sh_video) {
mp_msg(MSGT_GLOBAL, MSGL_INFO,
- "ANS_SUB_VISIBILITY=%d\n", sub_visibility);
+ "ANS_SUB_VISIBILITY=%d\n", opts->sub_visibility);
}
break;
diff --git a/defaultopts.c b/defaultopts.c
index 8636fe69f0..672dbd5f5c 100644
--- a/defaultopts.c
+++ b/defaultopts.c
@@ -39,6 +39,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.audio_id = -1,
.video_id = -1,
.sub_id = -1,
+ .sub_visibility = 1,
.extension_parsing = 1,
.audio_output_channels = 2,
.audio_output_format = -1, // AF_FORMAT_UNKNOWN
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
index a346f658cf..ad4671fe57 100644
--- a/libmpcodecs/vf_ass.c
+++ b/libmpcodecs/vf_ass.c
@@ -352,19 +352,21 @@ static int render_frame(struct vf_instance *vf, mp_image_t *mpi,
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
- struct osd_state *osd = vf->priv->osd;
+ struct vf_priv_s *priv = vf->priv;
+ struct MPOpts *opts = vf->opts;
+ struct osd_state *osd = priv->osd;
ASS_Image *images = 0;
- ASS_Renderer *renderer = osd->ass_renderer;
- bool vs = osd->vsfilter_aspect && vf->opts->ass_vsfilter_aspect_compat;
- if (sub_visibility && osd->ass_track && (pts != MP_NOPTS_VALUE)) {
- struct mp_eosd_res dim = { .w = vf->priv->outw, .h = vf->priv->outh,
- .mt = vf->opts->ass_top_margin,
- .mb = vf->opts->ass_bottom_margin };
- mp_ass_configure(renderer, vf->opts, &dim, 0);
- ass_set_aspect_ratio(renderer,
- vs ? 1. : vf->priv->aspect_correction, 1);
- images = ass_render_frame(renderer, osd->ass_track,
- (pts - osd->sub_offset + sub_delay) * 1000 + .5, NULL);
+ if (pts != MP_NOPTS_VALUE) {
+ osd->dim = (struct mp_eosd_res){ .w = vf->priv->outw,
+ .h = vf->priv->outh,
+ .mt = opts->ass_top_margin,
+ .mb = opts->ass_bottom_margin };
+ osd->normal_scale = vf->priv->aspect_correction;
+ osd->vsfilter_scale = 1;
+ osd->sub_pts = pts - osd->sub_offset;
+ struct sub_bitmaps b;
+ sub_get_bitmaps(osd, &b);
+ images = b.imgs;
}
prepare_image(vf, mpi);
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 0db75b670e..076850c8c2 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -30,7 +30,6 @@
#include "libvo/video_out.h"
-#include "sub/ass_mp.h"
#include "sub/sub.h"
struct vf_priv_s {
@@ -122,40 +121,29 @@ static int control(struct vf_instance *vf, int request, void *data)
};
return vo_control(video_out, VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
}
-#ifdef CONFIG_ASS
case VFCTRL_INIT_EOSD: {
vf->priv->prev_visibility = false;
return CONTROL_TRUE;
}
case VFCTRL_DRAW_EOSD: {
- struct mp_eosd_res dim = { 0 };
+ struct osd_state *osd = data;
+ osd->dim = (struct mp_eosd_res){0};
if (!video_out->config_ok ||
- vo_control(video_out, VOCTRL_GET_EOSD_RES, &dim) != true) {
+ vo_control(video_out, VOCTRL_GET_EOSD_RES, &osd->dim) != true) {
vf->priv->prev_visibility = false;
return CONTROL_FALSE;
}
- struct osd_state *osd = data;
- mp_eosd_images_t images = { NULL, 2 };
- ASS_Renderer *renderer = osd->ass_renderer;
- double scale = 1;
- if (osd->vsfilter_aspect && vf->opts->ass_vsfilter_aspect_compat)
- scale = vf->priv->scale_ratio;
- if (sub_visibility && osd->ass_track && (osd->pts != MP_NOPTS_VALUE)) {
- mp_ass_configure(renderer, vf->opts, &dim,
- vf->default_caps & VFCAP_EOSD_UNSCALED);
- ass_set_aspect_ratio(renderer, scale, 1);
- images.imgs = ass_render_frame(renderer, osd->ass_track,
- (osd->pts + sub_delay) * 1000 + .5,
- &images.changed);
- if (!vf->priv->prev_visibility)
- images.changed = 2;
- vf->priv->prev_visibility = true;
- } else
- vf->priv->prev_visibility = false;
+ osd->normal_scale = 1;
+ osd->vsfilter_scale = vf->priv->scale_ratio;
+ osd->unscaled = vf->default_caps & VFCAP_EOSD_UNSCALED;
+ struct sub_bitmaps images;
+ sub_get_bitmaps(osd, &images);
+ if (!vf->priv->prev_visibility)
+ images.changed = 2;
+ vf->priv->prev_visibility = true;
return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE;
}
-#endif
}
return CONTROL_UNKNOWN;
}
diff --git a/libvo/eosd_packer.h b/libvo/eosd_packer.h
index e207a4a2dd..eaacd0223f 100644
--- a/libvo/eosd_packer.h
+++ b/libvo/eosd_packer.h
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include "sub/ass_mp.h"
+#include "sub/dec_sub.h"
// Pool of surfaces
struct eosd_surface {
diff --git a/mp_core.h b/mp_core.h
index ea21752767..e42beb40c5 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -107,8 +107,8 @@ struct track {
// fields. The data is stored in stream->sub this case.
// External text subtitle using libass subtitle renderer.
- struct ass_track *ass_track;
- bool native_ass_track;
+ // The sh_sub is a dummy and doesn't belong to a demuxer.
+ struct sh_sub *sh_sub;
// External text subtitle using non-libass subtitle renderer.
struct sub_data *subdata;
diff --git a/mplayer.c b/mplayer.c
index 0734defbd6..5b02e33588 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -605,8 +605,13 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_SUB) {
mpctx->initialized_flags &= ~INITIALIZED_SUB;
+ struct track *track = mpctx->current_track[STREAM_SUB];
+ // One of these was active; they can't be both active.
+ assert(!(mpctx->sh_sub && (track && track->sh_sub)));
if (mpctx->sh_sub)
sub_switchoff(mpctx->sh_sub, mpctx->osd);
+ if (track && track->sh_sub)
+ sub_switchoff(track->sh_sub, mpctx->osd);
cleanup_demux_stream(mpctx, STREAM_SUB);
reset_subtitles(mpctx);
}
@@ -623,10 +628,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
for (int i = 0; i < mpctx->num_tracks; i++) {
struct track *track = mpctx->tracks[i];
sub_free(track->subdata);
-#ifdef CONFIG_ASS
- if (track->ass_track)
- ass_free_track(track->ass_track);
-#endif
+ talloc_free(track->sh_sub);
talloc_free(track);
}
mpctx->num_tracks = 0;
@@ -1040,16 +1042,16 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
{
struct MPOpts *opts = &mpctx->opts;
sub_data *subd = NULL;
- struct ass_track *asst = NULL;
- bool is_native_ass = false;
+ struct sh_sub *sh = NULL;
if (filename == NULL)
return;
-#ifdef CONFIG_ASS
if (opts->ass_enabled) {
- asst = mp_ass_read_stream(mpctx->ass_library, filename, sub_cp);
- is_native_ass = asst;
+#ifdef CONFIG_ASS
+ struct ass_track *asst = mp_ass_read_stream(mpctx->ass_library,
+ filename, sub_cp);
+ bool is_native_ass = asst;
if (!asst) {
subd = sub_read_file(filename, fps, &mpctx->opts);
if (subd) {
@@ -1058,12 +1060,14 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
subd = NULL;
}
}
- } else
+ if (asst)
+ sh = sd_ass_create_from_track(asst, is_native_ass, opts);
#endif
- subd = sub_read_file(filename, fps, &mpctx->opts);
+ } else
+ subd = sub_read_file(filename, fps, &mpctx->opts);
- if (!asst && !subd) {
+ if (!sh && !subd) {
mp_tmsg(MSGT_CPLAYER, noerr ? MSGL_WARN : MSGL_ERR,
"Cannot load subtitles: %s\n", filename);
return;
@@ -1072,11 +1076,11 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
struct track *track = talloc_ptrtype(NULL, track);
*track = (struct track) {
.type = STREAM_SUB,
+ .title = talloc_strdup(track, filename),
.user_tid = find_new_tid(mpctx, STREAM_SUB),
.demuxer_id = -1,
.is_external = true,
- .ass_track = asst,
- .native_ass_track = is_native_ass,
+ .sh_sub = sh,
.subdata = subd,
};
MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
@@ -1743,10 +1747,6 @@ double playing_audio_pts(struct MPContext *mpctx)
static void reset_subtitles(struct MPContext *mpctx)
{
- struct sh_sub *sh_sub = mpctx->sh_sub;
-
- if (sh_sub)
- sub_reset(sh_sub, mpctx->osd);
sub_clear_text(&mpctx->subs, MP_NOPTS_VALUE);
if (vo_sub)
set_osd_subtitle(mpctx, NULL);
@@ -1941,7 +1941,6 @@ static void reinit_subs(struct MPContext *mpctx)
init_demux_stream(mpctx, STREAM_SUB);
- mpctx->osd->ass_track = NULL;
vobsub_id = -1;
if (!track)
@@ -1967,20 +1966,17 @@ static void reinit_subs(struct MPContext *mpctx)
if (track->vobsub_id_plus_one) {
vobsub_id = track->vobsub_id_plus_one - 1;
- } else if (track->subdata || track->ass_track) {
+ } else if (track->subdata || track->sh_sub) {
#ifdef CONFIG_ASS
- if (opts->ass_enabled && track->ass_track) {
- mpctx->osd->ass_track = track->ass_track;
- mpctx->osd->vsfilter_aspect = track->native_ass_track;
- }
+ if (opts->ass_enabled && track->sh_sub)
+ sub_init(track->sh_sub, mpctx->osd);
#endif
vo_osd_changed(OSDTYPE_SUBTITLE);
} else if (track->stream) {
if (mpctx->sh_sub->type == 'v')
init_vo_spudec(mpctx);
- else {
+ else
sub_init(mpctx->sh_sub, mpctx->osd);
- }
}
}
@@ -2365,11 +2361,9 @@ int reinit_video_chain(struct MPContext *mpctx)
sh_video->vfilter = append_filters(sh_video->vfilter, opts->vf_settings);
-#ifdef CONFIG_ASS
if (opts->ass_enabled)
sh_video->vfilter->control(sh_video->vfilter, VFCTRL_INIT_EOSD,
mpctx->ass_library);
-#endif
init_best_video_codec(sh_video, video_codec_list, video_fm_list);
@@ -2616,7 +2610,10 @@ static int redraw_osd(struct MPContext *mpctx)
return -1;
if (vo_redraw_frame(mpctx->video_out) < 0)
return -1;
- mpctx->osd->pts = mpctx->video_pts - mpctx->osd->sub_offset;
+ mpctx->osd->sub_pts = mpctx->video_pts;
+ if (mpctx->osd->sub_pts != MP_NOPTS_VALUE)
+ mpctx->osd->sub_pts += sub_delay - mpctx->osd->sub_offset;
+
if (!(sh_video->output_flags & VFCAP_EOSD_FILTER))
vf->control(vf, VFCTRL_DRAW_EOSD, mpctx->osd);
vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
@@ -3215,7 +3212,9 @@ static void run_playloop(struct MPContext *mpctx)
update_subtitles(mpctx, sh_video->pts);
update_osd_msg(mpctx);
struct vf_instance *vf = sh_video->vfilter;
- mpctx->osd->pts = mpctx->video_pts - mpctx->osd->sub_offset;
+ mpctx->osd->sub_pts = mpctx->video_pts;
+ if (mpctx->osd->sub_pts != MP_NOPTS_VALUE)
+ mpctx->osd->sub_pts += sub_delay - mpctx->osd->sub_offset;
vf->control(vf, VFCTRL_DRAW_EOSD, mpctx->osd);
vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
vo_osd_reset_changed();
@@ -4048,7 +4047,6 @@ terminate_playback: // don't jump here after ao/vo/getch initialization!
vo_sub = NULL;
#ifdef CONFIG_ASS
- mpctx->osd->ass_track = NULL;
if (mpctx->osd->ass_renderer)
ass_renderer_done(mpctx->osd->ass_renderer);
mpctx->osd->ass_renderer = NULL;
diff --git a/options.h b/options.h
index 307f9682b3..2b06535afd 100644
--- a/options.h
+++ b/options.h
@@ -74,6 +74,7 @@ typedef struct MPOpts {
int sub_id;
char **audio_lang;
char **sub_lang;
+ int sub_visibility;
int hr_mp3_seek;
char *quvi_format;
diff --git a/sub/ass_mp.h b/sub/ass_mp.h
index 095cf4311d..3cfbe147b7 100644
--- a/sub/ass_mp.h
+++ b/sub/ass_mp.h
@@ -61,10 +61,4 @@ typedef struct ass_image {
#endif
-typedef struct {
- ASS_Image *imgs;
- int changed;
-} mp_eosd_images_t;
-
-
#endif /* MPLAYER_ASS_MP_H */
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 7528e90e58..c710ff575a 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -22,8 +22,9 @@
#include "config.h"
#include "libmpdemux/stheader.h"
-#include "sd.h"
-#include "dec_sub.h"
+#include "sub/sd.h"
+#include "sub/sub.h"
+#include "sub/dec_sub.h"
#include "options.h"
extern const struct sd_functions sd_ass;
@@ -33,6 +34,7 @@ void sub_init(struct sh_sub *sh, struct osd_state *osd)
{
struct MPOpts *opts = sh->opts;
+ assert(!osd->sh_sub);
#ifdef CONFIG_ASS
if (opts->ass_enabled && is_text_sub(sh->type))
sh->sd_driver = &sd_ass;
@@ -42,6 +44,8 @@ void sub_init(struct sh_sub *sh, struct osd_state *osd)
if (sh->sd_driver) {
if (sh->sd_driver->init(sh, osd) < 0)
return;
+ osd->sh_sub = sh;
+ osd->changed_outside_sd = true;
sh->initialized = true;
sh->active = true;
}
@@ -54,6 +58,22 @@ void sub_decode(struct sh_sub *sh, struct osd_state *osd, void *data,
sh->sd_driver->decode(sh, osd, data, data_len, pts, duration);
}
+void sub_get_bitmaps(struct osd_state *osd, struct sub_bitmaps *res)
+{
+ struct MPOpts *opts = osd->opts;
+
+ *res = (struct sub_bitmaps){.imgs = NULL, .changed = 2};
+ if (!opts->sub_visibility || !osd->sh_sub || !osd->sh_sub->active) {
+ osd->changed_outside_sd = true;
+ return;
+ }
+ if (osd->sh_sub->sd_driver->get_bitmaps)
+ osd->sh_sub->sd_driver->get_bitmaps(osd->sh_sub, osd, res);
+ if (osd->changed_outside_sd)
+ res->changed = 2;
+ osd->changed_outside_sd = false;
+}
+
void sub_reset(struct sh_sub *sh, struct osd_state *osd)
{
if (sh->active && sh->sd_driver->reset)
@@ -62,8 +82,11 @@ void sub_reset(struct sh_sub *sh, struct osd_state *osd)
void sub_switchoff(struct sh_sub *sh, struct osd_state *osd)
{
- if (sh->active && sh->sd_driver->switch_off)
+ if (sh->active && sh->sd_driver->switch_off) {
+ assert(osd->sh_sub == sh);
sh->sd_driver->switch_off(sh, osd);
+ osd->sh_sub = NULL;
+ }
sh->active = false;
}
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index e58ad65550..f09b555685 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -3,12 +3,18 @@
struct sh_sub;
struct osd_state;
+struct ass_track;
typedef struct mp_eosd_res {
int w, h; // screen dimensions, including black borders
int mt, mb, ml, mr; // borders (top, bottom, left, right)
} mp_eosd_res_t;
+typedef struct sub_bitmaps {
+ struct ass_image *imgs;
+ int changed;
+} mp_eosd_images_t;
+
static inline bool is_text_sub(int type)
{
return type == 't' || type == 'm' || type == 'a';
@@ -16,9 +22,14 @@ static inline bool is_text_sub(int type)
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 sub_bitmaps *res);
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);
+
#endif
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index 9f15173442..e770215ce6 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -331,9 +331,11 @@ void vo_update_text_progbar(struct osd_state *osd, mp_osd_obj_t* obj)
void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t* obj)
{
+ struct MPOpts *opts = osd->opts;
+
obj->flags |= OSDFLAG_CHANGED | OSDFLAG_VISIBLE;
- if (!vo_sub || !sub_visibility) {
+ if (!vo_sub || !opts->sub_visibility) {
obj->flags &= ~OSDFLAG_VISIBLE;
return;
}
diff --git a/sub/sd.h b/sub/sd.h
index c36110277b..7a0740f823 100644
--- a/sub/sd.h
+++ b/sub/sd.h
@@ -3,11 +3,14 @@
struct osd_state;
struct sh_sub;
+struct sub_bitmaps;
struct sd_functions {
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 sub_bitmaps *res);
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 f54c18e805..72dee06018 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -23,6 +23,7 @@
#include "talloc.h"
+#include "options.h"
#include "mpcommon.h"
#include "mp_msg.h"
#include "libmpdemux/stheader.h"
@@ -33,6 +34,7 @@
struct sd_ass_priv {
struct ass_track *ass_track;
+ bool vsfilter_aspect;
bool incomplete_event;
};
@@ -61,9 +63,7 @@ static int init(struct sh_sub *sh, struct osd_state *osd)
ctx->ass_track = mp_ass_default_track(osd->ass_library, sh->opts);
}
- assert(osd->ass_track == NULL);
- osd->ass_track = ctx->ass_track;
- osd->vsfilter_aspect = sh->type == 'a';
+ ctx->vsfilter_aspect = sh->type == 'a';
return 0;
}
@@ -125,6 +125,25 @@ 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 sub_bitmaps *res)
+{
+ struct sd_ass_priv *ctx = sh->context;
+ struct MPOpts *opts = osd->opts;
+
+ if (osd->sub_pts == MP_NOPTS_VALUE)
+ return;
+
+ double scale = osd->normal_scale;
+ if (ctx->vsfilter_aspect && opts->ass_vsfilter_aspect_compat)
+ scale = osd->vsfilter_scale;
+ ASS_Renderer *renderer = osd->ass_renderer;
+ mp_ass_configure(renderer, opts, &osd->dim, osd->unscaled);
+ ass_set_aspect_ratio(renderer, scale, 1);
+ res->imgs = ass_render_frame(renderer, ctx->ass_track,
+ osd->sub_pts * 1000 + .5, &res->changed);
+}
+
static void reset(struct sh_sub *sh, struct osd_state *osd)
{
struct sd_ass_priv *ctx = sh->context;
@@ -133,12 +152,6 @@ static void reset(struct sh_sub *sh, struct osd_state *osd)
ctx->incomplete_event = false;
}
-static void switch_off(struct sh_sub *sh, struct osd_state *osd)
-{
- reset(sh, osd);
- osd->ass_track = NULL;
-}
-
static void uninit(struct sh_sub *sh)
{
struct sd_ass_priv *ctx = sh->context;
@@ -150,7 +163,27 @@ static void uninit(struct sh_sub *sh)
const struct sd_functions sd_ass = {
.init = init,
.decode = decode,
+ .get_bitmaps = get_bitmaps,
.reset = reset,
- .switch_off = switch_off,
+ .switch_off = reset,
.uninit = uninit,
};
+
+
+struct sh_sub *sd_ass_create_from_track(struct ass_track *track,
+ bool vsfilter_aspect,
+ struct MPOpts *opts)
+{
+ struct sh_sub *sh = talloc(NULL, struct sh_sub);
+ *sh = (struct sh_sub) {
+ .opts = opts,
+ .type = 'a',
+ .sd_driver = &sd_ass,
+ .context = talloc_struct(sh, struct sd_ass_priv, {
+ .ass_track = track,
+ .vsfilter_aspect = vsfilter_aspect,
+ }),
+ .initialized = true,
+ };
+ return sh;
+}
diff --git a/sub/sub.c b/sub/sub.c
index 67413c936e..5b5920d23c 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -30,6 +30,7 @@
#include "osdep/timer.h"
#include "talloc.h"
+#include "options.h"
#include "mplayer.h"
#include "mp_msg.h"
#include "libvo/video_out.h"
@@ -170,6 +171,7 @@ static int osd_update_ext(struct osd_state *osd, int dxs, int dys,
int left_border, int top_border, int right_border,
int bottom_border, int orig_w, int orig_h)
{
+ struct MPOpts *opts = osd->opts;
mp_osd_obj_t* obj=vo_osd_list;
int chg=0;
@@ -190,7 +192,7 @@ static int osd_update_ext(struct osd_state *osd, int dxs, int dys,
vo_update_text_progbar(osd, obj);
break;
case OSDTYPE_SPU:
- if(sub_visibility && vo_spudec && spudec_visible(vo_spudec)){
+ if (opts->sub_visibility && vo_spudec && spudec_visible(vo_spudec)){
vo_update_spudec_sub(osd, obj);
obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED;
}
diff --git a/sub/sub.h b/sub/sub.h
index 3ad8dc9217..8a8a2ab941 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -62,15 +62,19 @@ typedef struct mp_osd_obj_s {
struct osd_state {
struct ass_library *ass_library;
struct ass_renderer *ass_renderer;
- int w, h;
- char *osd_text;
- struct ass_track *ass_track;
- double pts;
+ struct sh_sub *sh_sub;
+ bool changed_outside_sd;
+ double sub_pts;
double sub_offset;
- bool vsfilter_aspect;
+ struct mp_eosd_res dim;
+ double normal_scale;
+ double vsfilter_scale;
+ bool unscaled;
struct ass_renderer *osd_render;
struct ass_library *osd_ass_library;
+ char *osd_text;
+ int w, h;
struct MPOpts *opts;
};
@@ -113,7 +117,6 @@ extern char *sub_cp;
extern int sub_pos;
extern int sub_width_p;
extern int sub_alignment;
-extern int sub_visibility;
extern int sub_bg_color; /* subtitles background color */
extern int sub_bg_alpha;
extern int spu_alignment;