History

client API, lua: add new API for setting OSD overlays

Lua scripting has an undocumented mp.set_osd_ass() function, which is used by osc.lua and console.lua. Apparently, 3rd party scripts also use this. It's probably time to make this a public API. The Lua implementation just bypassed the libmpv API. To make it usable by any type of client, turn it into a command, "osd-overlay". There's already a "overlay-add". Ignore it (although the manpage admits guiltiness). I don't really want to deal with that old command. Its main problem is that it uses global IDs, while I'd like to avoid that scripts mess with each others overlays (whether that is accidentally or intentionally). Maybe "overlay-add" can eventually be merged into "osd-overlay", but I'm too lazy to do that now. Scripting now uses the commands. There is a helper to manage OSD overlays. The helper is very "thin"; I only want to force script authors to use the ID allocation, which may help with putting multiple scripts into a single .lua file without causing conflicts (basically, avoiding singletons within a script's environment). The old set_osd_ass() is emulated with the new API. The JS scripting wrapper also provides a set_osd_ass() function, which calls internal mpv API. Comment that part (to keep it compiling), but I'm leaving it to @avih to finish the change.

wm4 committed 6 years ago

Commit 07287261 parent 96932fe11 files · +292 −68Browse files

Unified · Split

11 files
  1. DOCS/man/input.rst +80 −0
  2. DOCS/man/lua.rst +35 −0
  3. player/client.c +1 −1
  4. player/command.c +32 −0
  5. player/javascript.c +1 −1
  6. player/lua.c +0 −27
  7. player/lua/defaults.lua +59 −0
  8. sub/osd.h +11 −2
  9. sub/osd_dummy.c +5 −2
  10. sub/osd_libass.c +66 −31
  11. sub/osd_state.h +2 −4
DOCS/man/input.rst+80−0
@@ -937,6 +937,86 @@ Input Commands that are Possibly Subject to Change · 936 unmodified lines
937 Remove an overlay added with ``overlay-add`` and the same ID. Does nothing937 Remove an overlay added with ``overlay-add`` and the same ID. Does nothing
938 if no overlay with this ID exists.938 if no overlay with this ID exists.
939 939
940``osd-overlay``
941 Add/update/remove an OSD overlay.
942
943 (Although this sounds similar to ``overlay-add``, ``osd-overlay`` is for
944 text overlays, while ``overlay-add`` is for bitmaps. Maybe ``overlay-add``
945 will be merged into ``osd-overlay`` to remove this oddity.)
946
947 You can use this to add text overlays in ASS format. ASS has advanced
948 positioning and rendering tags, which can be used to render almost any kind
949 of vector graphics.
950
951 This command accepts the following parameters:
952
953 ``id``
954 Arbitrary integer that identifies the overlay. Multiple overlays can be
955 added by calling this command with different ``id`` parameters. Calling
956 this command with the same ``id`` replaces the previously set overlay.
957
958 There is a separate namespace for each libmpv client (i.e. IPC
959 connection, script), so IDs can be made up and assigned by the API user
960 without conflicting with other API users.
961
962 If the libmpv client is destroyed, all overlays associated with it are
963 also deleted. In particular, connecting via ``--input-ipc-server``,
964 adding an overlay, and disconnecting will remove the overlay immediately
965 again.
966
967 ``format``
968 String that gives the type of the overlay. Accepts the following values:
969
970 ``ass-events``
971 The ``data`` parameter is a string. The string is split on the
972 newline character. Every line is turned into the ``Text`` part of
973 a ``Dialogue`` ASS event. Timing is unused (but behavior of timing
974 dependent ASS tags may change in future mpv versions).
975
976 Note that it's better to put multiple lines into ``data``, instead
977 of adding multiple OSD overlays.
978
979 This provides 2 ASS ``Styles``. ``OSD`` contains the text style as
980 defined by the current ``--osd-...`` options. ``Default`` is
981 similar, and contains style that ``OSD`` would have if all options
982 were set to the default.
983
984 In addition, the ``res_x`` and ``res_y`` options specify the value
985 of the ASS ``PlayResX`` and ``PlayResY`` header fields. If ``res_y``
986 is set to 0, ``PlayResY`` is initialized to an arbitrary default
987 value (but note that the default for this command is 720, not 0).
988 If ``res_x`` is set to 0, ``PlayResX`` is set based on ``res_y``
989 such that a virtual ASS pixel has a square pixel aspect ratio.
990
991 ``none``
992 Special value that causes the overlay to be removed. Most parameters
993 other than ``id`` and ``format`` are mostly ignored.
994
995 ``data``
996 String defining the overlay contents according to the ``format``
997 parameter.
998
999 ``res_x``, ``res_y``
1000 Used if ``format`` is set to ``ass-events`` (see description there).
1001 Optional, defaults to 0/720.
1002
1003 ``z``
1004 The Z order of the overlay. Optional, defaults to 0.
1005
1006 Note that Z order between different overlays of different formats is
1007 static, and cannot be changed (currently, this means that bitmap
1008 overlays added by ``overlay-add`` are always on top of the ASS overlays
1009 added by ``osd-overlay``). In addition, the builtin OSD components are
1010 always below any of the custom OSD. (This includes subtitles of any kind
1011 as well as text rendered by ``show-text``.)
1012
1013 It's possible that future mpv versions will randomly change how Z order
1014 between different OSD formats and builtin OSD is handled.
1015
1016 Note: always use named arguments (``mpv_command_node()``). Scripts should
1017 use the ``mp.create_osd_overlay()`` helper instead of invoking this command
1018 directly.
1019
940``script-message [<arg1> [<arg2> [...]]]``1020``script-message [<arg1> [<arg2> [...]]]``
941 Send a message to all clients, and pass it the following list of arguments.1021 Send a message to all clients, and pass it the following list of arguments.
942 What this message means, how many arguments it takes, and what the arguments1022 What this message means, how many arguments it takes, and what the arguments
DOCS/man/lua.rst+35−0
@@ -536,6 +536,41 @@ are useful only in special situations. · 535 unmodified lines
536 Undo a previous registration with ``mp.register_script_message``. Does536 Undo a previous registration with ``mp.register_script_message``. Does
537 nothing if the ``name`` wasn't registered.537 nothing if the ``name`` wasn't registered.
538 538
539``mp.create_osd_overlay(format)``
540 Create an OSD overlay. This is a very thin wrapper around the ``osd-overlay``
541 command. The function returns a table, which mostly contains fields that
542 will be passed to ``osd-overlay``. The ``format`` parameter is used to
543 initialize the ``format`` field. The ``data`` field contains the text to
544 be used as overlay. For details, see the ``osd-overlay`` command.
545
546 In addition, it provides the following methods:
547
548 ``update()``
549 Commit the OSD overlay to the screen, or in other words, run the
550 ``osd-overlay`` command with the current fields of the overlay table.
551
552 ``remove()``
553 Remove the overlay from the screen. A ``update()`` call will add it
554 again.
555
556 Example:
557
558 ::
559
560 ov = mp.create_osd_overlay("ass-events")
561 ov.data = "{\\an5}{\\b1}hello world!"
562 ov:update()
563
564 The advantage of using this wrapper (as opposed to running ``osd-overlay``
565 directly) is that the ``id`` field is allocated automatically.
566
567``mp.get_osd_size()``
568 Returns a tuple of ``osd_width, osd_height, osd_par``. The first two give
569 the size of the OSD in pixels (for video ouputs like ``--vo=xv``, this may
570 be "scaled" pixels). The third is the display pixel aspect ratio.
571
572 May return invalid/nonsense values if OSD is not initialized yet.
573
539mp.msg functions574mp.msg functions
540----------------575----------------
541 576
player/client.c+1−1
@@ -457,7 +457,7 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) · 456 unmodified lines
457 // causes a crash, block until all asynchronous requests were served.457 // causes a crash, block until all asynchronous requests were served.
458 mpv_wait_async_requests(ctx);458 mpv_wait_async_requests(ctx);
459 459
460 osd_set_external(mpctx->osd, ctx, 0, 0, NULL);460 osd_set_external_remove_owner(mpctx->osd, ctx);
461 mp_input_remove_sections_by_owner(mpctx->input, ctx->name);461 mp_input_remove_sections_by_owner(mpctx->input, ctx->name);
462 462
463 pthread_mutex_lock(&clients->lock);463 pthread_mutex_lock(&clients->lock);
player/command.c+32−0
@@ -4085,6 +4085,25 @@ static void overlay_uninit(struct MPContext *mpctx) · 4084 unmodified lines
4085 mp_image_unrefp(&cmd->overlay_osd[n].packed);4085 mp_image_unrefp(&cmd->overlay_osd[n].packed);
4086}4086}
4087 4087
4088static void cmd_osd_overlay(void *p)
4089{
4090 struct mp_cmd_ctx *cmd = p;
4091 struct MPContext *mpctx = cmd->mpctx;
4092
4093 struct osd_external_ass ov = {
4094 .owner = cmd->cmd->sender,
4095 .id = cmd->args[0].v.i64,
4096 .format = cmd->args[1].v.i,
4097 .data = cmd->args[2].v.s,
4098 .res_x = cmd->args[3].v.i,
4099 .res_y = cmd->args[4].v.i,
4100 .z = cmd->args[5].v.i,
4101 };
4102
4103 osd_set_external(mpctx->osd, &ov);
4104 mp_wakeup_core(mpctx);
4105}
4106
4088static struct track *find_track_with_url(struct MPContext *mpctx, int type,4107static struct track *find_track_with_url(struct MPContext *mpctx, int type,
4089 const char *url)4108 const char *url)
4090{4109{
@@ -5877,6 +5896,19 @@ const struct mp_cmd_def mp_cmds[] = { · 1786 unmodified lines
5877 OPT_INT("stride", v.i, 0), }},5896 OPT_INT("stride", v.i, 0), }},
5878 { "overlay-remove", cmd_overlay_remove, { OPT_INT("id", v.i, 0) } },5897 { "overlay-remove", cmd_overlay_remove, { OPT_INT("id", v.i, 0) } },
5879 5898
5899 { "osd-overlay", cmd_osd_overlay,
5900 {
5901 OPT_INT64("id", v.i64, 0),
5902 OPT_CHOICE("format", v.i, 0, ({"none", 0},
5903 {"ass-events", 1})),
5904 OPT_STRING("data", v.s, 0),
5905 OPT_INT("res_x", v.i, 0, OPTDEF_INT(0)),
5906 OPT_INT("res_y", v.i, 0, OPTDEF_INT(720)),
5907 OPT_INT("z", v.i, 0, OPTDEF_INT(0)),
5908 },
5909 .is_noisy = true,
5910 },
5911
5880 { "write-watch-later-config", cmd_write_watch_later_config },5912 { "write-watch-later-config", cmd_write_watch_later_config },
5881 5913
5882 { "hook-add", cmd_hook_add, { OPT_STRING("arg0", v.s, 0),5914 { "hook-add", cmd_hook_add, { OPT_STRING("arg0", v.s, 0),
player/javascript.c+1−1
@@ -738,7 +738,7 @@ static void script_set_osd_ass(js_State *J) · 737 unmodified lines
738 int res_x = jsL_checkint(J, 1);738 int res_x = jsL_checkint(J, 1);
739 int res_y = jsL_checkint(J, 2);739 int res_y = jsL_checkint(J, 2);
740 const char *text = js_tostring(J, 3);740 const char *text = js_tostring(J, 3);
741 osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);741 //osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);
742 mp_wakeup_core(ctx->mpctx);742 mp_wakeup_core(ctx->mpctx);
743 push_success(J);743 push_success(J);
744}744}
player/lua.c+0−27
@@ -998,31 +998,6 @@ static int script_raw_abort_async_command(lua_State *L) · 997 unmodified lines
998 return 0;998 return 0;
999}999}
1000 1000
1001static int script_set_osd_ass(lua_State *L)
1002{
1003 struct script_ctx *ctx = get_ctx(L);
1004 int res_x = luaL_checkinteger(L, 1);
1005 int res_y = luaL_checkinteger(L, 2);
1006 const char *text = luaL_checkstring(L, 3);
1007 if (!text[0])
1008 text = " "; // force external OSD initialization
1009 osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);
1010 mp_wakeup_core(ctx->mpctx);
1011 return 0;
1012}
1013
1014static int script_get_osd_size(lua_State *L)
1015{
1016 struct MPContext *mpctx = get_mpctx(L);
1017 struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd);
1018 double aspect = 1.0 * vo_res.w / MPMAX(vo_res.h, 1) /
1019 (vo_res.display_par ? vo_res.display_par : 1);
1020 lua_pushnumber(L, vo_res.w);
1021 lua_pushnumber(L, vo_res.h);
1022 lua_pushnumber(L, aspect);
1023 return 3;
1024}
1025
1026static int script_get_osd_margins(lua_State *L)1001static int script_get_osd_margins(lua_State *L)
1027{1002{
1028 struct MPContext *mpctx = get_mpctx(L);1003 struct MPContext *mpctx = get_mpctx(L);
@@ -1275,8 +1250,6 @@ static const struct fn_entry main_fns[] = { · 246 unmodified lines
1275 FN_ENTRY(set_property_native),1250 FN_ENTRY(set_property_native),
1276 FN_ENTRY(raw_observe_property),1251 FN_ENTRY(raw_observe_property),
1277 FN_ENTRY(raw_unobserve_property),1252 FN_ENTRY(raw_unobserve_property),
1278 FN_ENTRY(set_osd_ass),
1279 FN_ENTRY(get_osd_size),
1280 FN_ENTRY(get_osd_margins),1253 FN_ENTRY(get_osd_margins),
1281 FN_ENTRY(get_mouse_pos),1254 FN_ENTRY(get_mouse_pos),
1282 FN_ENTRY(get_time),1255 FN_ENTRY(get_time),
player/lua/defaults.lua+59−0
@@ -589,6 +589,65 @@ function mp.abort_async_command(t) · 588 unmodified lines
589 end589 end
590end590end
591 591
592local overlay_mt = {}
593overlay_mt.__index = overlay_mt
594local overlay_new_id = 0
595
596function mp.create_osd_overlay(format)
597 overlay_new_id = overlay_new_id + 1
598 local overlay = {
599 format = format,
600 id = overlay_new_id,
601 data = "",
602 res_x = 0,
603 res_y = 720,
604 }
605 setmetatable(overlay, overlay_mt)
606 return overlay
607end
608
609function overlay_mt.update(ov)
610 local cmd = {}
611 for k, v in pairs(ov) do
612 cmd[k] = v
613 end
614 cmd.name = "osd-overlay"
615 mp.command_native(cmd)
616end
617
618function overlay_mt.remove(ov)
619 mp.command_native {
620 name = "osd-overlay",
621 id = ov.id,
622 format = "none",
623 data = "",
624 }
625end
626
627-- legacy API
628function mp.set_osd_ass(res_x, res_y, data)
629 if not mp._legacy_overlay then
630 mp._legacy_overlay = mp.create_osd_overlay("ass-events")
631 end
632 mp._legacy_overlay.res_x = res_x
633 mp._legacy_overlay.res_y = res_y
634 mp._legacy_overlay.data = data
635 mp._legacy_overlay:update()
636end
637
638function mp.get_osd_size()
639 local w = mp.get_property_number("osd-width", 0)
640 local h = mp.get_property_number("osd-height", 0)
641 local par = mp.get_property_number("osd-par", 0)
642 if par == 0 then
643 par = 1
644 end
645
646 local aspect = 1.0 * w / math.max(h) / par
647 return w, h, aspect
648end
649
650
592local mp_utils = package.loaded["mp.utils"]651local mp_utils = package.loaded["mp.utils"]
593 652
594function mp_utils.format_table(t, set)653function mp_utils.format_table(t, set)
sub/osd.h+11−2
@@ -202,9 +202,18 @@ struct mp_osd_res osd_get_vo_res(struct osd_state *osd); · 201 unmodified lines
202void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,202void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,
203 struct mp_osd_res res, double compensate_par);203 struct mp_osd_res res, double compensate_par);
204 204
205struct osd_external_ass {
206 void *owner; // unique pointer (NULL is also allowed)
207 int64_t id;
208 int format;
209 char *data;
210 int res_x, res_y;
211 int z;
212};
213
205// defined in osd_libass.c and osd_dummy.c214// defined in osd_libass.c and osd_dummy.c
206void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,215void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov);
207 char *text);216void osd_set_external_remove_owner(struct osd_state *osd, void *owner);
208void osd_get_text_size(struct osd_state *osd, int *out_screen_h, int *out_font_h);217void osd_get_text_size(struct osd_state *osd, int *out_screen_h, int *out_font_h);
209void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);218void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);
210 219
sub/osd_dummy.c+5−2
@@ -24,8 +24,11 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, · 23 unmodified lines
24 *out_imgs = (struct sub_bitmaps) {0};24 *out_imgs = (struct sub_bitmaps) {0};
25}25}
26 26
27void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,27void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov)
28 char *text)28{
29}
30
31void osd_set_external_remove_owner(struct osd_state *osd, void *owner)
29{32{
30}33}
31 34
sub/osd_libass.c+66−31
@@ -80,8 +80,8 @@ static void destroy_ass_renderer(struct ass_state *ass) · 79 unmodified lines
80 80
81static void destroy_external(struct osd_external *ext)81static void destroy_external(struct osd_external *ext)
82{82{
83 talloc_free(ext->text);
84 destroy_ass_renderer(&ext->ass);83 destroy_ass_renderer(&ext->ass);
84 talloc_free(ext);
85}85}
86 86
87void osd_destroy_backend(struct osd_state *osd)87void osd_destroy_backend(struct osd_state *osd)
@@ -90,7 +90,7 @@ void osd_destroy_backend(struct osd_state *osd) · 2 unmodified lines
90 struct osd_object *obj = osd->objs[n];90 struct osd_object *obj = osd->objs[n];
91 destroy_ass_renderer(&obj->ass);91 destroy_ass_renderer(&obj->ass);
92 for (int i = 0; i < obj->num_externals; i++)92 for (int i = 0; i < obj->num_externals; i++)
93 destroy_external(&obj->externals[i]);93 destroy_external(obj->externals[i]);
94 obj->num_externals = 0;94 obj->num_externals = 0;
95 }95 }
96}96}
@@ -470,11 +470,9 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj) · 373 unmodified lines
470static void update_external(struct osd_state *osd, struct osd_object *obj,470static void update_external(struct osd_state *osd, struct osd_object *obj,
471 struct osd_external *ext)471 struct osd_external *ext)
472{472{
473 bstr t = bstr0(ext->text);473 bstr t = bstr0(ext->ov.data);
474 if (!t.len)474 ext->ass.res_x = ext->ov.res_x;
475 return;475 ext->ass.res_y = ext->ov.res_y;
476 ext->ass.res_x = ext->res_x;
477 ext->ass.res_y = ext->res_y;
478 create_ass_track(osd, obj, &ext->ass);476 create_ass_track(osd, obj, &ext->ass);
479 477
480 clear_ass(&ext->ass);478 clear_ass(&ext->ass);
@@ -497,29 +495,42 @@ static void update_external(struct osd_state *osd, struct osd_object *obj, · 16 unmodified lines
497 }495 }
498}496}
499 497
500void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y,498static int cmp_zorder(const void *pa, const void *pb)
501 char *text)499{
500 const struct osd_external *a = *(struct osd_external **)pa;
501 const struct osd_external *b = *(struct osd_external **)pb;
502 return a->ov.z == b->ov.z ? 0 : (a->ov.z > b->ov.z ? 1 : -1);
503}
504
505void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov)
502{506{
503 pthread_mutex_lock(&osd->lock);507 pthread_mutex_lock(&osd->lock);
504 struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];508 struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
505 struct osd_external *entry = 0;509 bool zorder_changed = false;
510 int index = -1;
511
506 for (int n = 0; n < obj->num_externals; n++) {512 for (int n = 0; n < obj->num_externals; n++) {
507 if (obj->externals[n].id == id) {513 struct osd_external *e = obj->externals[n];
508 entry = &obj->externals[n];514 if (e->ov.id == ov->id && e->ov.owner == ov->owner) {
515 index = n;
509 break;516 break;
510 }517 }
511 }518 }
512 if (!entry && !text)
513 goto done;
514 519
515 if (!entry) {520 if (index < 0) {
516 struct osd_external new = { .id = id };521 if (!ov->format)
522 goto done;
523 struct osd_external *new = talloc_zero(NULL, struct osd_external);
524 new->ov.owner = ov->owner;
525 new->ov.id = ov->id;
517 MP_TARRAY_APPEND(obj, obj->externals, obj->num_externals, new);526 MP_TARRAY_APPEND(obj, obj->externals, obj->num_externals, new);
518 entry = &obj->externals[obj->num_externals - 1];527 index = obj->num_externals - 1;
528 zorder_changed = true;
519 }529 }
520 530
521 if (!text) {531 struct osd_external *entry = obj->externals[index];
522 int index = entry - &obj->externals[0];532
533 if (!ov->format) {
523 destroy_external(entry);534 destroy_external(entry);
524 MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, index);535 MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, index);
525 obj->changed = true;536 obj->changed = true;
@@ -527,22 +538,46 @@ void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y, · 1 unmodified line
527 goto done;538 goto done;
528 }539 }
529 540
530 if (!entry->text || strcmp(entry->text, text) != 0 ||541 entry->ov.format = ov->format;
531 entry->res_x != res_x || entry->res_y != res_y)542 if (!entry->ov.data)
532 {543 entry->ov.data = talloc_strdup(entry, "");
533 talloc_free(entry->text);544 entry->ov.data[0] = '\0'; // reuse memory allocation
534 entry->text = talloc_strdup(NULL, text);545 entry->ov.data = talloc_strdup_append(entry->ov.data, ov->data);
535 entry->res_x = res_x;546 entry->ov.res_x = ov->res_x;
536 entry->res_y = res_y;547 entry->ov.res_y = ov->res_y;
537 update_external(osd, obj, entry);548 zorder_changed |= entry->ov.z != ov->z;
538 obj->changed = true;549 entry->ov.z = ov->z;
539 osd->want_redraw_notification = true;550
551 update_external(osd, obj, entry);
552
553 obj->changed = true;
554 osd->want_redraw_notification = true;
555
556 if (zorder_changed) {
557 qsort(obj->externals, obj->num_externals, sizeof(obj->externals[0]),
558 cmp_zorder);
540 }559 }
541 560
542done:561done:
543 pthread_mutex_unlock(&osd->lock);562 pthread_mutex_unlock(&osd->lock);
544}563}
545 564
565void osd_set_external_remove_owner(struct osd_state *osd, void *owner)
566{
567 pthread_mutex_lock(&osd->lock);
568 struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
569 for (int n = obj->num_externals - 1; n >= 0; n--) {
570 struct osd_external *e = obj->externals[n];
571 if (e->ov.owner == owner) {
572 destroy_external(e);
573 MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, n);
574 obj->changed = true;
575 osd->want_redraw_notification = true;
576 }
577 }
578 pthread_mutex_unlock(&osd->lock);
579}
580
546static void append_ass(struct ass_state *ass, struct mp_osd_res *res,581static void append_ass(struct ass_state *ass, struct mp_osd_res *res,
547 ASS_Image **img_list, bool *changed)582 ASS_Image **img_list, bool *changed)
548{583{
@@ -574,8 +609,8 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, · 25 unmodified lines
574 609
575 append_ass(&obj->ass, &obj->vo_res, &obj->ass_imgs[0], &obj->changed);610 append_ass(&obj->ass, &obj->vo_res, &obj->ass_imgs[0], &obj->changed);
576 for (int n = 0; n < obj->num_externals; n++) {611 for (int n = 0; n < obj->num_externals; n++) {
577 append_ass(&obj->externals[n].ass, &obj->vo_res, &obj->ass_imgs[n + 1],612 append_ass(&obj->externals[n]->ass, &obj->vo_res,
578 &obj->changed);613 &obj->ass_imgs[n + 1], &obj->changed);
579 }614 }
580 615
581 mp_ass_packer_pack(obj->ass_packer, obj->ass_imgs, obj->num_externals + 1,616 mp_ass_packer_pack(obj->ass_packer, obj->ass_imgs, obj->num_externals + 1,
sub/osd_state.h+2−4
@@ -38,7 +38,7 @@ struct osd_object { · 37 unmodified lines
38 struct dec_sub *sub;38 struct dec_sub *sub;
39 39
40 // OSDTYPE_EXTERNAL40 // OSDTYPE_EXTERNAL
41 struct osd_external *externals;41 struct osd_external **externals;
42 int num_externals;42 int num_externals;
43 43
44 // OSDTYPE_EXTERNAL244 // OSDTYPE_EXTERNAL2
@@ -56,9 +56,7 @@ struct osd_object { · 11 unmodified lines
56};56};
57 57
58struct osd_external {58struct osd_external {
59 void *id;59 struct osd_external_ass ov;
60 char *text;
61 int res_x, res_y;
62 struct ass_state ass;60 struct ass_state ass;
63};61};
64 62

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t