mirror of
https://github.com/mpv-player/mpv
synced 2025-02-03 21:52:12 +00:00
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.
This commit is contained in:
parent
3194058309
commit
78b5324eee
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user