diff options
Diffstat (limited to 'sub/osd_libass.c')
-rw-r--r-- | sub/osd_libass.c | 97 |
1 files changed, 66 insertions, 31 deletions
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, |