From bf68634d15c747fd05f118b1bd95e3017c1eb6bb Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 19 Oct 2012 17:49:49 +0200 Subject: sub: add cache to mp_draw_sub_bitmaps() This caches scaled RGBA sub-bitmaps. --- sub/draw_bmp.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++------- sub/draw_bmp.h | 9 +++++-- sub/sub.c | 15 ++++++------ sub/sub.h | 4 ++- 4 files changed, 86 insertions(+), 19 deletions(-) (limited to 'sub') diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c index fba3513ee4..315e52dfdd 100644 --- a/sub/draw_bmp.c +++ b/sub/draw_bmp.c @@ -19,6 +19,7 @@ #include "sub/draw_bmp.h" #include +#include #include #include "sub/sub.h" @@ -27,6 +28,26 @@ #include "libmpcodecs/img_format.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 CONDITIONAL #define CONDITIONAL2 @@ -430,8 +451,11 @@ static bool align_bbox_to_swscale_requirements(int *x1, int *y1, return (*x2 > *x1) && (*y2 > *y1); } -void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs, - struct mp_csp_details *csp) +// cache: if not NULL, the function will set *cache to a talloc-allocated cache +// 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 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 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 int format = IMGFMT_444P16; int bits = 16; @@ -528,11 +575,20 @@ void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs, 0, 0, temp->w, temp->h)) continue; - if (!sub_bitmap_to_mp_images(&sbi, color_yuv, &color_a, &sba, sb, - sbs->format, csp, rgb2yuv, format, bits)) { - mp_msg(MSGT_VO, MSGL_ERR, - "render_sub_bitmap: invalid sub bitmap type\n"); - 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, + sbs->format, csp, rgb2yuv, format, + bits)) + { + mp_msg(MSGT_VO, MSGL_ERR, + "render_sub_bitmap: invalid sub bitmap type\n"); + continue; + } } // call blend_alpha 3 times @@ -563,10 +619,13 @@ 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); - if (sba) free_mp_image(sba); + } } if (temp != &dst_region) { diff --git a/sub/draw_bmp.h b/sub/draw_bmp.h index 478965af15..b7ebcf5e8a 100644 --- a/sub/draw_bmp.h +++ b/sub/draw_bmp.h @@ -1,11 +1,16 @@ #ifndef MPLAYER_DRAW_BMP_H #define MPLAYER_DRAW_BMP_H +#include "sub/sub.h" + struct mp_image; struct sub_bitmaps; struct mp_csp_details; -void mp_draw_sub_bitmaps(struct mp_image *dst, struct sub_bitmaps *sbs, - struct mp_csp_details *csp); +struct mp_draw_sub_cache; +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 */ diff --git a/sub/sub.c b/sub/sub.c index 0438ffccab..6c0f740766 100644 --- a/sub/sub.c +++ b/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 osd_state *osd; struct mp_image *dest; struct mp_csp_details *dest_csp; bool changed; @@ -292,7 +293,10 @@ struct draw_on_image_closure { static void draw_on_image(void *ctx, struct sub_bitmaps *imgs) { 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; } @@ -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, struct mp_csp_details *dest_csp) { - static const bool formats[SUBBITMAP_COUNT] = { - [SUBBITMAP_LIBASS] = true, - [SUBBITMAP_RGBA] = true, - }; - struct draw_on_image_closure closure = {dest, dest_csp}; - osd_draw(osd, params, draw_flags, formats, &draw_on_image, &closure); + struct draw_on_image_closure closure = {osd, dest, dest_csp}; + osd_draw(osd, params, draw_flags, mp_draw_sub_formats, + &draw_on_image, &closure); return closure.changed; } diff --git a/sub/sub.h b/sub/sub.h index ecfd0c40cc..494b84379b 100644 --- a/sub/sub.h +++ b/sub/sub.h @@ -106,7 +106,6 @@ struct osd_object { // caches for OSD conversion (internal to render_object()) struct osd_conv_cache *cache[OSD_CONV_CACHE_MAX]; - struct sub_bitmaps cached; // VO cache state @@ -138,6 +137,9 @@ struct osd_state { struct MPOpts *opts; + // Internal to sub.c + struct mp_draw_sub_cache *draw_cache; + // Internally used by osd_libass.c struct ass_renderer *osd_render; struct ass_library *osd_ass_library; -- cgit v1.2.3