summaryrefslogtreecommitdiffstats
path: root/sub/draw_bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sub/draw_bmp.c')
-rw-r--r--sub/draw_bmp.c77
1 files changed, 68 insertions, 9 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) {