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.
This commit is contained in:
wm4 2012-12-28 15:49:27 +01:00
parent 03730e73dc
commit 5cbdf8f61e
1 changed files with 48 additions and 27 deletions

View File

@ -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;
imgs->parts = c->part;
imgs->num_parts = num_bb;
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);
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);
for (int n = 0; n < src.num_parts; n++) {
struct sub_bitmap *s = &src.parts[n];
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);
if (talloc_get_size(c->scratch) < newsize) {
talloc_free(c->scratch);
c->scratch = talloc_array(c, uint8_t, newsize);
}
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;
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;
}