summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
Diffstat (limited to 'sub')
-rw-r--r--sub/osd.h13
-rw-r--r--sub/osd_dummy.c7
-rw-r--r--sub/osd_libass.c97
-rw-r--r--sub/osd_state.h6
4 files changed, 84 insertions, 39 deletions
diff --git a/sub/osd.h b/sub/osd.h
index 660a828767..31b3dd532b 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -202,9 +202,18 @@ struct mp_osd_res osd_get_vo_res(struct osd_state *osd);
void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,
struct mp_osd_res res, double compensate_par);
+struct osd_external_ass {
+ void *owner; // unique pointer (NULL is also allowed)
+ int64_t id;
+ int format;
+ char *data;
+ int res_x, res_y;
+ int z;
+};
+
// defined in osd_libass.c and osd_dummy.c
-void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,
- char *text);
+void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov);
+void osd_set_external_remove_owner(struct osd_state *osd, void *owner);
void osd_get_text_size(struct osd_state *osd, int *out_screen_h, int *out_font_h);
void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);
diff --git a/sub/osd_dummy.c b/sub/osd_dummy.c
index 0e6b802cef..db032ec5b1 100644
--- a/sub/osd_dummy.c
+++ b/sub/osd_dummy.c
@@ -24,8 +24,11 @@ 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, void *id, int res_x, int res_y,
- char *text)
+void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov)
+{
+}
+
+void osd_set_external_remove_owner(struct osd_state *osd, void *owner)
{
}
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index d5f7bb82bf..01c0337eb4 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -80,8 +80,8 @@ static void destroy_ass_renderer(struct ass_state *ass)
static void destroy_external(struct osd_external *ext)
{
- talloc_free(ext->text);
destroy_ass_renderer(&ext->ass);
+ talloc_free(ext);
}
void osd_destroy_backend(struct osd_state *osd)
@@ -90,7 +90,7 @@ void osd_destroy_backend(struct osd_state *osd)
struct osd_object *obj = osd->objs[n];
destroy_ass_renderer(&obj->ass);
for (int i = 0; i < obj->num_externals; i++)
- destroy_external(&obj->externals[i]);
+ destroy_external(obj->externals[i]);
obj->num_externals = 0;
}
}
@@ -470,11 +470,9 @@ static void update_osd(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(ext->text);
- if (!t.len)
- return;
- ext->ass.res_x = ext->res_x;
- ext->ass.res_y = ext->res_y;
+ bstr t = bstr0(ext->ov.data);
+ ext->ass.res_x = ext->ov.res_x;
+ ext->ass.res_y = ext->ov.res_y;
create_ass_track(osd, obj, &ext->ass);
clear_ass(&ext->ass);
@@ -497,29 +495,42 @@ static void update_external(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)
+static int cmp_zorder(const void *pa, const void *pb)
+{
+ const struct osd_external *a = *(struct osd_external **)pa;
+ const struct osd_external *b = *(struct osd_external **)pb;
+ return a->ov.z == b->ov.z ? 0 : (a->ov.z > b->ov.z ? 1 : -1);
+}
+
+void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov)
{
pthread_mutex_lock(&osd->lock);
struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
- struct osd_external *entry = 0;
+ bool zorder_changed = false;
+ int index = -1;
+
for (int n = 0; n < obj->num_externals; n++) {
- if (obj->externals[n].id == id) {
- entry = &obj->externals[n];
+ struct osd_external *e = obj->externals[n];
+ if (e->ov.id == ov->id && e->ov.owner == ov->owner) {
+ index = n;
break;
}
}
- if (!entry && !text)
- goto done;
- if (!entry) {
- struct osd_external new = { .id = id };
+ if (index < 0) {
+ if (!ov->format)
+ goto done;
+ struct osd_external *new = talloc_zero(NULL, struct osd_external);
+ new->ov.owner = ov->owner;
+ new->ov.id = ov->id;
MP_TARRAY_APPEND(obj, obj->externals, obj->num_externals, new);
- entry = &obj->externals[obj->num_externals - 1];
+ index = obj->num_externals - 1;
+ zorder_changed = true;
}
- if (!text) {
- int index = entry - &obj->externals[0];
+ struct osd_external *entry = obj->externals[index];
+
+ if (!ov->format) {
destroy_external(entry);
MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, index);
obj->changed = true;
@@ -527,22 +538,46 @@ void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,
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->changed = true;
- osd->want_redraw_notification = true;
+ entry->ov.format = ov->format;
+ if (!entry->ov.data)
+ entry->ov.data = talloc_strdup(entry, "");
+ entry->ov.data[0] = '\0'; // reuse memory allocation
+ entry->ov.data = talloc_strdup_append(entry->ov.data, ov->data);
+ entry->ov.res_x = ov->res_x;
+ entry->ov.res_y = ov->res_y;
+ zorder_changed |= entry->ov.z != ov->z;
+ entry->ov.z = ov->z;
+
+ update_external(osd, obj, entry);
+
+ obj->changed = true;
+ osd->want_redraw_notification = true;
+
+ if (zorder_changed) {
+ qsort(obj->externals, obj->num_externals, sizeof(obj->externals[0]),
+ cmp_zorder);
}
done:
pthread_mutex_unlock(&osd->lock);
}
+void osd_set_external_remove_owner(struct osd_state *osd, void *owner)
+{
+ pthread_mutex_lock(&osd->lock);
+ struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
+ for (int n = obj->num_externals - 1; n >= 0; n--) {
+ struct osd_external *e = obj->externals[n];
+ if (e->ov.owner == owner) {
+ destroy_external(e);
+ MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, n);
+ obj->changed = true;
+ osd->want_redraw_notification = true;
+ }
+ }
+ pthread_mutex_unlock(&osd->lock);
+}
+
static void append_ass(struct ass_state *ass, struct mp_osd_res *res,
ASS_Image **img_list, bool *changed)
{
@@ -574,8 +609,8 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj,
append_ass(&obj->ass, &obj->vo_res, &obj->ass_imgs[0], &obj->changed);
for (int n = 0; n < obj->num_externals; n++) {
- append_ass(&obj->externals[n].ass, &obj->vo_res, &obj->ass_imgs[n + 1],
- &obj->changed);
+ append_ass(&obj->externals[n]->ass, &obj->vo_res,
+ &obj->ass_imgs[n + 1], &obj->changed);
}
mp_ass_packer_pack(obj->ass_packer, obj->ass_imgs, obj->num_externals + 1,
diff --git a/sub/osd_state.h b/sub/osd_state.h
index ac8befe3ba..8207cf0dda 100644
--- a/sub/osd_state.h
+++ b/sub/osd_state.h
@@ -38,7 +38,7 @@ struct osd_object {
struct dec_sub *sub;
// OSDTYPE_EXTERNAL
- struct osd_external *externals;
+ struct osd_external **externals;
int num_externals;
// OSDTYPE_EXTERNAL2
@@ -56,9 +56,7 @@ struct osd_object {
};
struct osd_external {
- void *id;
- char *text;
- int res_x, res_y;
+ struct osd_external_ass ov;
struct ass_state ass;
};