summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-19 17:49:49 +0200
committerwm4 <wm4@nowhere>2012-10-24 21:56:34 +0200
commitbf68634d15c747fd05f118b1bd95e3017c1eb6bb (patch)
tree92395008313f2ce60c06189f2cd4a05a0dbaf9e7
parent97c6425140aecc3910a622fb0ad7d79916cfebbe (diff)
downloadmpv-bf68634d15c747fd05f118b1bd95e3017c1eb6bb.tar.bz2
mpv-bf68634d15c747fd05f118b1bd95e3017c1eb6bb.tar.xz
sub: add cache to mp_draw_sub_bitmaps()
This caches scaled RGBA sub-bitmaps.
-rw-r--r--sub/draw_bmp.c77
-rw-r--r--sub/draw_bmp.h9
-rw-r--r--sub/sub.c15
-rw-r--r--sub/sub.h4
4 files changed, 86 insertions, 19 deletions
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 <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) {
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;