summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/lua.c7
-rw-r--r--sub/osd.c19
-rw-r--r--sub/osd.h5
-rw-r--r--sub/osd_dummy.c5
-rw-r--r--sub/osd_libass.c81
-rw-r--r--sub/osd_state.h14
6 files changed, 87 insertions, 44 deletions
diff --git a/player/lua.c b/player/lua.c
index 04c7dbb977..680577554c 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -391,6 +391,7 @@ static int load_lua(struct mpv_handle *client, const char *fname)
r = 0;
error_out:
+ osd_set_external(ctx->mpctx->osd, client, 0, 0, NULL); // remove overlay
mp_resume_all(client);
if (ctx->state)
lua_close(ctx->state);
@@ -963,14 +964,14 @@ static int script_command_native(lua_State *L)
static int script_set_osd_ass(lua_State *L)
{
- struct MPContext *mpctx = get_mpctx(L);
+ struct script_ctx *ctx = get_ctx(L);
int res_x = luaL_checkinteger(L, 1);
int res_y = luaL_checkinteger(L, 2);
const char *text = luaL_checkstring(L, 3);
if (!text[0])
text = " "; // force external OSD initialization
- osd_set_external(mpctx->osd, res_x, res_y, (char *)text);
- mp_input_wakeup(mpctx->input);
+ osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);
+ mp_input_wakeup(ctx->mpctx->input);
return 0;
}
diff --git a/sub/osd.c b/sub/osd.c
index a9bc035c73..c05fc5a0e3 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -145,7 +145,7 @@ void osd_free(struct osd_state *osd)
talloc_free(osd);
}
-static void osd_changed_unlocked(struct osd_state *osd, int obj)
+void osd_changed_unlocked(struct osd_state *osd, int obj)
{
osd->objs[obj]->force_redraw = true;
osd->want_redraw = true;
@@ -201,23 +201,6 @@ void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s)
pthread_mutex_unlock(&osd->lock);
}
-void osd_set_external(struct osd_state *osd, int res_x, int res_y, char *text)
-{
- pthread_mutex_lock(&osd->lock);
- struct osd_object *osd_obj = osd->objs[OSDTYPE_EXTERNAL];
- if (strcmp(osd_obj->text, text) != 0 ||
- osd_obj->external_res_x != res_x ||
- osd_obj->external_res_y != res_y)
- {
- talloc_free(osd_obj->text);
- osd_obj->text = talloc_strdup(osd_obj, text);
- osd_obj->external_res_x = res_x;
- osd_obj->external_res_y = res_y;
- osd_changed_unlocked(osd, osd_obj->type);
- }
- pthread_mutex_unlock(&osd->lock);
-}
-
void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs)
{
pthread_mutex_lock(&osd->lock);
diff --git a/sub/osd.h b/sub/osd.h
index c066b09645..654330f152 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -163,8 +163,6 @@ struct osd_progbar_state {
};
void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s);
-void osd_set_external(struct osd_state *osd, int res_x, int res_y, char *text);
-
void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs);
enum mp_osd_draw_flags {
@@ -203,6 +201,9 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj,
void osd_init_backend(struct osd_state *osd);
void osd_destroy_backend(struct osd_state *osd);
+void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,
+ char *text);
+
// doesn't need locking
void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);
extern const char *const osd_ass_0;
diff --git a/sub/osd_dummy.c b/sub/osd_dummy.c
index 1982870248..061f6446c3 100644
--- a/sub/osd_dummy.c
+++ b/sub/osd_dummy.c
@@ -26,3 +26,8 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj,
{
*out_imgs = (struct sub_bitmaps) {0};
}
+
+void osd_set_external(struct osd_state *osd, char *id, int res_x, int res_y,
+ char *text)
+{
+}
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index d58573a910..30d404d8c6 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -79,12 +79,21 @@ static void destroy_ass_renderer(struct ass_state *ass)
ass->log = NULL;
}
+static void destroy_external(struct osd_external *ext)
+{
+ talloc_free(ext->text);
+ destroy_ass_renderer(&ext->ass);
+}
+
void osd_destroy_backend(struct osd_state *osd)
{
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct osd_object *obj = osd->objs[n];
destroy_ass_renderer(&obj->ass);
talloc_free(obj->parts_cache.parts);
+ for (int i = 0; i < obj->num_externals; i++)
+ destroy_external(&obj->externals[i]);
+ obj->num_externals = 0;
}
}
@@ -431,44 +440,76 @@ static void update_osd(struct osd_state *osd, struct osd_object *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,
+ struct osd_external *ext)
{
- bstr t = bstr0(obj->text);
+ bstr t = bstr0(ext->text);
if (!t.len)
return;
- create_ass_track(osd, obj, &obj->ass, obj->external_res_x,
- obj->external_res_y);
+ create_ass_track(osd, obj, &ext->ass, ext->res_x, ext->res_y);
- clear_ass(&obj->ass);
+ clear_ass(&ext->ass);
- int resy = obj->ass.track->PlayResY;
- mp_ass_set_style(get_style(&obj->ass, "OSD"), resy, osd->opts->osd_style);
+ int resy = ext->ass.track->PlayResY;
+ mp_ass_set_style(get_style(&ext->ass, "OSD"), resy, osd->opts->osd_style);
// Some scripts will reference this style name with \r tags.
const struct osd_style_opts *def = osd_style_conf.defaults;
- mp_ass_set_style(get_style(&obj->ass, "Default"), resy, def);
+ mp_ass_set_style(get_style(&ext->ass, "Default"), resy, def);
while (t.len) {
bstr line;
bstr_split_tok(t, "\n", &line, &t);
if (line.len) {
char *tmp = bstrdup0(NULL, line);
- add_osd_ass_event(obj->ass.track, "OSD", tmp);
+ add_osd_ass_event(ext->ass.track, "OSD", tmp);
talloc_free(tmp);
}
}
}
-static void update_object(struct osd_state *osd, struct osd_object *obj)
+void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,
+ char *text)
{
- switch (obj->type) {
- case OSDTYPE_OSD:
- update_osd(osd, obj);
- break;
- case OSDTYPE_EXTERNAL:
- update_external(osd, obj);
- break;
+ pthread_mutex_lock(&osd->lock);
+ struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
+ struct osd_external *entry = 0;
+ for (int n = 0; n < obj->num_externals; n++) {
+ if (obj->externals[n].id == id) {
+ entry = &obj->externals[n];
+ break;
+ }
+ }
+ if (!entry && !text)
+ goto done;
+
+ if (!entry) {
+ struct osd_external new = { .id = id };
+ MP_TARRAY_APPEND(obj, obj->externals, obj->num_externals, new);
+ entry = &obj->externals[obj->num_externals - 1];
+ }
+
+ if (!text) {
+ int index = entry - &obj->externals[0];
+ destroy_external(entry);
+ MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, index);
+ goto done;
}
+
+ if (!entry->text || strcmp(entry->text, text) != 0 ||
+ entry->res_x != res_x || entry->res_y != res_y)
+ {
+ talloc_free(entry->text);
+ entry->text = talloc_strdup(NULL, text);
+ entry->res_x = res_x;
+ entry->res_y = res_y;
+ update_external(osd, obj, entry);
+ obj->parts_cache.change_id = 1;
+ osd_changed_unlocked(osd, obj->type);
+ }
+
+done:
+ pthread_mutex_unlock(&osd->lock);
}
static void append_ass(struct ass_state *ass, struct mp_osd_res *res,
@@ -485,10 +526,12 @@ static void append_ass(struct ass_state *ass, struct mp_osd_res *res,
void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj,
struct sub_bitmaps *out_imgs)
{
- if (obj->force_redraw)
- update_object(osd, obj);
+ if (obj->force_redraw && obj->type == OSDTYPE_OSD)
+ update_osd(osd, obj);
append_ass(&obj->ass, &obj->vo_res, &obj->parts_cache);
+ for (int n = 0; n < obj->num_externals; n++)
+ append_ass(&obj->externals[n].ass, &obj->vo_res, &obj->parts_cache);
*out_imgs = obj->parts_cache;
diff --git a/sub/osd_state.h b/sub/osd_state.h
index 66fee5a387..c52c3354cd 100644
--- a/sub/osd_state.h
+++ b/sub/osd_state.h
@@ -20,7 +20,7 @@ struct osd_object {
bool force_redraw;
- // OSDTYPE_SUB/OSDTYPE_SUB2/OSDTYPE_OSD/OSDTYPE_EXTERNAL
+ // OSDTYPE_OSD
char *text;
// OSDTYPE_OSD
@@ -30,7 +30,8 @@ struct osd_object {
struct dec_sub *sub;
// OSDTYPE_EXTERNAL
- int external_res_x, external_res_y;
+ struct osd_external *externals;
+ int num_externals;
// OSDTYPE_EXTERNAL2
struct sub_bitmaps *external2;
@@ -48,6 +49,13 @@ struct osd_object {
struct ass_state ass;
};
+struct osd_external {
+ void *id;
+ char *text;
+ int res_x, res_y;
+ struct ass_state ass;
+};
+
struct osd_state {
pthread_mutex_t lock;
@@ -64,4 +72,6 @@ struct osd_state {
struct mp_draw_sub_cache *draw_cache;
};
+void osd_changed_unlocked(struct osd_state *osd, int obj);
+
#endif