2009-02-08 03:27:30 +00:00
|
|
|
/*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2009-02-08 03:27:30 +00:00
|
|
|
*
|
sub/osd: relicense to LGPL
All contributors of the code used for these files agreed to the LGPL
relicensing.
There are some unaccounted contributors, but all of their code was
completely removed before. (The only exception is one contributor whose
only line left was "#include <string.h>". I don't know if that's
copyrightable, but it wasn't needed anyway, so just remove it.)
These files started out as libvo/sub.* (renamed to sub/sub.*, then
renamed again to sub/osd.*). They used to contain code for rendering
the OSD (as in, actual pixel manipulation and text layouting). But
later all this code was dropped, and libass was used to render the OSD
instead. Actual subtitle rendering was reimplemented in other files
(the old subtitle rendering path is completely gone).
One potential problem are the option declarations, which makes this
harder, as these options involve more history. But it turns out most of
them were reimplemented since 80270218cb9, rather than taken from old
code. (Although not all - but the rest covered by relicensing
agreements.)
This also affects osd_state.h, which was apparently incorrectly implied
to be LGPL.
2017-04-20 10:39:00 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2009-02-08 03:27:30 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2009-02-08 03:27:30 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
sub/osd: relicense to LGPL
All contributors of the code used for these files agreed to the LGPL
relicensing.
There are some unaccounted contributors, but all of their code was
completely removed before. (The only exception is one contributor whose
only line left was "#include <string.h>". I don't know if that's
copyrightable, but it wasn't needed anyway, so just remove it.)
These files started out as libvo/sub.* (renamed to sub/sub.*, then
renamed again to sub/osd.*). They used to contain code for rendering
the OSD (as in, actual pixel manipulation and text layouting). But
later all this code was dropped, and libass was used to render the OSD
instead. Actual subtitle rendering was reimplemented in other files
(the old subtitle rendering path is completely gone).
One potential problem are the option declarations, which makes this
harder, as these options involve more history. But it turns out most of
them were reimplemented since 80270218cb9, rather than taken from old
code. (Although not all - but the rest covered by relicensing
agreements.)
This also affects osd_state.h, which was apparently incorrectly implied
to be LGPL.
2017-04-20 10:39:00 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2009-02-08 03:27:30 +00:00
|
|
|
*
|
sub/osd: relicense to LGPL
All contributors of the code used for these files agreed to the LGPL
relicensing.
There are some unaccounted contributors, but all of their code was
completely removed before. (The only exception is one contributor whose
only line left was "#include <string.h>". I don't know if that's
copyrightable, but it wasn't needed anyway, so just remove it.)
These files started out as libvo/sub.* (renamed to sub/sub.*, then
renamed again to sub/osd.*). They used to contain code for rendering
the OSD (as in, actual pixel manipulation and text layouting). But
later all this code was dropped, and libass was used to render the OSD
instead. Actual subtitle rendering was reimplemented in other files
(the old subtitle rendering path is completely gone).
One potential problem are the option declarations, which makes this
harder, as these options involve more history. But it turns out most of
them were reimplemented since 80270218cb9, rather than taken from old
code. (Although not all - but the rest covered by relicensing
agreements.)
This also affects osd_state.h, which was apparently incorrectly implied
to be LGPL.
2017-04-20 10:39:00 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2009-02-08 03:27:30 +00:00
|
|
|
*/
|
2001-03-24 04:36:17 +00:00
|
|
|
|
2002-04-06 19:09:06 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2012-09-28 19:33:26 +00:00
|
|
|
#include <assert.h>
|
2002-04-06 19:09:06 +00:00
|
|
|
|
2012-07-30 19:13:03 +00:00
|
|
|
#include <libavutil/common.h>
|
|
|
|
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/common.h"
|
2002-11-06 23:54:29 +00:00
|
|
|
|
2006-11-25 13:03:51 +00:00
|
|
|
#include "stream/stream.h"
|
2006-11-25 11:20:02 +00:00
|
|
|
|
2007-09-10 11:10:50 +00:00
|
|
|
#include "osdep/timer.h"
|
2007-07-29 17:57:39 +00:00
|
|
|
|
2016-01-11 18:03:40 +00:00
|
|
|
#include "mpv_talloc.h"
|
2017-12-29 16:19:25 +00:00
|
|
|
#include "options/m_config.h"
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/options.h"
|
2013-12-21 18:06:37 +00:00
|
|
|
#include "common/global.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/msg.h"
|
stats: some more performance graphs
Add an infrastructure for collecting performance-related data, use it in
some places. Add rendering of them to stats.lua.
There were two main goals: minimal impact on the normal code and normal
playback. So all these stats_* function calls either happen only during
initialization, or return immediately if no stats collection is going
on. That's why it does this lazily adding of stats entries etc. (a first
iteration made each stats entry an API thing, instead of just a single
stats_ctx, but I thought that was getting too intrusive in the "normal"
code, even if everything gets worse inside of stats.c).
You could get most of this information from various profilers (including
the extremely primitive --dump-stats thing in mpv), but this makes it
easier to see the most important information at once (at least in
theory), partially because we know best about the context of various
things.
Not very happy with this. It's all pretty primitive and dumb. At this
point I just wanted to get over with it, without necessarily having to
revisit it later, but with having my stupid statistics.
Somehow the code feels terrible. There are a lot of meh decisions in
there that could be better or worse (but mostly could be better), and it
just sucks but it's also trivial and uninteresting and does the job. I
guess I hate programming. It's so tedious and the result is always shit.
Anyway, enjoy.
2020-04-08 22:27:54 +00:00
|
|
|
#include "common/stats.h"
|
2016-01-15 21:53:53 +00:00
|
|
|
#include "player/client.h"
|
|
|
|
#include "player/command.h"
|
2013-11-24 11:58:06 +00:00
|
|
|
#include "osd.h"
|
2014-01-18 00:19:20 +00:00
|
|
|
#include "osd_state.h"
|
2012-10-04 15:16:40 +00:00
|
|
|
#include "dec_sub.h"
|
2012-09-28 19:38:52 +00:00
|
|
|
#include "img_convert.h"
|
2012-10-07 01:26:46 +00:00
|
|
|
#include "draw_bmp.h"
|
sub: do not copy the target image if there is no OSD/subs
It's not easy to tell whether the OSD/subs are empty, or if something is
drawn. In general you have to use osd_draw() with a custom callback. If
nothing is visible, the callback is never invoked. (The actual reason
why this is so "hard" is the implementation of osd_libass.c, which
doesn't allow separating rendering and drawing of OSD elements, because
all OSD elements share the same ASS_Renderer.)
To simplify avoiding copies, make osd_draw_on_image() instead of the
caller use mp_image_make_writeable(). Introduce osd_draw_on_image_p(),
which works like osd_draw_on_image(), but gets the new image allocation
from an image pool. This is supposed to be an optimization, because it
reduces the frequency of large allocations/deallocations for image data.
The result of this is that the frequency of copies needed in conjunction
with vf_sub, screenshots, and vo_lavc (encoding) should be reduced.
vf_sub now always does true pass-through if no subs are shown.
Drop the pts check from vf_sub. This didn't make much sense.
2012-12-22 16:17:43 +00:00
|
|
|
#include "video/mp_image.h"
|
|
|
|
#include "video/mp_image_pool.h"
|
2001-03-27 00:32:24 +00:00
|
|
|
|
2015-02-16 19:03:56 +00:00
|
|
|
#define OPT_BASE_STRUCT struct osd_style_opts
|
|
|
|
static const m_option_t style_opts[] = {
|
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-14 20:28:01 +00:00
|
|
|
{"font", OPT_STRING(font)},
|
|
|
|
{"font-size", OPT_FLOAT(font_size), M_RANGE(1, 9000)},
|
|
|
|
{"color", OPT_COLOR(color)},
|
2024-05-21 03:15:23 +00:00
|
|
|
{"outline-color", OPT_COLOR(outline_color)},
|
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-14 20:28:01 +00:00
|
|
|
{"back-color", OPT_COLOR(back_color)},
|
2024-05-21 03:15:23 +00:00
|
|
|
{"outline-size", OPT_FLOAT(outline_size)},
|
|
|
|
{"border-color", OPT_ALIAS("outline-color"), .alias_use_prefix = true},
|
|
|
|
{"shadow-color", OPT_ALIAS("back-color"), .alias_use_prefix = true},
|
|
|
|
{"border-style", OPT_CHOICE(border_style,
|
|
|
|
{"outline-and-shadow", 1}, {"opaque-box", 3}, {"background-box", 4})},
|
|
|
|
{"border-size", OPT_ALIAS("outline-size"), .alias_use_prefix = true},
|
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-14 20:28:01 +00:00
|
|
|
{"shadow-offset", OPT_FLOAT(shadow_offset)},
|
|
|
|
{"spacing", OPT_FLOAT(spacing), M_RANGE(-10, 10)},
|
|
|
|
{"margin-x", OPT_INT(margin_x), M_RANGE(0, 300)},
|
|
|
|
{"margin-y", OPT_INT(margin_y), M_RANGE(0, 600)},
|
|
|
|
{"align-x", OPT_CHOICE(align_x,
|
|
|
|
{"left", -1}, {"center", 0}, {"right", +1})},
|
|
|
|
{"align-y", OPT_CHOICE(align_y,
|
|
|
|
{"top", -1}, {"center", 0}, {"bottom", +1})},
|
|
|
|
{"blur", OPT_FLOAT(blur), M_RANGE(0, 20)},
|
2023-02-20 03:32:50 +00:00
|
|
|
{"bold", OPT_BOOL(bold)},
|
|
|
|
{"italic", OPT_BOOL(italic)},
|
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-14 20:28:01 +00:00
|
|
|
{"justify", OPT_CHOICE(justify,
|
|
|
|
{"auto", 0}, {"left", 1}, {"center", 2}, {"right", 3})},
|
|
|
|
{"font-provider", OPT_CHOICE(font_provider,
|
2020-08-12 15:28:08 +00:00
|
|
|
{"auto", 0}, {"none", 1}, {"fontconfig", 2}), .flags = UPDATE_SUB_HARD},
|
2022-02-11 02:36:34 +00:00
|
|
|
{"fonts-dir", OPT_STRING(fonts_dir),
|
|
|
|
.flags = M_OPT_FILE | UPDATE_SUB_HARD},
|
2015-02-16 19:03:56 +00:00
|
|
|
{0}
|
2012-11-17 19:56:45 +00:00
|
|
|
};
|
2002-01-10 17:21:00 +00:00
|
|
|
|
2012-11-17 19:56:45 +00:00
|
|
|
const struct m_sub_options osd_style_conf = {
|
2015-02-16 19:03:56 +00:00
|
|
|
.opts = style_opts,
|
|
|
|
.size = sizeof(struct osd_style_opts),
|
|
|
|
.defaults = &(const struct osd_style_opts){
|
|
|
|
.font = "sans-serif",
|
|
|
|
.font_size = 55,
|
|
|
|
.color = {255, 255, 255, 255},
|
2024-05-21 03:15:23 +00:00
|
|
|
.outline_color = {0, 0, 0, 255},
|
|
|
|
.back_color = {240, 240, 240, 128},
|
|
|
|
.border_style = 1,
|
|
|
|
.outline_size = 3,
|
2015-02-16 19:03:56 +00:00
|
|
|
.shadow_offset = 0,
|
|
|
|
.margin_x = 25,
|
|
|
|
.margin_y = 22,
|
2015-02-16 19:04:02 +00:00
|
|
|
.align_x = -1,
|
|
|
|
.align_y = -1,
|
2012-11-17 19:56:45 +00:00
|
|
|
},
|
2016-09-19 18:16:44 +00:00
|
|
|
.change_flags = UPDATE_OSD,
|
2015-02-16 19:03:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct m_sub_options sub_style_conf = {
|
|
|
|
.opts = style_opts,
|
2012-11-17 19:56:45 +00:00
|
|
|
.size = sizeof(struct osd_style_opts),
|
2015-02-16 19:03:56 +00:00
|
|
|
.defaults = &(const struct osd_style_opts){
|
|
|
|
.font = "sans-serif",
|
|
|
|
.font_size = 55,
|
|
|
|
.color = {255, 255, 255, 255},
|
2024-05-21 03:15:23 +00:00
|
|
|
.outline_color = {0, 0, 0, 255},
|
|
|
|
.back_color = {240, 240, 240, 128},
|
|
|
|
.border_style = 1,
|
|
|
|
.outline_size = 3,
|
2015-02-16 19:03:56 +00:00
|
|
|
.shadow_offset = 0,
|
|
|
|
.margin_x = 25,
|
|
|
|
.margin_y = 22,
|
2015-02-16 19:04:02 +00:00
|
|
|
.align_x = 0,
|
|
|
|
.align_y = 1,
|
2015-02-16 19:03:56 +00:00
|
|
|
},
|
2016-09-19 18:16:44 +00:00
|
|
|
.change_flags = UPDATE_OSD,
|
2012-11-17 19:56:45 +00:00
|
|
|
};
|
|
|
|
|
2017-08-29 13:15:34 +00:00
|
|
|
bool osd_res_equals(struct mp_osd_res a, struct mp_osd_res b)
|
2008-06-23 22:53:58 +00:00
|
|
|
{
|
VO, sub: refactor
Remove VFCTRL_DRAW_OSD, VFCAP_EOSD_FILTER, VFCAP_EOSD_RGBA, VFCAP_EOSD,
VOCTRL_DRAW_EOSD, VOCTRL_GET_EOSD_RES, VOCTRL_QUERY_EOSD_FORMAT.
Remove draw_osd_with_eosd(), which rendered the OSD by calling
VOCTRL_DRAW_EOSD. Change VOs to call osd_draw() directly, which takes
a callback as argument. (This basically works like the old OSD API,
except multiple OSD bitmap formats are supported and caching is
possible.)
Remove all mentions of "eosd". It's simply "osd" now.
Make OSD size per-OSD-object, as they can be different when using
vf_sub. Include display_par/video_par in resolution change detection.
Fix the issue with margin borders in vo_corevideo.
2012-10-19 17:25:18 +00:00
|
|
|
return a.w == b.w && a.h == b.h && a.ml == b.ml && a.mt == b.mt
|
|
|
|
&& a.mr == b.mr && a.mb == b.mb
|
2013-11-24 12:07:49 +00:00
|
|
|
&& a.display_par == b.display_par;
|
2009-01-10 13:47:41 +00:00
|
|
|
}
|
|
|
|
|
2013-12-21 18:06:37 +00:00
|
|
|
struct osd_state *osd_create(struct mpv_global *global)
|
2008-06-23 22:53:58 +00:00
|
|
|
{
|
2024-03-17 17:21:09 +00:00
|
|
|
static_assert(MAX_OSD_PARTS >= OSDTYPE_COUNT, "");
|
2016-03-08 20:54:17 +00:00
|
|
|
|
2008-06-24 05:29:36 +00:00
|
|
|
struct osd_state *osd = talloc_zero(NULL, struct osd_state);
|
2012-09-28 19:38:52 +00:00
|
|
|
*osd = (struct osd_state) {
|
2017-12-29 16:19:25 +00:00
|
|
|
.opts_cache = m_config_cache_alloc(osd, global, &mp_osd_render_sub_opts),
|
2013-12-21 18:06:37 +00:00
|
|
|
.global = global,
|
|
|
|
.log = mp_log_new(osd, global->log, "osd"),
|
2023-10-19 10:16:12 +00:00
|
|
|
.force_video_pts = MP_NOPTS_VALUE,
|
stats: some more performance graphs
Add an infrastructure for collecting performance-related data, use it in
some places. Add rendering of them to stats.lua.
There were two main goals: minimal impact on the normal code and normal
playback. So all these stats_* function calls either happen only during
initialization, or return immediately if no stats collection is going
on. That's why it does this lazily adding of stats entries etc. (a first
iteration made each stats entry an API thing, instead of just a single
stats_ctx, but I thought that was getting too intrusive in the "normal"
code, even if everything gets worse inside of stats.c).
You could get most of this information from various profilers (including
the extremely primitive --dump-stats thing in mpv), but this makes it
easier to see the most important information at once (at least in
theory), partially because we know best about the context of various
things.
Not very happy with this. It's all pretty primitive and dumb. At this
point I just wanted to get over with it, without necessarily having to
revisit it later, but with having my stupid statistics.
Somehow the code feels terrible. There are a lot of meh decisions in
there that could be better or worse (but mostly could be better), and it
just sucks but it's also trivial and uninteresting and does the job. I
guess I hate programming. It's so tedious and the result is always shit.
Anyway, enjoy.
2020-04-08 22:27:54 +00:00
|
|
|
.stats = stats_ctx_create(osd, global, "osd"),
|
2008-06-23 22:53:58 +00:00
|
|
|
};
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_init(&osd->lock);
|
2017-12-29 16:19:25 +00:00
|
|
|
osd->opts = osd->opts_cache->opts;
|
2012-10-04 15:16:32 +00:00
|
|
|
|
2012-09-28 19:38:52 +00:00
|
|
|
for (int n = 0; n < MAX_OSD_PARTS; n++) {
|
2013-12-24 16:46:14 +00:00
|
|
|
struct osd_object *obj = talloc(osd, struct osd_object);
|
|
|
|
*obj = (struct osd_object) {
|
2012-09-28 19:38:52 +00:00
|
|
|
.type = n,
|
2014-01-18 00:19:20 +00:00
|
|
|
.text = talloc_strdup(obj, ""),
|
|
|
|
.progbar_state = {.type = -1},
|
2020-05-09 15:54:33 +00:00
|
|
|
.vo_change_id = 1,
|
2013-12-24 16:46:14 +00:00
|
|
|
};
|
2012-09-28 19:38:52 +00:00
|
|
|
osd->objs[n] = obj;
|
|
|
|
}
|
2012-10-04 15:16:32 +00:00
|
|
|
|
2013-12-24 16:46:14 +00:00
|
|
|
osd->objs[OSDTYPE_SUB]->is_sub = true;
|
|
|
|
osd->objs[OSDTYPE_SUB2]->is_sub = true;
|
2012-10-04 15:16:32 +00:00
|
|
|
|
osd: use libass for OSD rendering
The OSD will now be rendered with libass. The old rendering code, which
used freetype/fontconfig and did text layout manually, is disabled. To
re-enable the old code, use the --disable-libass-osd configure switch.
Some switches do nothing with the new code enabled, such as -subalign,
-sub-bg-alpha, -sub-bg-color, and many more. (The reason is mostly that
the code for rendering unstyled subtitles with libass doesn't make any
attempts to support them. Some of them could be supported in theory.)
Teletext rendering is not implemented in the new OSD rendering code. I
don't have any teletext sources for testing, and since teletext is
being phased out world-wide, the need for this is questionable.
Note that rendering is extremely inefficient, mostly because the libass
output is blended with the extremely strange mplayer OSD format. This
could be improved at a later point.
Remove most OSD rendering from vo_aa.c, because that was extremely
hacky, can't be made work with osd_libass, and didn't work anyway in
my tests.
Internally, some cleanup is done. Subtitle and OSD related variable
declarations were literally all over the place. Move them to sub.h and
sub.c, which were hoarding most of these declarations already. Make the
player core in mplayer.c free of concerns like bitmap font loading.
The old OSD rendering code has been moved to osd_ft.c. The font_load.c
and font_load_ft.c are only needed and compiled if the old OSD
rendering code is configured.
2012-03-22 05:26:37 +00:00
|
|
|
osd_init_backend(osd);
|
2008-06-23 22:53:58 +00:00
|
|
|
return osd;
|
2002-04-15 19:17:12 +00:00
|
|
|
}
|
2001-06-02 16:02:38 +00:00
|
|
|
|
2012-09-28 19:38:52 +00:00
|
|
|
void osd_free(struct osd_state *osd)
|
|
|
|
{
|
|
|
|
if (!osd)
|
|
|
|
return;
|
|
|
|
osd_destroy_backend(osd);
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
talloc_free(osd->objs[OSDTYPE_EXTERNAL2]->external2);
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_destroy(&osd->lock);
|
2012-09-28 19:38:52 +00:00
|
|
|
talloc_free(osd);
|
|
|
|
}
|
|
|
|
|
2016-03-08 20:54:17 +00:00
|
|
|
void osd_set_text(struct osd_state *osd, const char *text)
|
2014-01-18 00:19:20 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-03-08 20:54:17 +00:00
|
|
|
struct osd_object *osd_obj = osd->objs[OSDTYPE_OSD];
|
2011-08-08 08:07:17 +00:00
|
|
|
if (!text)
|
|
|
|
text = "";
|
2014-01-18 00:19:20 +00:00
|
|
|
if (strcmp(osd_obj->text, text) != 0) {
|
|
|
|
talloc_free(osd_obj->text);
|
|
|
|
osd_obj->text = talloc_strdup(osd_obj, text);
|
2016-09-16 15:17:32 +00:00
|
|
|
osd_obj->osd_changed = true;
|
|
|
|
osd->want_redraw_notification = true;
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
|
|
|
|
2016-03-08 20:54:17 +00:00
|
|
|
void osd_set_sub(struct osd_state *osd, int index, struct dec_sub *dec_sub)
|
2014-01-18 00:19:20 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-09-16 12:21:09 +00:00
|
|
|
if (index >= 0 && index < 2) {
|
|
|
|
struct osd_object *obj = osd->objs[OSDTYPE_SUB + index];
|
|
|
|
obj->sub = dec_sub;
|
|
|
|
obj->vo_change_id += 1;
|
|
|
|
}
|
2016-09-16 15:17:32 +00:00
|
|
|
osd->want_redraw_notification = true;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool osd_get_render_subs_in_filter(struct osd_state *osd)
|
2013-04-28 19:12:11 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
bool r = osd->render_subs_in_filter;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void osd_set_render_subs_in_filter(struct osd_state *osd, bool s)
|
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2020-05-13 18:07:59 +00:00
|
|
|
if (osd->render_subs_in_filter != s) {
|
|
|
|
osd->render_subs_in_filter = s;
|
|
|
|
|
|
|
|
int change_id = 0;
|
|
|
|
for (int n = 0; n < MAX_OSD_PARTS; n++)
|
|
|
|
change_id = MPMAX(change_id, osd->objs[n]->vo_change_id);
|
|
|
|
for (int n = 0; n < MAX_OSD_PARTS; n++)
|
|
|
|
osd->objs[n]->vo_change_id = change_id + 1;
|
|
|
|
}
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
|
|
|
|
2016-10-26 18:43:03 +00:00
|
|
|
void osd_set_force_video_pts(struct osd_state *osd, double video_pts)
|
|
|
|
{
|
2021-11-25 07:10:47 +00:00
|
|
|
atomic_store(&osd->force_video_pts, video_pts);
|
2016-10-26 18:43:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double osd_get_force_video_pts(struct osd_state *osd)
|
|
|
|
{
|
2021-11-25 07:10:47 +00:00
|
|
|
return atomic_load(&osd->force_video_pts);
|
2016-10-26 18:43:03 +00:00
|
|
|
}
|
|
|
|
|
2014-01-18 00:19:20 +00:00
|
|
|
void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s)
|
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2015-11-28 18:24:31 +00:00
|
|
|
struct osd_object *osd_obj = osd->objs[OSDTYPE_OSD];
|
2014-01-18 00:19:20 +00:00
|
|
|
osd_obj->progbar_state.type = s->type;
|
|
|
|
osd_obj->progbar_state.value = s->value;
|
|
|
|
osd_obj->progbar_state.num_stops = s->num_stops;
|
|
|
|
MP_TARRAY_GROW(osd_obj, osd_obj->progbar_state.stops, s->num_stops);
|
2018-10-14 13:51:36 +00:00
|
|
|
if (s->num_stops) {
|
|
|
|
memcpy(osd_obj->progbar_state.stops, s->stops,
|
|
|
|
sizeof(osd_obj->progbar_state.stops[0]) * s->num_stops);
|
|
|
|
}
|
2016-09-16 15:17:32 +00:00
|
|
|
osd_obj->osd_changed = true;
|
|
|
|
osd->want_redraw_notification = true;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs)
|
2013-04-28 19:12:11 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL2];
|
|
|
|
talloc_free(obj->external2);
|
|
|
|
obj->external2 = sub_bitmaps_copy(NULL, imgs);
|
|
|
|
obj->vo_change_id += 1;
|
2016-09-16 15:17:32 +00:00
|
|
|
osd->want_redraw_notification = true;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
}
|
|
|
|
|
2016-03-21 21:23:41 +00:00
|
|
|
static void check_obj_resize(struct osd_state *osd, struct mp_osd_res res,
|
|
|
|
struct osd_object *obj)
|
|
|
|
{
|
|
|
|
if (!osd_res_equals(res, obj->vo_res)) {
|
|
|
|
obj->vo_res = res;
|
2023-08-25 03:46:05 +00:00
|
|
|
obj->osd_changed = true;
|
2020-01-08 01:31:18 +00:00
|
|
|
mp_client_broadcast_event_external(osd->global->client_api,
|
|
|
|
MP_EVENT_WIN_RESIZE, NULL);
|
2016-03-21 21:23:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Optional. Can be called for faster reaction of OSD-generating scripts like
|
|
|
|
// osc.lua. This can achieve that the resize happens first, so that the OSD is
|
|
|
|
// generated at the correct resolution the first time the resized frame is
|
|
|
|
// rendered. Since the OSD doesn't (and can't) wait for the script, this
|
|
|
|
// increases the time in which the script can react, and also gets rid of the
|
|
|
|
// unavoidable redraw delay (though it will still be racy).
|
|
|
|
// Unnecessary for anything else.
|
|
|
|
void osd_resize(struct osd_state *osd, struct mp_osd_res res)
|
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-03-21 21:23:41 +00:00
|
|
|
int types[] = {OSDTYPE_OSD, OSDTYPE_EXTERNAL, OSDTYPE_EXTERNAL2, -1};
|
|
|
|
for (int n = 0; types[n] >= 0; n++)
|
|
|
|
check_obj_resize(osd, res, osd->objs[types[n]]);
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2016-03-21 21:23:41 +00:00
|
|
|
}
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
static struct sub_bitmaps *render_object(struct osd_state *osd,
|
|
|
|
struct osd_object *obj,
|
|
|
|
struct mp_osd_res osdres, double video_pts,
|
|
|
|
const bool sub_formats[SUBBITMAP_COUNT])
|
2012-09-28 19:38:52 +00:00
|
|
|
{
|
2016-07-03 16:33:28 +00:00
|
|
|
int format = SUBBITMAP_LIBASS;
|
2017-12-29 16:19:25 +00:00
|
|
|
if (!sub_formats[format] || osd->opts->force_rgba_osd)
|
2022-01-11 20:03:27 +00:00
|
|
|
format = SUBBITMAP_BGRA;
|
2016-07-03 16:33:28 +00:00
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmaps *res = NULL;
|
2012-09-28 19:38:52 +00:00
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
check_obj_resize(osd, osdres, obj);
|
VO, sub: refactor
Remove VFCTRL_DRAW_OSD, VFCAP_EOSD_FILTER, VFCAP_EOSD_RGBA, VFCAP_EOSD,
VOCTRL_DRAW_EOSD, VOCTRL_GET_EOSD_RES, VOCTRL_QUERY_EOSD_FORMAT.
Remove draw_osd_with_eosd(), which rendered the OSD by calling
VOCTRL_DRAW_EOSD. Change VOs to call osd_draw() directly, which takes
a callback as argument. (This basically works like the old OSD API,
except multiple OSD bitmap formats are supported and caching is
possible.)
Remove all mentions of "eosd". It's simply "osd" now.
Make OSD size per-OSD-object, as they can be different when using
vf_sub. Include display_par/video_par in resolution change detection.
Fix the issue with margin borders in vo_corevideo.
2012-10-19 17:25:18 +00:00
|
|
|
|
2021-01-13 15:59:08 +00:00
|
|
|
if (obj->type == OSDTYPE_SUB) {
|
2022-01-19 17:23:52 +00:00
|
|
|
if (obj->sub && sub_is_primary_visible(obj->sub))
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
res = sub_get_bitmaps(obj->sub, obj->vo_res, format, video_pts);
|
2021-01-13 15:59:08 +00:00
|
|
|
} else if (obj->type == OSDTYPE_SUB2) {
|
|
|
|
if (obj->sub && sub_is_secondary_visible(obj->sub))
|
|
|
|
res = sub_get_bitmaps(obj->sub, obj->vo_res, format, video_pts);
|
2013-09-30 20:27:37 +00:00
|
|
|
} else if (obj->type == OSDTYPE_EXTERNAL2) {
|
2014-01-18 00:19:20 +00:00
|
|
|
if (obj->external2 && obj->external2->format) {
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
res = sub_bitmaps_copy(NULL, obj->external2); // need to be owner
|
2015-03-18 11:33:14 +00:00
|
|
|
obj->external2->change_id = 0;
|
2013-09-30 20:27:37 +00:00
|
|
|
}
|
2012-09-28 19:38:52 +00:00
|
|
|
} else {
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
res = osd_object_get_bitmaps(osd, obj, format);
|
2012-09-28 19:38:52 +00:00
|
|
|
}
|
|
|
|
|
2020-05-09 15:54:33 +00:00
|
|
|
if (obj->vo_had_output != !!res) {
|
|
|
|
obj->vo_had_output = !!res;
|
|
|
|
obj->vo_change_id += 1;
|
|
|
|
}
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
if (res) {
|
|
|
|
obj->vo_change_id += res->change_id;
|
2012-09-28 19:38:52 +00:00
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
res->render_index = obj->type;
|
|
|
|
res->change_id = obj->vo_change_id;
|
|
|
|
}
|
2012-09-28 19:38:52 +00:00
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
return res;
|
2012-10-04 15:16:32 +00:00
|
|
|
}
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
// Render OSD to a list of bitmap and return it. The returned object is
|
|
|
|
// refcounted. Typically you should hold it only for a short time, and then
|
|
|
|
// release it.
|
2012-10-19 17:11:08 +00:00
|
|
|
// draw_flags is a bit field of OSD_DRAW_* constants
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmap_list *osd_render(struct osd_state *osd, struct mp_osd_res res,
|
|
|
|
double video_pts, int draw_flags,
|
|
|
|
const bool formats[SUBBITMAP_COUNT])
|
2012-10-04 15:16:32 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmap_list *list = talloc_zero(NULL, struct sub_bitmap_list);
|
2020-05-09 15:54:33 +00:00
|
|
|
list->change_id = 1;
|
|
|
|
list->w = res.w;
|
|
|
|
list->h = res.h;
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
|
2021-11-25 07:10:47 +00:00
|
|
|
double force_video_pts = atomic_load(&osd->force_video_pts);
|
|
|
|
if (force_video_pts != MP_NOPTS_VALUE)
|
|
|
|
video_pts = force_video_pts;
|
2016-10-26 18:43:03 +00:00
|
|
|
|
2012-10-19 17:11:08 +00:00
|
|
|
if (draw_flags & OSD_DRAW_SUB_FILTER)
|
|
|
|
draw_flags |= OSD_DRAW_SUB_ONLY;
|
|
|
|
|
2012-10-04 15:16:32 +00:00
|
|
|
for (int n = 0; n < MAX_OSD_PARTS; n++) {
|
|
|
|
struct osd_object *obj = osd->objs[n];
|
2012-10-19 17:11:08 +00:00
|
|
|
|
|
|
|
// Object is drawn into the video frame itself; don't draw twice
|
|
|
|
if (osd->render_subs_in_filter && obj->is_sub &&
|
|
|
|
!(draw_flags & OSD_DRAW_SUB_FILTER))
|
|
|
|
continue;
|
|
|
|
if ((draw_flags & OSD_DRAW_SUB_ONLY) && !obj->is_sub)
|
|
|
|
continue;
|
2015-03-23 01:42:19 +00:00
|
|
|
if ((draw_flags & OSD_DRAW_OSD_ONLY) && obj->is_sub)
|
|
|
|
continue;
|
2012-10-19 17:11:08 +00:00
|
|
|
|
stats: some more performance graphs
Add an infrastructure for collecting performance-related data, use it in
some places. Add rendering of them to stats.lua.
There were two main goals: minimal impact on the normal code and normal
playback. So all these stats_* function calls either happen only during
initialization, or return immediately if no stats collection is going
on. That's why it does this lazily adding of stats entries etc. (a first
iteration made each stats entry an API thing, instead of just a single
stats_ctx, but I thought that was getting too intrusive in the "normal"
code, even if everything gets worse inside of stats.c).
You could get most of this information from various profilers (including
the extremely primitive --dump-stats thing in mpv), but this makes it
easier to see the most important information at once (at least in
theory), partially because we know best about the context of various
things.
Not very happy with this. It's all pretty primitive and dumb. At this
point I just wanted to get over with it, without necessarily having to
revisit it later, but with having my stupid statistics.
Somehow the code feels terrible. There are a lot of meh decisions in
there that could be better or worse (but mostly could be better), and it
just sucks but it's also trivial and uninteresting and does the job. I
guess I hate programming. It's so tedious and the result is always shit.
Anyway, enjoy.
2020-04-08 22:27:54 +00:00
|
|
|
char *stat_type_render = obj->is_sub ? "sub-render" : "osd-render";
|
|
|
|
stats_time_start(osd->stats, stat_type_render);
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmaps *imgs =
|
|
|
|
render_object(osd, obj, res, video_pts, formats);
|
stats: some more performance graphs
Add an infrastructure for collecting performance-related data, use it in
some places. Add rendering of them to stats.lua.
There were two main goals: minimal impact on the normal code and normal
playback. So all these stats_* function calls either happen only during
initialization, or return immediately if no stats collection is going
on. That's why it does this lazily adding of stats entries etc. (a first
iteration made each stats entry an API thing, instead of just a single
stats_ctx, but I thought that was getting too intrusive in the "normal"
code, even if everything gets worse inside of stats.c).
You could get most of this information from various profilers (including
the extremely primitive --dump-stats thing in mpv), but this makes it
easier to see the most important information at once (at least in
theory), partially because we know best about the context of various
things.
Not very happy with this. It's all pretty primitive and dumb. At this
point I just wanted to get over with it, without necessarily having to
revisit it later, but with having my stupid statistics.
Somehow the code feels terrible. There are a lot of meh decisions in
there that could be better or worse (but mostly could be better), and it
just sucks but it's also trivial and uninteresting and does the job. I
guess I hate programming. It's so tedious and the result is always shit.
Anyway, enjoy.
2020-04-08 22:27:54 +00:00
|
|
|
|
|
|
|
stats_time_end(osd->stats, stat_type_render);
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
if (imgs && imgs->num_parts > 0) {
|
|
|
|
if (formats[imgs->format]) {
|
|
|
|
talloc_steal(list, imgs);
|
|
|
|
MP_TARRAY_APPEND(list, list->items, list->num_items, imgs);
|
|
|
|
imgs = NULL;
|
2012-10-19 17:11:08 +00:00
|
|
|
} else {
|
2013-12-21 18:06:37 +00:00
|
|
|
MP_ERR(osd, "Can't render OSD part %d (format %d).\n",
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
obj->type, imgs->format);
|
2012-10-19 17:11:08 +00:00
|
|
|
}
|
2012-10-04 15:16:32 +00:00
|
|
|
}
|
sub: uglify sub decoder with locking
The plan is to make the whole OSD thread-safe, and we start with this.
We just put locks on all entry points (fortunately, dec_sub.c and all
sd_*.c decoders are very closed off, and only the entry points in
dec_sub.h let you access it). I think this is pretty ugly, but at least
it's very simple.
There's a special case with sub_get_bitmaps(): this function returns
pointers to decoder data (specifically, libass images). There's no way
to synchronize this internally, so expose sub_lock/sub_unlock functions.
To make things simpler, and especially because the lock is sort-of
exposed to the outside world, make the locks recursive. Although the
only case where this is actually needed (although trivial) is
sub_set_extradata().
One corner case are ASS subtitles: for some reason, we keep a single
ASS_Renderer instance for subtitles around (probably to avoid rescanning
fonts with ordered chapters), and this ASS_Renderer instance is not
synchronized. Also, demux_libass.c loads ASS_Track objects, which are
directly passed to sd_ass.c. These things are not synchronized (and
would be hard to synchronize), and basically we're out of luck. But I
think for now, accesses happen reasonably serialized, so there is no
actual problem yet, even if we start to access OSD from other threads.
2014-01-17 22:13:09 +00:00
|
|
|
|
2020-05-09 15:54:33 +00:00
|
|
|
list->change_id += obj->vo_change_id;
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
talloc_free(imgs);
|
2012-10-04 15:16:32 +00:00
|
|
|
}
|
2014-01-18 00:19:20 +00:00
|
|
|
|
2016-09-16 15:17:32 +00:00
|
|
|
// If this is called with OSD_DRAW_SUB_ONLY or OSD_DRAW_OSD_ONLY set, assume
|
|
|
|
// it will always draw the complete OSD by doing multiple osd_draw() calls.
|
|
|
|
// OSD_DRAW_SUB_FILTER on the other hand is an evil special-case, and we
|
|
|
|
// must not reset the flag when it happens.
|
2016-09-15 12:22:48 +00:00
|
|
|
if (!(draw_flags & OSD_DRAW_SUB_FILTER))
|
2016-09-16 15:17:32 +00:00
|
|
|
osd->want_redraw_notification = false;
|
2016-09-15 12:22:48 +00:00
|
|
|
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
return list;
|
2012-10-19 17:11:08 +00:00
|
|
|
}
|
|
|
|
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
// Warning: this function should be considered legacy. Use osd_render() instead.
|
|
|
|
void osd_draw(struct osd_state *osd, struct mp_osd_res res,
|
|
|
|
double video_pts, int draw_flags,
|
|
|
|
const bool formats[SUBBITMAP_COUNT],
|
|
|
|
void (*cb)(void *ctx, struct sub_bitmaps *imgs), void *cb_ctx)
|
2012-10-19 17:11:08 +00:00
|
|
|
{
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmap_list *list =
|
|
|
|
osd_render(osd, res, video_pts, draw_flags, formats);
|
|
|
|
|
|
|
|
stats_time_start(osd->stats, "draw");
|
|
|
|
|
|
|
|
for (int n = 0; n < list->num_items; n++)
|
|
|
|
cb(cb_ctx, list->items[n]);
|
|
|
|
|
|
|
|
stats_time_end(osd->stats, "draw");
|
|
|
|
|
|
|
|
talloc_free(list);
|
2012-09-28 19:38:52 +00:00
|
|
|
}
|
|
|
|
|
sub: do not copy the target image if there is no OSD/subs
It's not easy to tell whether the OSD/subs are empty, or if something is
drawn. In general you have to use osd_draw() with a custom callback. If
nothing is visible, the callback is never invoked. (The actual reason
why this is so "hard" is the implementation of osd_libass.c, which
doesn't allow separating rendering and drawing of OSD elements, because
all OSD elements share the same ASS_Renderer.)
To simplify avoiding copies, make osd_draw_on_image() instead of the
caller use mp_image_make_writeable(). Introduce osd_draw_on_image_p(),
which works like osd_draw_on_image(), but gets the new image allocation
from an image pool. This is supposed to be an optimization, because it
reduces the frequency of large allocations/deallocations for image data.
The result of this is that the frequency of copies needed in conjunction
with vf_sub, screenshots, and vo_lavc (encoding) should be reduced.
vf_sub now always does true pass-through if no subs are shown.
Drop the pts check from vf_sub. This didn't make much sense.
2012-12-22 16:17:43 +00:00
|
|
|
// Calls mp_image_make_writeable() on the dest image if something is drawn.
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
// draw_flags as in osd_render().
|
|
|
|
void osd_draw_on_image(struct osd_state *osd, struct mp_osd_res res,
|
2012-10-27 16:06:09 +00:00
|
|
|
double video_pts, int draw_flags, struct mp_image *dest)
|
2012-10-07 01:26:46 +00:00
|
|
|
{
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
osd_draw_on_image_p(osd, res, video_pts, draw_flags, NULL, dest);
|
2012-10-07 01:26:46 +00:00
|
|
|
}
|
|
|
|
|
sub: do not copy the target image if there is no OSD/subs
It's not easy to tell whether the OSD/subs are empty, or if something is
drawn. In general you have to use osd_draw() with a custom callback. If
nothing is visible, the callback is never invoked. (The actual reason
why this is so "hard" is the implementation of osd_libass.c, which
doesn't allow separating rendering and drawing of OSD elements, because
all OSD elements share the same ASS_Renderer.)
To simplify avoiding copies, make osd_draw_on_image() instead of the
caller use mp_image_make_writeable(). Introduce osd_draw_on_image_p(),
which works like osd_draw_on_image(), but gets the new image allocation
from an image pool. This is supposed to be an optimization, because it
reduces the frequency of large allocations/deallocations for image data.
The result of this is that the frequency of copies needed in conjunction
with vf_sub, screenshots, and vo_lavc (encoding) should be reduced.
vf_sub now always does true pass-through if no subs are shown.
Drop the pts check from vf_sub. This didn't make much sense.
2012-12-22 16:17:43 +00:00
|
|
|
// Like osd_draw_on_image(), but if dest needs to be copied to make it
|
|
|
|
// writeable, allocate images from the given pool. (This is a minor
|
|
|
|
// optimization to reduce "real" image sized memory allocations.)
|
|
|
|
void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res,
|
|
|
|
double video_pts, int draw_flags,
|
|
|
|
struct mp_image_pool *pool, struct mp_image *dest)
|
|
|
|
{
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
struct sub_bitmap_list *list =
|
|
|
|
osd_render(osd, res, video_pts, draw_flags, mp_draw_sub_formats);
|
|
|
|
|
|
|
|
if (!list->num_items) {
|
|
|
|
talloc_free(list);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mp_image_pool_make_writeable(pool, dest))
|
|
|
|
return; // on OOM, skip
|
|
|
|
|
|
|
|
// Need to lock for the dumb osd->draw_cache thing.
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
|
2020-05-11 17:51:32 +00:00
|
|
|
if (!osd->draw_cache)
|
2020-05-13 18:07:59 +00:00
|
|
|
osd->draw_cache = mp_draw_sub_alloc(osd, osd->global);
|
2020-05-11 17:51:32 +00:00
|
|
|
|
2020-05-09 15:54:11 +00:00
|
|
|
stats_time_start(osd->stats, "draw-bmp");
|
|
|
|
|
2020-05-11 17:51:32 +00:00
|
|
|
if (!mp_draw_sub_bitmaps(osd->draw_cache, dest, list))
|
draw_bmp: rewrite
draw_bmp.c is the software blender for subtitles and OSD. It's used by
encoding mode (burning subtitles), and some VOs, like vo_drm, vo_x11,
vo_xv, and possibly more.
This changes the algorithm from upsampling the video to 4:4:4 and then
blending to downsampling the OSD and then blending directly to video.
This has far-reaching consequences for its internals, and results in an
effective rewrite.
Since I wanted to avoid un-premultiplying, all blending is done with
premultiplied alpha. That's actually the sane thing to do. The old code
just didn't do it, because it's very weird in YUV fixed point.
Essentially, you'd have to compensate for the chroma centering constant
by subtracting src_alpha/255*128. This seemed so hairy (especially with
correct rounding and high bit depths involved) that I went for using
float.
I think it turned out mostly OK, although it's more complex and less
maintainable than before. reinit() is certainly a bit too long. While it
should be possible to optimize the RGB path more (for example by
blending directly instead of doing the stupid float conversion), this is
probably slower. vo_xv users probably lose in this, because it takes the
slowest path (due to subsampling requirements and using YUV).
Why this rewrite? Nobody knows. I simply forgot the reason. But you'll
have it anyway. Whether or not this would have required a full rewrite,
at least it supports target alpha now (you can for example hard sub
transparent PNGs, if you ever wanted to use mpv for this).
Remove the check in vf_sub. The new draw_bmp.c is not as reliant on
libswscale anymore (mostly uses repack.c now), and osd.c shows an
error message on missing support instead now.
Formats with chroma subsampling of 4 are not supported, because FFmpeg
doesn't provide pixfmt definitions for alpha variants. We could provide
those ourselves (relatively trivial), but why bother.
2020-05-09 16:01:07 +00:00
|
|
|
MP_WARN(osd, "Failed rendering OSD.\n");
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
talloc_steal(osd, osd->draw_cache);
|
2020-05-09 15:54:11 +00:00
|
|
|
|
|
|
|
stats_time_end(osd->stats, "draw-bmp");
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
|
|
|
|
talloc_free(list);
|
2012-11-21 16:59:24 +00:00
|
|
|
}
|
|
|
|
|
2014-01-21 22:43:54 +00:00
|
|
|
// Setup the OSD resolution to render into an image with the given parameters.
|
|
|
|
// The interesting part about this is that OSD has to compensate the aspect
|
|
|
|
// ratio if the image does not have a 1:1 pixel aspect ratio.
|
|
|
|
struct mp_osd_res osd_res_from_image_params(const struct mp_image_params *p)
|
|
|
|
{
|
|
|
|
return (struct mp_osd_res) {
|
|
|
|
.w = p->w,
|
|
|
|
.h = p->h,
|
2015-12-19 19:04:31 +00:00
|
|
|
.display_par = p->p_h / (double)p->p_w,
|
2014-01-21 22:43:54 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-16 15:17:32 +00:00
|
|
|
// Typically called to react to OSD style changes.
|
2016-09-15 12:22:48 +00:00
|
|
|
void osd_changed(struct osd_state *osd)
|
2002-02-22 15:25:11 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-09-16 15:17:32 +00:00
|
|
|
osd->objs[OSDTYPE_OSD]->osd_changed = true;
|
|
|
|
osd->want_redraw_notification = true;
|
2017-12-29 16:19:25 +00:00
|
|
|
// Done here for a lack of a better place.
|
|
|
|
m_config_cache_update(osd->opts_cache);
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
osd: use libass for OSD rendering
The OSD will now be rendered with libass. The old rendering code, which
used freetype/fontconfig and did text layout manually, is disabled. To
re-enable the old code, use the --disable-libass-osd configure switch.
Some switches do nothing with the new code enabled, such as -subalign,
-sub-bg-alpha, -sub-bg-color, and many more. (The reason is mostly that
the code for rendering unstyled subtitles with libass doesn't make any
attempts to support them. Some of them could be supported in theory.)
Teletext rendering is not implemented in the new OSD rendering code. I
don't have any teletext sources for testing, and since teletext is
being phased out world-wide, the need for this is questionable.
Note that rendering is extremely inefficient, mostly because the libass
output is blended with the extremely strange mplayer OSD format. This
could be improved at a later point.
Remove most OSD rendering from vo_aa.c, because that was extremely
hacky, can't be made work with osd_libass, and didn't work anyway in
my tests.
Internally, some cleanup is done. Subtitle and OSD related variable
declarations were literally all over the place. Move them to sub.h and
sub.c, which were hoarding most of these declarations already. Make the
player core in mplayer.c free of concerns like bitmap font loading.
The old OSD rendering code has been moved to osd_ft.c. The font_load.c
and font_load_ft.c are only needed and compiled if the old OSD
rendering code is configured.
2012-03-22 05:26:37 +00:00
|
|
|
}
|
2002-04-16 00:35:01 +00:00
|
|
|
|
2014-01-18 00:19:20 +00:00
|
|
|
bool osd_query_and_reset_want_redraw(struct osd_state *osd)
|
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-09-15 12:22:48 +00:00
|
|
|
bool r = osd->want_redraw_notification;
|
|
|
|
osd->want_redraw_notification = false;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2016-03-08 20:54:17 +00:00
|
|
|
struct mp_osd_res osd_get_vo_res(struct osd_state *osd)
|
2014-01-18 00:19:20 +00:00
|
|
|
{
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_lock(&osd->lock);
|
2016-03-08 20:54:17 +00:00
|
|
|
// Any OSDTYPE is fine; but it mustn't be a subtitle one (can have lower res.)
|
|
|
|
struct mp_osd_res res = osd->objs[OSDTYPE_OSD]->vo_res;
|
2023-10-21 02:55:41 +00:00
|
|
|
mp_mutex_unlock(&osd->lock);
|
2014-01-18 00:19:20 +00:00
|
|
|
return res;
|
2013-12-12 23:19:17 +00:00
|
|
|
}
|
|
|
|
|
2013-12-11 22:15:29 +00:00
|
|
|
// Position the subbitmaps in imgs on the screen. Basically, this fits the
|
|
|
|
// subtitle canvas (of size frame_w x frame_h) onto the screen, such that it
|
|
|
|
// fills the whole video area (especially if the video is magnified, e.g. on
|
2014-10-21 09:37:32 +00:00
|
|
|
// fullscreen). If compensate_par is >0, adjust the way the subtitles are
|
|
|
|
// "stretched" on the screen, and letter-box the result. If compensate_par
|
|
|
|
// is <0, strictly letter-box the subtitles. If it is 0, stretch them.
|
2013-12-11 22:15:29 +00:00
|
|
|
void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,
|
|
|
|
struct mp_osd_res res, double compensate_par)
|
|
|
|
{
|
|
|
|
int vidw = res.w - res.ml - res.mr;
|
|
|
|
int vidh = res.h - res.mt - res.mb;
|
|
|
|
double xscale = (double)vidw / frame_w;
|
|
|
|
double yscale = (double)vidh / frame_h;
|
2021-10-29 18:45:10 +00:00
|
|
|
if (compensate_par < 0) {
|
|
|
|
assert(res.display_par);
|
2014-10-21 09:37:32 +00:00
|
|
|
compensate_par = xscale / yscale / res.display_par;
|
2021-10-29 18:45:10 +00:00
|
|
|
}
|
2015-10-21 21:07:24 +00:00
|
|
|
if (compensate_par > 0)
|
|
|
|
xscale /= compensate_par;
|
2013-12-11 22:15:29 +00:00
|
|
|
int cx = vidw / 2 - (int)(frame_w * xscale) / 2;
|
|
|
|
int cy = vidh / 2 - (int)(frame_h * yscale) / 2;
|
|
|
|
for (int i = 0; i < imgs->num_parts; i++) {
|
|
|
|
struct sub_bitmap *bi = &imgs->parts[i];
|
2024-05-02 01:56:01 +00:00
|
|
|
struct mp_rect rc = {
|
|
|
|
.x0 = lrint(bi->x * xscale),
|
|
|
|
.y0 = lrint(bi->y * yscale),
|
|
|
|
.x1 = lrint((bi->x + bi->w) * xscale),
|
|
|
|
.y1 = lrint((bi->y + bi->h) * yscale),
|
|
|
|
};
|
|
|
|
bi->x = rc.x0 + cx + res.ml;
|
|
|
|
bi->y = rc.y0 + cy + res.mt;
|
|
|
|
bi->dw = mp_rect_w(rc);
|
|
|
|
bi->dh = mp_rect_h(rc);
|
2013-12-11 22:15:29 +00:00
|
|
|
}
|
|
|
|
}
|
video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 21:34:32 +00:00
|
|
|
|
|
|
|
// Copy *in and return a new allocation of it. Free with talloc_free(). This
|
|
|
|
// will contain a refcounted copy of the image data.
|
|
|
|
//
|
|
|
|
// in->packed must be set and must be a refcounted image, unless there is no
|
|
|
|
// data (num_parts==0).
|
|
|
|
//
|
|
|
|
// p_cache: if not NULL, then this points to a struct sub_bitmap_copy_cache*
|
|
|
|
// variable. The function may set this to an allocation and may later
|
|
|
|
// read it. You have to free it with talloc_free() when done.
|
|
|
|
// in: valid struct, or NULL (in this case it also returns NULL)
|
|
|
|
// returns: new copy, or NULL if there was no data in the input
|
|
|
|
struct sub_bitmaps *sub_bitmaps_copy(struct sub_bitmap_copy_cache **p_cache,
|
|
|
|
struct sub_bitmaps *in)
|
|
|
|
{
|
|
|
|
if (!in || !in->num_parts)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
struct sub_bitmaps *res = talloc(NULL, struct sub_bitmaps);
|
|
|
|
*res = *in;
|
|
|
|
|
|
|
|
// Note: the p_cache thing is a lie and unused.
|
|
|
|
|
|
|
|
// The bitmaps being refcounted is essential for performance, and for
|
|
|
|
// not invalidating in->parts[*].bitmap pointers.
|
|
|
|
assert(in->packed && in->packed->bufs[0]);
|
|
|
|
|
|
|
|
res->packed = mp_image_new_ref(res->packed);
|
|
|
|
talloc_steal(res, res->packed);
|
|
|
|
|
|
|
|
res->parts = NULL;
|
|
|
|
MP_RESIZE_ARRAY(res, res->parts, res->num_parts);
|
|
|
|
memcpy(res->parts, in->parts, sizeof(res->parts[0]) * res->num_parts);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|