mirror of https://github.com/mpv-player/mpv
sub: add cache to mp_draw_sub_bitmaps()
This caches scaled RGBA sub-bitmaps.
This commit is contained in:
parent
97c6425140
commit
bf68634d15
|
@ -19,6 +19,7 @@
|
||||||
#include "sub/draw_bmp.h"
|
#include "sub/draw_bmp.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "sub/sub.h"
|
#include "sub/sub.h"
|
||||||
|
@ -27,6 +28,26 @@
|
||||||
#include "libmpcodecs/img_format.h"
|
#include "libmpcodecs/img_format.h"
|
||||||
#include "libvo/csputils.h"
|
#include "libvo/csputils.h"
|
||||||
|
|
||||||
|
const bool mp_draw_sub_formats[SUBBITMAP_COUNT] = {
|
||||||
|
[SUBBITMAP_LIBASS] = true,
|
||||||
|
[SUBBITMAP_RGBA] = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sub_cache {
|
||||||
|
struct mp_image *i, *a;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct part {
|
||||||
|
int bitmap_pos_id;
|
||||||
|
int num_imgs;
|
||||||
|
struct sub_cache *imgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mp_draw_sub_cache
|
||||||
|
{
|
||||||
|
struct part *parts[MAX_OSD_PARTS];
|
||||||
|
};
|
||||||
|
|
||||||
#define ACCURATE
|
#define ACCURATE
|
||||||
#define CONDITIONAL
|
#define CONDITIONAL
|
||||||
#define CONDITIONAL2
|
#define CONDITIONAL2
|
||||||
|
@ -430,8 +451,11 @@ static bool align_bbox_to_swscale_requirements(int *x1, int *y1,
|
||||||
return (*x2 > *x1) && (*y2 > *y1);
|
return (*x2 > *x1) && (*y2 > *y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs,
|
// cache: if not NULL, the function will set *cache to a talloc-allocated cache
|
||||||
struct mp_csp_details *csp)
|
// containing scaled versions of sbs contents - free the cache with
|
||||||
|
// talloc_free()
|
||||||
|
void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
|
||||||
|
struct sub_bitmaps *sbs, struct mp_csp_details *csp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
|
@ -440,6 +464,29 @@ void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs,
|
||||||
float yuv2rgb[3][4];
|
float yuv2rgb[3][4];
|
||||||
float rgb2yuv[3][4];
|
float rgb2yuv[3][4];
|
||||||
|
|
||||||
|
if (cache && !*cache)
|
||||||
|
*cache = talloc_zero(NULL, struct mp_draw_sub_cache);
|
||||||
|
|
||||||
|
struct part *part = NULL;
|
||||||
|
|
||||||
|
bool use_cache = sbs->format == SUBBITMAP_RGBA;
|
||||||
|
if (cache && use_cache) {
|
||||||
|
part = (*cache)->parts[sbs->render_index];
|
||||||
|
if (part && part->bitmap_pos_id != sbs->bitmap_pos_id) {
|
||||||
|
talloc_free(part);
|
||||||
|
part = NULL;
|
||||||
|
}
|
||||||
|
if (!part) {
|
||||||
|
part = talloc_zero(*cache, struct part);
|
||||||
|
part->bitmap_pos_id = sbs->bitmap_pos_id;
|
||||||
|
part->num_imgs = sbs->num_parts;
|
||||||
|
part->imgs = talloc_zero_array(part, struct sub_cache,
|
||||||
|
part->num_imgs);
|
||||||
|
}
|
||||||
|
assert(part->num_imgs == sbs->num_parts);
|
||||||
|
(*cache)->parts[sbs->render_index] = part;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ACCURATE
|
#ifdef ACCURATE
|
||||||
int format = IMGFMT_444P16;
|
int format = IMGFMT_444P16;
|
||||||
int bits = 16;
|
int bits = 16;
|
||||||
|
@ -528,12 +575,21 @@ void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs,
|
||||||
0, 0, temp->w, temp->h))
|
0, 0, temp->w, temp->h))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (part) {
|
||||||
|
sbi = part->imgs[i].i;
|
||||||
|
sba = part->imgs[i].a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(sbi && sba)) {
|
||||||
if (!sub_bitmap_to_mp_images(&sbi, color_yuv, &color_a, &sba, sb,
|
if (!sub_bitmap_to_mp_images(&sbi, color_yuv, &color_a, &sba, sb,
|
||||||
sbs->format, csp, rgb2yuv, format, bits)) {
|
sbs->format, csp, rgb2yuv, format,
|
||||||
|
bits))
|
||||||
|
{
|
||||||
mp_msg(MSGT_VO, MSGL_ERR,
|
mp_msg(MSGT_VO, MSGL_ERR,
|
||||||
"render_sub_bitmap: invalid sub bitmap type\n");
|
"render_sub_bitmap: invalid sub bitmap type\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// call blend_alpha 3 times
|
// call blend_alpha 3 times
|
||||||
int p;
|
int p;
|
||||||
|
@ -563,11 +619,14 @@ void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sbi)
|
if (part) {
|
||||||
|
part->imgs[i].i = talloc_steal(part, sbi);
|
||||||
|
part->imgs[i].a = talloc_steal(part, sba);
|
||||||
|
} else {
|
||||||
free_mp_image(sbi);
|
free_mp_image(sbi);
|
||||||
if (sba)
|
|
||||||
free_mp_image(sba);
|
free_mp_image(sba);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (temp != &dst_region) {
|
if (temp != &dst_region) {
|
||||||
// convert back
|
// convert back
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
#ifndef MPLAYER_DRAW_BMP_H
|
#ifndef MPLAYER_DRAW_BMP_H
|
||||||
#define MPLAYER_DRAW_BMP_H
|
#define MPLAYER_DRAW_BMP_H
|
||||||
|
|
||||||
|
#include "sub/sub.h"
|
||||||
|
|
||||||
struct mp_image;
|
struct mp_image;
|
||||||
struct sub_bitmaps;
|
struct sub_bitmaps;
|
||||||
struct mp_csp_details;
|
struct mp_csp_details;
|
||||||
void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs,
|
struct mp_draw_sub_cache;
|
||||||
struct mp_csp_details *csp);
|
void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
|
||||||
|
struct sub_bitmaps *sbs, struct mp_csp_details *csp);
|
||||||
|
|
||||||
|
extern const bool mp_draw_sub_formats[SUBBITMAP_COUNT];
|
||||||
|
|
||||||
#endif /* MPLAYER_DRAW_BMP_H */
|
#endif /* MPLAYER_DRAW_BMP_H */
|
||||||
|
|
||||||
|
|
15
sub/sub.c
15
sub/sub.c
|
@ -284,6 +284,7 @@ void draw_osd_with_eosd(struct vo *vo, struct osd_state *osd)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct draw_on_image_closure {
|
struct draw_on_image_closure {
|
||||||
|
struct osd_state *osd;
|
||||||
struct mp_image *dest;
|
struct mp_image *dest;
|
||||||
struct mp_csp_details *dest_csp;
|
struct mp_csp_details *dest_csp;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
@ -292,7 +293,10 @@ struct draw_on_image_closure {
|
||||||
static void draw_on_image(void *ctx, struct sub_bitmaps *imgs)
|
static void draw_on_image(void *ctx, struct sub_bitmaps *imgs)
|
||||||
{
|
{
|
||||||
struct draw_on_image_closure *closure = ctx;
|
struct draw_on_image_closure *closure = ctx;
|
||||||
mp_draw_sub_bitmaps(closure->dest, imgs, closure->dest_csp);
|
struct osd_state *osd = closure->osd;
|
||||||
|
mp_draw_sub_bitmaps(&osd->draw_cache, closure->dest, imgs,
|
||||||
|
closure->dest_csp);
|
||||||
|
talloc_steal(osd, osd->draw_cache);
|
||||||
closure->changed = true;
|
closure->changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,12 +305,9 @@ bool osd_draw_on_image(struct osd_state *osd, struct sub_render_params *params,
|
||||||
int draw_flags, struct mp_image *dest,
|
int draw_flags, struct mp_image *dest,
|
||||||
struct mp_csp_details *dest_csp)
|
struct mp_csp_details *dest_csp)
|
||||||
{
|
{
|
||||||
static const bool formats[SUBBITMAP_COUNT] = {
|
struct draw_on_image_closure closure = {osd, dest, dest_csp};
|
||||||
[SUBBITMAP_LIBASS] = true,
|
osd_draw(osd, params, draw_flags, mp_draw_sub_formats,
|
||||||
[SUBBITMAP_RGBA] = true,
|
&draw_on_image, &closure);
|
||||||
};
|
|
||||||
struct draw_on_image_closure closure = {dest, dest_csp};
|
|
||||||
osd_draw(osd, params, draw_flags, formats, &draw_on_image, &closure);
|
|
||||||
return closure.changed;
|
return closure.changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,6 @@ struct osd_object {
|
||||||
|
|
||||||
// caches for OSD conversion (internal to render_object())
|
// caches for OSD conversion (internal to render_object())
|
||||||
struct osd_conv_cache *cache[OSD_CONV_CACHE_MAX];
|
struct osd_conv_cache *cache[OSD_CONV_CACHE_MAX];
|
||||||
|
|
||||||
struct sub_bitmaps cached;
|
struct sub_bitmaps cached;
|
||||||
|
|
||||||
// VO cache state
|
// VO cache state
|
||||||
|
@ -138,6 +137,9 @@ struct osd_state {
|
||||||
|
|
||||||
struct MPOpts *opts;
|
struct MPOpts *opts;
|
||||||
|
|
||||||
|
// Internal to sub.c
|
||||||
|
struct mp_draw_sub_cache *draw_cache;
|
||||||
|
|
||||||
// Internally used by osd_libass.c
|
// Internally used by osd_libass.c
|
||||||
struct ass_renderer *osd_render;
|
struct ass_renderer *osd_render;
|
||||||
struct ass_library *osd_ass_library;
|
struct ass_library *osd_ass_library;
|
||||||
|
|
Loading…
Reference in New Issue