mpv/sub/draw_bmp.h

64 lines
2.9 KiB
C
Raw Normal View History

#ifndef MPLAYER_DRAW_BMP_H
#define MPLAYER_DRAW_BMP_H
#include "osd.h"
struct mp_rect;
struct mp_image;
struct mpv_global;
struct mp_draw_sub_cache;
struct mp_draw_sub_cache *mp_draw_sub_alloc(void *ta_parent, struct mpv_global *g);
// Only for use in tests.
struct mp_draw_sub_cache *mp_draw_sub_alloc_test(struct mp_image *dst);
// 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 PL_ALPHA_PREMULTIPLIED
// (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);
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);
// 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.
// If num_mod_rcs==0 is returned, this function guarantees that the act region
// did not change since the last call.
// 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);
extern const bool mp_draw_sub_formats[SUBBITMAP_COUNT];
#endif /* MPLAYER_DRAW_BMP_H */
// vim: ts=4 sw=4 et tw=80