summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-15 15:04:49 +0100
committerwm4 <wm4@nowhere>2013-12-15 15:04:49 +0100
commit78b5324eeefc2b8a235a8ea412283491ee009a1e (patch)
tree781e871012c9ba25010323142d39b1ea9845b292 /sub
parent319405830996b2bc73e9cdf437e389f2045adafe (diff)
downloadmpv-78b5324eeefc2b8a235a8ea412283491ee009a1e.tar.bz2
mpv-78b5324eeefc2b8a235a8ea412283491ee009a1e.tar.xz
osd: use separate ASS_Renderer for each OSD object
This simplifies things, although it is slightly less efficient (probably uses a bit more memory). This also happens to fix that the OSC dropped the libass cache on every frame.
Diffstat (limited to 'sub')
-rw-r--r--sub/ass_mp.c5
-rw-r--r--sub/osd.h8
-rw-r--r--sub/osd_libass.c86
3 files changed, 53 insertions, 46 deletions
diff --git a/sub/ass_mp.c b/sub/ass_mp.c
index 72c22d54e6..5ae85c0d06 100644
--- a/sub/ass_mp.c
+++ b/sub/ass_mp.c
@@ -222,9 +222,10 @@ static void message_callback(int level, const char *format, va_list va, void *ct
ASS_Library *mp_ass_init(struct MPOpts *opts)
{
- ASS_Library *priv;
char *path = mp_find_user_config_file("fonts");
- priv = ass_library_init();
+ ASS_Library *priv = ass_library_init();
+ if (!priv)
+ abort();
ass_set_message_cb(priv, message_callback, NULL);
if (path)
ass_set_fonts_dir(priv, path);
diff --git a/sub/osd.h b/sub/osd.h
index 7f8a2f2141..d869700a92 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -115,8 +115,10 @@ struct osd_object {
struct mp_osd_res vo_res;
// Internally used by osd_libass.c
- struct ass_track *osd_track;
struct sub_bitmap *parts_cache;
+ struct ass_track *osd_track;
+ struct ass_renderer *osd_render;
+ struct ass_library *osd_ass_library;
};
struct osd_state {
@@ -155,10 +157,6 @@ struct osd_state {
// Internal to sub.c
struct mp_draw_sub_cache *draw_cache;
-
- // Internally used by osd_libass.c
- struct ass_renderer *osd_render;
- struct ass_library *osd_ass_library;
};
// Start of OSD symbols in osd_font.pfb
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index 71255256a9..38ae0b99cb 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -41,13 +41,23 @@ static const char osd_font_pfb[] =
void osd_init_backend(struct osd_state *osd)
{
- osd->osd_ass_library = mp_ass_init(osd->opts);
- ass_add_font(osd->osd_ass_library, "mpv-osd-symbols", (void *)osd_font_pfb,
+}
+
+static void create_ass_renderer(struct osd_state *osd, struct osd_object *obj)
+{
+ if (obj->osd_render)
+ return;
+
+ obj->osd_ass_library = mp_ass_init(osd->opts);
+ ass_add_font(obj->osd_ass_library, "mpv-osd-symbols", (void *)osd_font_pfb,
sizeof(osd_font_pfb) - 1);
- osd->osd_render = ass_renderer_init(osd->osd_ass_library);
- mp_ass_configure_fonts(osd->osd_render, osd->opts->osd_style);
- ass_set_aspect_ratio(osd->osd_render, 1.0, 1.0);
+ obj->osd_render = ass_renderer_init(obj->osd_ass_library);
+ if (!obj->osd_render)
+ abort();
+
+ mp_ass_configure_fonts(obj->osd_render, osd->opts->osd_style);
+ ass_set_aspect_ratio(obj->osd_render, 1.0, 1.0);
}
void osd_destroy_backend(struct osd_state *osd)
@@ -57,29 +67,41 @@ void osd_destroy_backend(struct osd_state *osd)
if (obj->osd_track)
ass_free_track(obj->osd_track);
obj->osd_track = NULL;
+ if (obj->osd_render)
+ ass_renderer_done(obj->osd_render);
+ obj->osd_render = NULL;
+ if (obj->osd_ass_library)
+ ass_library_done(obj->osd_ass_library);
+ obj->osd_ass_library = NULL;
}
- if (osd->osd_render)
- ass_renderer_done(osd->osd_render);
- osd->osd_render = NULL;
- ass_library_done(osd->osd_ass_library);
- osd->osd_ass_library = NULL;
}
-static void create_osd_ass_track(struct osd_state *osd, struct osd_object *obj)
+static void create_ass_track(struct osd_state *osd, struct osd_object *obj,
+ int res_x, int res_y)
{
+ create_ass_renderer(osd, obj);
+
ASS_Track *track = obj->osd_track;
if (!track)
- track = ass_new_track(osd->osd_ass_library);
+ track = ass_new_track(obj->osd_ass_library);
+
+ int old_res_x = track->PlayResX;
+ int old_res_y = track->PlayResY;
double aspect = 1.0 * obj->vo_res.w / FFMAX(obj->vo_res.h, 1) /
obj->vo_res.display_par;
track->track_type = TRACK_TYPE_ASS;
track->Timer = 100.;
- track->PlayResY = MP_ASS_FONT_PLAYRESY;
- track->PlayResX = track->PlayResY * aspect;
+ track->PlayResY = res_y ? res_y : MP_ASS_FONT_PLAYRESY;
+ track->PlayResX = res_x ? res_x : track->PlayResY * aspect;
track->WrapStyle = 1; // end-of-line wrapping instead of smart wrapping
+ // Force libass to clear its internal cache - it doesn't check for
+ // PlayRes changes itself.
+ if (old_res_x != track->PlayResX || old_res_y != track->PlayResY)
+ ass_set_frame_size(obj->osd_render, 1, 1);
+
if (track->n_styles == 0) {
track->Kerning = true;
int sid = ass_alloc_style(track);
@@ -87,7 +109,7 @@ static void create_osd_ass_track(struct osd_state *osd, struct osd_object *obj)
ASS_Style *style = track->styles + sid;
style->Alignment = 5; // top-title, left
style->Name = strdup("OSD");
- mp_ass_set_style(style, MP_ASS_FONT_PLAYRESY, osd->opts->osd_style);
+ mp_ass_set_style(style, track->PlayResY, osd->opts->osd_style);
// Set to neutral base direction, as opposed to VSFilter LTR default
style->Encoding = -1;
@@ -95,7 +117,7 @@ static void create_osd_ass_track(struct osd_state *osd, struct osd_object *obj)
style = track->styles + sid;
style->Name = strdup("Default");
const struct osd_style_opts *def = osd_style_conf.defaults;
- mp_ass_set_style(style, MP_ASS_FONT_PLAYRESY, def);
+ mp_ass_set_style(style, track->PlayResY, def);
style->Encoding = -1;
}
@@ -155,7 +177,7 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj)
{
struct MPOpts *opts = osd->opts;
- create_osd_ass_track(osd, obj);
+ create_ass_track(osd, obj, 0, 0);
clear_obj(obj);
if (!osd->osd_text[0])
return;
@@ -257,7 +279,7 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj,
struct MPOpts *opts = osd->opts;
bool new_track = !obj->osd_track;
- create_osd_ass_track(osd, obj);
+ create_ass_track(osd, obj, 0, 0);
ASS_Track *track = obj->osd_track;
ASS_Style *style = track->styles + track->default_style;
@@ -361,24 +383,9 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
static void update_external(struct osd_state *osd, struct osd_object *obj)
{
- create_osd_ass_track(osd, obj);
+ create_ass_track(osd, obj, osd->external_res_x, osd->external_res_y);
clear_obj(obj);
- if (osd->external_res_x < 1 || osd->external_res_y < 1)
- return;
-
- ASS_Track *track = obj->osd_track;
-
- if (track->PlayResX != osd->external_res_x ||
- track->PlayResY != osd->external_res_y)
- {
- track->PlayResX = osd->external_res_x;
- track->PlayResY = osd->external_res_y;
- // Force libass to clear its internal cache - it doesn't check for
- // PlayRes changes itself.
- ass_set_frame_size(osd->osd_render, 1, 1);
- }
-
bstr t = bstr0(osd->external);
while (t.len) {
bstr line;
@@ -400,8 +407,9 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj)
if (!osd->sub_text || !osd->sub_text[0])
return;
+ create_ass_renderer(osd, obj);
if (!obj->osd_track)
- obj->osd_track = mp_ass_default_track(osd->osd_ass_library, osd->opts);
+ obj->osd_track = mp_ass_default_track(obj->osd_ass_library, osd->opts);
struct osd_style_opts font = *opts->sub_text_style;
font.font_size *= opts->sub_scale;
@@ -410,7 +418,7 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj)
mp_ass_set_style(style, obj->osd_track->PlayResY, &font);
#if LIBASS_VERSION >= 0x01010000
- ass_set_line_position(osd->osd_render, 100 - opts->sub_pos);
+ ass_set_line_position(obj->osd_render, 100 - opts->sub_pos);
#endif
char *escaped_text = mangle_ass(osd->sub_text);
@@ -446,9 +454,9 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj,
if (!obj->osd_track)
return;
- ass_set_frame_size(osd->osd_render, obj->vo_res.w, obj->vo_res.h);
- ass_set_aspect_ratio(osd->osd_render, obj->vo_res.display_par, 1.0);
- mp_ass_render_frame(osd->osd_render, obj->osd_track, 0,
+ ass_set_frame_size(obj->osd_render, obj->vo_res.w, obj->vo_res.h);
+ ass_set_aspect_ratio(obj->osd_render, obj->vo_res.display_par, 1.0);
+ mp_ass_render_frame(obj->osd_render, obj->osd_track, 0,
&obj->parts_cache, out_imgs);
talloc_steal(obj, obj->parts_cache);
}