sub: add cache to mp_draw_sub_bitmaps()

This caches scaled RGBA sub-bitmaps.
This commit is contained in:
wm4 2012-10-19 17:49:49 +02:00
parent 97c6425140
commit bf68634d15
4 changed files with 86 additions and 19 deletions

View File

@ -19,6 +19,7 @@
#include "sub/draw_bmp.h"
#include <stdbool.h>
#include <assert.h>
#include <math.h>
#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) {

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;