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:
wm4 2015-11-28 19:24:31 +01:00
parent 73e0d545ce
commit 2b07d3eb47
4 changed files with 43 additions and 32 deletions

View File

@ -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;

View File

@ -82,7 +82,6 @@ enum mp_osdtype {
OSDTYPE_SUB,
OSDTYPE_SUB2, // IDs must be numerically successive
OSDTYPE_PROGBAR,
OSDTYPE_OSD,
OSDTYPE_EXTERNAL,

View File

@ -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;

View File

@ -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