mirror of https://github.com/mpv-player/mpv
osd: use the same ASS_Renderer for OSD text and progbar
Reduces memory usage and startup times. The implementation is a bit weird, because both OSD parts have conflicting requirements on the used ASS styles.
This commit is contained in:
parent
73e0d545ce
commit
2b07d3eb47
|
@ -188,7 +188,7 @@ void osd_set_render_subs_in_filter(struct osd_state *osd, bool s)
|
|||
void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s)
|
||||
{
|
||||
pthread_mutex_lock(&osd->lock);
|
||||
struct osd_object *osd_obj = osd->objs[OSDTYPE_PROGBAR];
|
||||
struct osd_object *osd_obj = osd->objs[OSDTYPE_OSD];
|
||||
osd_obj->progbar_state.type = s->type;
|
||||
osd_obj->progbar_state.value = s->value;
|
||||
osd_obj->progbar_state.num_stops = s->num_stops;
|
||||
|
|
|
@ -82,7 +82,6 @@ enum mp_osdtype {
|
|||
OSDTYPE_SUB,
|
||||
OSDTYPE_SUB2, // IDs must be numerically successive
|
||||
|
||||
OSDTYPE_PROGBAR,
|
||||
OSDTYPE_OSD,
|
||||
|
||||
OSDTYPE_EXTERNAL,
|
||||
|
|
|
@ -81,7 +81,7 @@ void osd_destroy_backend(struct osd_state *osd)
|
|||
}
|
||||
|
||||
static void create_ass_track(struct osd_state *osd, struct osd_object *obj,
|
||||
int res_x, int res_y)
|
||||
int res_x, int res_y, int n_default_styles)
|
||||
{
|
||||
create_ass_renderer(osd, obj);
|
||||
|
||||
|
@ -107,25 +107,30 @@ static void create_ass_track(struct osd_state *osd, struct osd_object *obj,
|
|||
if (old_res_x != track->PlayResX || old_res_y != track->PlayResY)
|
||||
ass_set_frame_size(obj->osd_render, 1, 1);
|
||||
|
||||
if (track->n_styles < 2) {
|
||||
int sid = ass_alloc_style(track);
|
||||
track->default_style = sid;
|
||||
ASS_Style *style = track->styles + sid;
|
||||
style->Name = strdup("OSD");
|
||||
// Set to neutral base direction, as opposed to VSFilter LTR default
|
||||
style->Encoding = -1;
|
||||
|
||||
sid = ass_alloc_style(track);
|
||||
assert(sid == track->default_style + 1);
|
||||
style = track->styles + sid;
|
||||
if (track->n_styles < 1 + n_default_styles) {
|
||||
int sid1 = ass_alloc_style(track);
|
||||
ASS_Style *style = track->styles + sid1;
|
||||
style->Name = strdup("Default");
|
||||
style->Encoding = -1;
|
||||
|
||||
for (int n = 0; n < n_default_styles; n++) {
|
||||
int sid2 = ass_alloc_style(track);
|
||||
if (n == 0)
|
||||
track->default_style = sid2;
|
||||
assert(sid1 + 1 == track->default_style);
|
||||
style = track->styles + sid2;
|
||||
style->Name = strdup("OSD");
|
||||
// Set to neutral base direction, as opposed to VSFilter LTR default
|
||||
style->Encoding = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ASS_Style *s_osd = track->styles + track->default_style;
|
||||
mp_ass_set_style(s_osd, track->PlayResY, osd->opts->osd_style);
|
||||
for (int n = 0; n < n_default_styles; n++) {
|
||||
ASS_Style *s_osd = track->styles + track->default_style + n;
|
||||
mp_ass_set_style(s_osd, track->PlayResY, osd->opts->osd_style);
|
||||
}
|
||||
|
||||
ASS_Style *s_def = track->styles + track->default_style + 1;
|
||||
ASS_Style *s_def = track->styles + track->default_style - 1;
|
||||
const struct osd_style_opts *def = osd_style_conf.defaults;
|
||||
mp_ass_set_style(s_def, track->PlayResY, def);
|
||||
|
||||
|
@ -189,23 +194,23 @@ static void mangle_ass(bstr *dst, const char *in)
|
|||
}
|
||||
}
|
||||
|
||||
static void add_osd_ass_event_escaped(ASS_Track *track, const char *text)
|
||||
static ASS_Event *add_osd_ass_event_escaped(ASS_Track *track, const char *text)
|
||||
{
|
||||
bstr buf = {0};
|
||||
mangle_ass(&buf, text);
|
||||
add_osd_ass_event(track, buf.start);
|
||||
ASS_Event *e = add_osd_ass_event(track, buf.start);
|
||||
talloc_free(buf.start);
|
||||
return e;
|
||||
}
|
||||
|
||||
static void update_osd(struct osd_state *osd, struct osd_object *obj)
|
||||
static void update_osd_text(struct osd_state *osd, struct osd_object *obj)
|
||||
{
|
||||
struct MPOpts *opts = osd->opts;
|
||||
|
||||
clear_obj(obj);
|
||||
if (!obj->text[0])
|
||||
return;
|
||||
|
||||
create_ass_track(osd, obj, 0, 0);
|
||||
create_ass_track(osd, obj, 0, 0, 2);
|
||||
|
||||
struct osd_style_opts font = *opts->osd_style;
|
||||
font.font_size *= opts->osd_scale;
|
||||
|
@ -215,10 +220,15 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj)
|
|||
if (!opts->osd_scale_by_window)
|
||||
playresy *= 720.0 / obj->vo_res.h;
|
||||
|
||||
ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style;
|
||||
// the 1st style is used for the progbar
|
||||
int style_id = obj->osd_track->default_style + 1;
|
||||
|
||||
ASS_Style *style = obj->osd_track->styles + style_id;
|
||||
mp_ass_set_style(style, playresy, &font);
|
||||
|
||||
add_osd_ass_event_escaped(obj->osd_track, obj->text);
|
||||
ASS_Event *e = add_osd_ass_event_escaped(obj->osd_track, obj->text);
|
||||
if (e)
|
||||
e->Style = style_id;
|
||||
}
|
||||
|
||||
// align: -1 .. +1
|
||||
|
@ -301,7 +311,7 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj,
|
|||
{
|
||||
struct MPOpts *opts = osd->opts;
|
||||
|
||||
create_ass_track(osd, obj, 0, 0);
|
||||
create_ass_track(osd, obj, 0, 0, 2);
|
||||
ASS_Track *track = obj->osd_track;
|
||||
ASS_Style *style = track->styles + track->default_style;
|
||||
|
||||
|
@ -327,8 +337,6 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj,
|
|||
|
||||
static void update_progbar(struct osd_state *osd, struct osd_object *obj)
|
||||
{
|
||||
clear_obj(obj);
|
||||
|
||||
if (obj->progbar_state.type < 0)
|
||||
return;
|
||||
|
||||
|
@ -403,6 +411,13 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
|
|||
ass_draw_reset(d);
|
||||
}
|
||||
|
||||
static void update_osd(struct osd_state *osd, struct osd_object *obj)
|
||||
{
|
||||
clear_obj(obj);
|
||||
update_osd_text(osd, obj);
|
||||
update_progbar(osd, obj);
|
||||
}
|
||||
|
||||
static void update_external(struct osd_state *osd, struct osd_object *obj)
|
||||
{
|
||||
clear_obj(obj);
|
||||
|
@ -410,7 +425,7 @@ static void update_external(struct osd_state *osd, struct osd_object *obj)
|
|||
bstr t = bstr0(obj->text);
|
||||
if (!t.len)
|
||||
return;
|
||||
create_ass_track(osd, obj, obj->external_res_x, obj->external_res_y);
|
||||
create_ass_track(osd, obj, obj->external_res_x, obj->external_res_y, 1);
|
||||
|
||||
while (t.len) {
|
||||
bstr line;
|
||||
|
@ -429,9 +444,6 @@ static void update_object(struct osd_state *osd, struct osd_object *obj)
|
|||
case OSDTYPE_OSD:
|
||||
update_osd(osd, obj);
|
||||
break;
|
||||
case OSDTYPE_PROGBAR:
|
||||
update_progbar(osd, obj);
|
||||
break;
|
||||
case OSDTYPE_EXTERNAL:
|
||||
update_external(osd, obj);
|
||||
break;
|
||||
|
|
|
@ -16,7 +16,7 @@ struct osd_object {
|
|||
// OSDTYPE_SUB/OSDTYPE_SUB2/OSDTYPE_OSD/OSDTYPE_EXTERNAL
|
||||
char *text;
|
||||
|
||||
// OSDTYPE_PROGBAR
|
||||
// OSDTYPE_OSD
|
||||
struct osd_progbar_state progbar_state;
|
||||
|
||||
// OSDTYPE_SUB/OSDTYPE_SUB2
|
||||
|
|
Loading…
Reference in New Issue