mirror of https://github.com/mpv-player/mpv
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:
parent
03730e73dc
commit
5cbdf8f61e
|
@ -31,8 +31,9 @@
|
||||||
#include "video/memcpy_pic.h"
|
#include "video/memcpy_pic.h"
|
||||||
|
|
||||||
struct osd_conv_cache {
|
struct osd_conv_cache {
|
||||||
struct sub_bitmap part;
|
struct sub_bitmap part[MP_SUB_BB_LIST_MAX];
|
||||||
struct sub_bitmap *parts;
|
struct sub_bitmap *parts;
|
||||||
|
void *scratch;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct osd_conv_cache *osd_conv_cache_new(void)
|
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;
|
return false;
|
||||||
assert(!src.scaled); // ASS is always unscaled
|
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->format = SUBBITMAP_RGBA;
|
||||||
imgs->parts = bmp;
|
imgs->parts = c->part;
|
||||||
imgs->num_parts = 0;
|
imgs->num_parts = num_bb;
|
||||||
|
|
||||||
struct mp_rect bb;
|
size_t newsize = 0;
|
||||||
if (!mp_sub_bitmaps_bb(&src, &bb))
|
for (int n = 0; n < num_bb; n++) {
|
||||||
return true;
|
struct mp_rect bb = bb_list[n];
|
||||||
|
int w = bb.x1 - bb.x0;
|
||||||
bmp->x = bb.x0;
|
int h = bb.y1 - bb.y0;
|
||||||
bmp->y = bb.y0;
|
int stride = w * 4;
|
||||||
bmp->w = bmp->dw = bb.x1 - bb.x0;
|
newsize += h * stride;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset_pic(bmp->bitmap, 0, bmp->w * 4, bmp->h, bmp->stride);
|
if (talloc_get_size(c->scratch) < newsize) {
|
||||||
|
talloc_free(c->scratch);
|
||||||
for (int n = 0; n < src.num_parts; n++) {
|
c->scratch = talloc_array(c, uint8_t, newsize);
|
||||||
struct sub_bitmap *s = &src.parts[n];
|
}
|
||||||
|
|
||||||
draw_ass_rgba(s->bitmap, s->w, s->h, s->stride,
|
uint8_t *data = c->scratch;
|
||||||
bmp->bitmap, bmp->stride,
|
|
||||||
s->x - bb.x0, s->y - bb.y0,
|
for (int n = 0; n < num_bb; n++) {
|
||||||
s->libass.color);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue