2012-10-24 17:11:42 +00:00
|
|
|
#ifndef MPLAYER_DRAW_BMP_H
|
|
|
|
#define MPLAYER_DRAW_BMP_H
|
|
|
|
|
2013-11-24 11:58:06 +00:00
|
|
|
#include "osd.h"
|
2012-10-19 15:49:49 +00:00
|
|
|
|
2020-05-11 17:51:32 +00:00
|
|
|
struct mp_rect;
|
2012-10-24 17:11:42 +00:00
|
|
|
struct mp_image;
|
2020-05-13 18:07:59 +00:00
|
|
|
struct mpv_global;
|
2012-10-19 15:49:49 +00:00
|
|
|
struct mp_draw_sub_cache;
|
2020-05-11 17:51:32 +00:00
|
|
|
|
2020-05-13 18:07:59 +00:00
|
|
|
struct mp_draw_sub_cache *mp_draw_sub_alloc(void *ta_parent, struct mpv_global *g);
|
2020-05-11 17:51:32 +00:00
|
|
|
|
2023-02-26 03:50:08 +00:00
|
|
|
// Only for use in tests.
|
|
|
|
struct mp_draw_sub_cache *mp_draw_sub_alloc_test(struct mp_image *dst);
|
|
|
|
|
2020-05-11 17:51:32 +00:00
|
|
|
// Render the sub-bitmaps in sbs_list to dst. sbs_list must have been rendered
|
|
|
|
// for an OSD resolution equivalent to dst's size (UB if not).
|
|
|
|
// Warning: if dst is a format with alpha, and dst is not set to MP_ALPHA_PREMUL
|
|
|
|
// (not done by default), this will be extremely slow.
|
|
|
|
// Warning: the caller is responsible for ensuring that dst is writable.
|
|
|
|
// cache: allocated instance; caches non-changing OSD parts etc.
|
|
|
|
// dst: image to draw to
|
|
|
|
// sbs_list: source sub-bitmaps
|
|
|
|
// returns: success
|
|
|
|
bool mp_draw_sub_bitmaps(struct mp_draw_sub_cache *cache, struct mp_image *dst,
|
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 *sbs_list);
|
2020-05-11 17:51:32 +00:00
|
|
|
|
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
|
|
|
char *mp_draw_sub_get_dbg_info(struct mp_draw_sub_cache *c);
|
2012-10-19 15:49:49 +00:00
|
|
|
|
2020-05-11 17:51:32 +00:00
|
|
|
// Return a RGBA overlay with subtitles. The returned image uses IMGFMT_BGRA and
|
|
|
|
// premultiplied alpha, and the size specified by sbs_list.w/h.
|
|
|
|
// This can return a list of active (act_) and modified (mod_) rectangles.
|
|
|
|
// Active rectangles are regions that contain visible OSD pixels. Modified
|
|
|
|
// rectangles are regions that were changed since the last call. This function
|
|
|
|
// always makes the act region a subset of the mod region. Rectangles within a
|
|
|
|
// list never overlap with rectangles within the same list.
|
2020-05-13 20:46:29 +00:00
|
|
|
// If num_mod_rcs==0 is returned, this function guarantees that the act region
|
|
|
|
// did not change since the last call.
|
2020-05-11 17:51:32 +00:00
|
|
|
// If the user-provided lists are too small (max_*_rcs too small), multiple
|
|
|
|
// rectangles are merged until they fit in the list.
|
|
|
|
// You can pass max_act_rcs=0, which implies you render the whole overlay.
|
|
|
|
// cache: allocated instance; keeps track of changed regions
|
|
|
|
// sbs_list: source sub-bitmaps
|
|
|
|
// act_rcs: caller allocated list of non-transparent rectangles
|
|
|
|
// max_act_rcs: number of allocated items in act_rcs
|
|
|
|
// num_act_rcs: set to the number of valid items in act_rcs
|
|
|
|
// mod_rcs, max_mod_rcs, num_mod_rcs: modified rectangles
|
|
|
|
// returns: internal OSD overlay owned by cache, NULL on error
|
|
|
|
// read only, valid until the next call on cache
|
|
|
|
struct mp_image *mp_draw_sub_overlay(struct mp_draw_sub_cache *cache,
|
|
|
|
struct sub_bitmap_list *sbs_list,
|
|
|
|
struct mp_rect *act_rcs,
|
|
|
|
int max_act_rcs,
|
|
|
|
int *num_act_rcs,
|
|
|
|
struct mp_rect *mod_rcs,
|
|
|
|
int max_mod_rcs,
|
|
|
|
int *num_mod_rcs);
|
|
|
|
|
2012-10-19 15:49:49 +00:00
|
|
|
extern const bool mp_draw_sub_formats[SUBBITMAP_COUNT];
|
2012-10-24 17:11:42 +00:00
|
|
|
|
|
|
|
#endif /* MPLAYER_DRAW_BMP_H */
|
|
|
|
|
|
|
|
// vim: ts=4 sw=4 et tw=80
|