summaryrefslogtreecommitdiffstats
path: root/sub/img_convert.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-28 15:49:27 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:16 +0100
commit5cbdf8f61e2b9583d8d8fd1f8100a27963582ba4 (patch)
treec938b10ac54404dcd5e3be85fe3f6de23d29809d /sub/img_convert.c
parent03730e73dc0439e0e673857d8c376a70cfcc8152 (diff)
downloadmpv-5cbdf8f61e2b9583d8d8fd1f8100a27963582ba4.tar.bz2
mpv-5cbdf8f61e2b9583d8d8fd1f8100a27963582ba4.tar.xz
img_convert: use multiple bounding boxes for ASS->RGBA
Should be more efficient in situations both subtitles and toptitles are shown, because no blending has to be performed for the video between them.
Diffstat (limited to 'sub/img_convert.c')
-rw-r--r--sub/img_convert.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/sub/img_convert.c b/sub/img_convert.c
index abbb6ad301..547f6aa265 100644
--- a/sub/img_convert.c
+++ b/sub/img_convert.c
@@ -31,8 +31,9 @@
#include "video/memcpy_pic.h"
struct osd_conv_cache {
- struct sub_bitmap part;
+ struct sub_bitmap part[MP_SUB_BB_LIST_MAX];
struct sub_bitmap *parts;
+ void *scratch;
};
struct osd_conv_cache *osd_conv_cache_new(void)
@@ -204,39 +205,59 @@ bool osd_conv_ass_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs)
return false;
assert(!src.scaled); // ASS is always unscaled
- struct sub_bitmap *bmp = &c->part;
+ struct mp_rect bb_list[MP_SUB_BB_LIST_MAX];
+ int num_bb = mp_get_sub_bb_list(&src, bb_list, MP_SUB_BB_LIST_MAX);
imgs->format = SUBBITMAP_RGBA;
- imgs->parts = bmp;
- imgs->num_parts = 0;
-
- struct mp_rect bb;
- if (!mp_sub_bitmaps_bb(&src, &bb))
- return true;
-
- bmp->x = bb.x0;
- bmp->y = bb.y0;
- bmp->w = bmp->dw = bb.x1 - bb.x0;
- bmp->h = bmp->dh = bb.y1 - bb.y0;
- bmp->stride = bmp->w * 4;
- size_t newsize = bmp->h * bmp->stride;
- if (talloc_get_size(bmp->bitmap) < newsize) {
- talloc_free(bmp->bitmap);
- bmp->bitmap = talloc_array(c, char, newsize);
+ imgs->parts = c->part;
+ imgs->num_parts = num_bb;
+
+ size_t newsize = 0;
+ for (int n = 0; n < num_bb; n++) {
+ struct mp_rect bb = bb_list[n];
+ int w = bb.x1 - bb.x0;
+ int h = bb.y1 - bb.y0;
+ int stride = w * 4;
+ newsize += h * stride;
}
- memset_pic(bmp->bitmap, 0, bmp->w * 4, bmp->h, bmp->stride);
+ if (talloc_get_size(c->scratch) < newsize) {
+ talloc_free(c->scratch);
+ c->scratch = talloc_array(c, uint8_t, newsize);
+ }
- for (int n = 0; n < src.num_parts; n++) {
- struct sub_bitmap *s = &src.parts[n];
+ uint8_t *data = c->scratch;
+
+ for (int n = 0; n < num_bb; n++) {
+ struct mp_rect bb = bb_list[n];
+ struct sub_bitmap *bmp = &c->part[n];
+
+ bmp->x = bb.x0;
+ bmp->y = bb.y0;
+ bmp->w = bmp->dw = bb.x1 - bb.x0;
+ bmp->h = bmp->dh = bb.y1 - bb.y0;
+ bmp->stride = bmp->w * 4;
+ bmp->bitmap = data;
+ data += bmp->h * bmp->stride;
- draw_ass_rgba(s->bitmap, s->w, s->h, s->stride,
- bmp->bitmap, bmp->stride,
- s->x - bb.x0, s->y - bb.y0,
- s->libass.color);
+ memset_pic(bmp->bitmap, 0, bmp->w * 4, bmp->h, bmp->stride);
+
+ for (int n = 0; n < src.num_parts; n++) {
+ struct sub_bitmap *s = &src.parts[n];
+
+ // Assume mp_get_sub_bb_list() never splits sub bitmaps
+ // So we don't clip/adjust the size of the sub bitmap
+ if (s->x > bb.x1 || s->x + s->w < bb.x0 ||
+ s->y > bb.y1 || s->y + s->h < bb.y0)
+ continue;
+
+ draw_ass_rgba(s->bitmap, s->w, s->h, s->stride,
+ bmp->bitmap, bmp->stride,
+ s->x - bb.x0, s->y - bb.y0,
+ s->libass.color);
+ }
}
- imgs->num_parts = 1;
return true;
}