diff options
Diffstat (limited to 'sub')
-rw-r--r-- | sub/osd.h | 13 | ||||
-rw-r--r-- | sub/osd_dummy.c | 7 | ||||
-rw-r--r-- | sub/osd_libass.c | 97 | ||||
-rw-r--r-- | sub/osd_state.h | 6 |
4 files changed, 84 insertions, 39 deletions
@@ -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; }; |