From 89a57148934ec7f150a6170ac1313f6f5c636596 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sat, 25 Aug 2012 21:22:39 +0300 Subject: 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 --- command.c | 17 ++++++--------- defaultopts.c | 1 + libmpcodecs/vf_ass.c | 26 ++++++++++++----------- libmpcodecs/vf_vo.c | 34 ++++++++++------------------- libvo/eosd_packer.h | 1 + mp_core.h | 4 ++-- mplayer.c | 60 +++++++++++++++++++++++++--------------------------- options.h | 1 + sub/ass_mp.h | 6 ------ sub/dec_sub.c | 29 ++++++++++++++++++++++--- sub/dec_sub.h | 11 ++++++++++ sub/osd_libass.c | 4 +++- sub/sd.h | 3 +++ sub/sd_ass.c | 53 +++++++++++++++++++++++++++++++++++++--------- sub/sub.c | 4 +++- sub/sub.h | 15 +++++++------ 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, ¶m) == 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 #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; -- cgit v1.2.3