mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
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:
@@ -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)
|
void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&osd->lock);
|
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.type = s->type;
|
||||||
osd_obj->progbar_state.value = s->value;
|
osd_obj->progbar_state.value = s->value;
|
||||||
osd_obj->progbar_state.num_stops = s->num_stops;
|
osd_obj->progbar_state.num_stops = s->num_stops;
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ enum mp_osdtype {
|
|||||||
OSDTYPE_SUB,
|
OSDTYPE_SUB,
|
||||||
OSDTYPE_SUB2, // IDs must be numerically successive
|
OSDTYPE_SUB2, // IDs must be numerically successive
|
||||||
|
|
||||||
OSDTYPE_PROGBAR,
|
|
||||||
OSDTYPE_OSD,
|
OSDTYPE_OSD,
|
||||||
|
|
||||||
OSDTYPE_EXTERNAL,
|
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,
|
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);
|
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)
|
if (old_res_x != track->PlayResX || old_res_y != track->PlayResY)
|
||||||
ass_set_frame_size(obj->osd_render, 1, 1);
|
ass_set_frame_size(obj->osd_render, 1, 1);
|
||||||
|
|
||||||
if (track->n_styles < 2) {
|
if (track->n_styles < 1 + n_default_styles) {
|
||||||
int sid = ass_alloc_style(track);
|
int sid1 = ass_alloc_style(track);
|
||||||
track->default_style = sid;
|
ASS_Style *style = track->styles + sid1;
|
||||||
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;
|
|
||||||
style->Name = strdup("Default");
|
style->Name = strdup("Default");
|
||||||
style->Encoding = -1;
|
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;
|
for (int n = 0; n < n_default_styles; n++) {
|
||||||
mp_ass_set_style(s_osd, track->PlayResY, osd->opts->osd_style);
|
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;
|
const struct osd_style_opts *def = osd_style_conf.defaults;
|
||||||
mp_ass_set_style(s_def, track->PlayResY, def);
|
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};
|
bstr buf = {0};
|
||||||
mangle_ass(&buf, text);
|
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);
|
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;
|
struct MPOpts *opts = osd->opts;
|
||||||
|
|
||||||
clear_obj(obj);
|
|
||||||
if (!obj->text[0])
|
if (!obj->text[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
create_ass_track(osd, obj, 0, 0);
|
create_ass_track(osd, obj, 0, 0, 2);
|
||||||
|
|
||||||
struct osd_style_opts font = *opts->osd_style;
|
struct osd_style_opts font = *opts->osd_style;
|
||||||
font.font_size *= opts->osd_scale;
|
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)
|
if (!opts->osd_scale_by_window)
|
||||||
playresy *= 720.0 / obj->vo_res.h;
|
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);
|
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
|
// 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;
|
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_Track *track = obj->osd_track;
|
||||||
ASS_Style *style = track->styles + track->default_style;
|
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)
|
static void update_progbar(struct osd_state *osd, struct osd_object *obj)
|
||||||
{
|
{
|
||||||
clear_obj(obj);
|
|
||||||
|
|
||||||
if (obj->progbar_state.type < 0)
|
if (obj->progbar_state.type < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -403,6 +411,13 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
|
|||||||
ass_draw_reset(d);
|
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)
|
static void update_external(struct osd_state *osd, struct osd_object *obj)
|
||||||
{
|
{
|
||||||
clear_obj(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);
|
bstr t = bstr0(obj->text);
|
||||||
if (!t.len)
|
if (!t.len)
|
||||||
return;
|
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) {
|
while (t.len) {
|
||||||
bstr line;
|
bstr line;
|
||||||
@@ -429,9 +444,6 @@ static void update_object(struct osd_state *osd, struct osd_object *obj)
|
|||||||
case OSDTYPE_OSD:
|
case OSDTYPE_OSD:
|
||||||
update_osd(osd, obj);
|
update_osd(osd, obj);
|
||||||
break;
|
break;
|
||||||
case OSDTYPE_PROGBAR:
|
|
||||||
update_progbar(osd, obj);
|
|
||||||
break;
|
|
||||||
case OSDTYPE_EXTERNAL:
|
case OSDTYPE_EXTERNAL:
|
||||||
update_external(osd, obj);
|
update_external(osd, obj);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct osd_object {
|
|||||||
// OSDTYPE_SUB/OSDTYPE_SUB2/OSDTYPE_OSD/OSDTYPE_EXTERNAL
|
// OSDTYPE_SUB/OSDTYPE_SUB2/OSDTYPE_OSD/OSDTYPE_EXTERNAL
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
// OSDTYPE_PROGBAR
|
// OSDTYPE_OSD
|
||||||
struct osd_progbar_state progbar_state;
|
struct osd_progbar_state progbar_state;
|
||||||
|
|
||||||
// OSDTYPE_SUB/OSDTYPE_SUB2
|
// OSDTYPE_SUB/OSDTYPE_SUB2
|
||||||
|
|||||||
Reference in New Issue
Block a user