diff options
Diffstat (limited to 'sub')
-rw-r--r-- | sub/img_convert.c | 42 | ||||
-rw-r--r-- | sub/img_convert.h | 2 | ||||
-rw-r--r-- | sub/sub.c | 5 |
3 files changed, 49 insertions, 0 deletions
diff --git a/sub/img_convert.c b/sub/img_convert.c index e2eded24c3..274a83d833 100644 --- a/sub/img_convert.c +++ b/sub/img_convert.c @@ -28,6 +28,7 @@ #include "video/img_format.h" #include "video/mp_image.h" #include "video/sws_utils.h" +#include "video/memcpy_pic.h" struct osd_conv_cache { struct sub_bitmap part; @@ -86,3 +87,44 @@ bool osd_conv_idx_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs) } return true; } + +bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs, + double gblur) +{ + struct sub_bitmaps src = *imgs; + if (src.format != SUBBITMAP_RGBA) + return false; + + talloc_free(c->parts); + imgs->parts = c->parts = talloc_array(c, struct sub_bitmap, src.num_parts); + + for (int n = 0; n < src.num_parts; n++) { + struct sub_bitmap *d = &imgs->parts[n]; + struct sub_bitmap *s = &src.parts[n]; + + // add a transparent padding border to reduce artifacts + int pad = 5; + struct mp_image *temp = alloc_mpi(s->w + pad * 2, s->h + pad * 2, + IMGFMT_BGRA); + memset_pic(temp->planes[0], 0, temp->w * 4, temp->h, temp->stride[0]); + uint8_t *p0 = temp->planes[0] + pad * 4 + pad * temp->stride[0]; + memcpy_pic(p0, s->bitmap, s->w * 4, s->h, temp->stride[0], s->stride); + + double sx = (double)s->dw / s->w; + double sy = (double)s->dh / s->h; + + d->x = s->x - pad * sx; + d->y = s->y - pad * sy; + d->w = d->dw = s->dw + pad * 2 * sx; + d->h = d->dh = s->dh + pad * 2 * sy; + struct mp_image *image = alloc_mpi(d->w, d->h, IMGFMT_BGRA); + talloc_steal(c->parts, image); + d->stride = image->stride[0]; + d->bitmap = image->planes[0]; + + mp_image_sw_blur_scale(image, temp, gblur); + + talloc_free(temp); + } + return true; +} diff --git a/sub/img_convert.h b/sub/img_convert.h index c947c44f01..eab543051c 100644 --- a/sub/img_convert.h +++ b/sub/img_convert.h @@ -11,5 +11,7 @@ struct osd_conv_cache *osd_conv_cache_new(void); // These functions convert from one OSD format to another. On success, they copy // the converted image data into c, and change imgs to point to the data. bool osd_conv_idx_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs); +bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs, + double gblur); #endif @@ -172,6 +172,8 @@ static void render_object(struct osd_state *osd, struct osd_object *obj, const bool formats[SUBBITMAP_COUNT], struct sub_bitmaps *out_imgs) { + struct MPOpts *opts = osd->opts; + *out_imgs = (struct sub_bitmaps) {0}; if (!osd_res_equals(res, obj->vo_res)) @@ -222,6 +224,9 @@ static void render_object(struct osd_state *osd, struct osd_object *obj, if (formats[SUBBITMAP_RGBA] && out_imgs->format == SUBBITMAP_INDEXED) cached |= osd_conv_idx_to_rgba(obj->cache[0], out_imgs); + if (out_imgs->format == SUBBITMAP_RGBA && opts->sub_gauss != 0.0f) + cached |= osd_conv_blur_rgba(obj->cache[1], out_imgs, opts->sub_gauss); + if (cached) obj->cached = *out_imgs; } |