summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
Diffstat (limited to 'sub')
-rw-r--r--sub/img_convert.c55
-rw-r--r--sub/img_convert.h4
-rw-r--r--sub/osd.c4
-rw-r--r--sub/sd_lavc.c25
4 files changed, 37 insertions, 51 deletions
diff --git a/sub/img_convert.c b/sub/img_convert.c
index ebf9c209da..2015e49ca6 100644
--- a/sub/img_convert.c
+++ b/sub/img_convert.c
@@ -41,52 +41,25 @@ struct osd_conv_cache *osd_conv_cache_new(void)
return talloc_zero(NULL, struct osd_conv_cache);
}
-bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs,
- double gblur)
+void mp_blur_rgba_sub_bitmap(struct sub_bitmap *d, double gblur)
{
- struct sub_bitmaps src = *imgs;
- if (src.format != SUBBITMAP_RGBA)
- return false;
+ struct mp_image *tmp1 = mp_image_alloc(IMGFMT_BGRA, d->w, d->h);
+ struct mp_image *tmp2 = mp_image_alloc(IMGFMT_BGRA, d->w, d->h);
+ if (tmp1 && tmp2) { // on OOM, skip region
+ struct mp_image s = {0};
+ mp_image_setfmt(&s, IMGFMT_BGRA);
+ mp_image_set_size(&s, d->w, d->h);
+ s.stride[0] = d->stride;
+ s.planes[0] = d->bitmap;
- talloc_free(c->parts);
- imgs->parts = c->parts = talloc_array(c, struct sub_bitmap, src.num_parts);
+ mp_image_copy(tmp1, &s);
- for (int n = 0; n < src.num_parts; n++) {
- struct sub_bitmap *d = &imgs->parts[n];
- struct sub_bitmap *s = &src.parts[n];
+ mp_image_sw_blur_scale(tmp2, tmp1, gblur);
- // add a transparent padding border to reduce artifacts
- int pad = 5;
- struct mp_image *temp = mp_image_alloc(IMGFMT_BGRA, s->w + pad * 2,
- s->h + pad * 2);
- if (!temp)
- continue; // on OOM, skip region
- 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 = mp_image_alloc(IMGFMT_BGRA, d->w, d->h);
- talloc_steal(c->parts, image);
- if (image) {
- d->stride = image->stride[0];
- d->bitmap = image->planes[0];
-
- mp_image_sw_blur_scale(image, temp, gblur);
- } else {
- // on OOM, skip region
- *d = *s;
- }
-
- talloc_free(temp);
+ mp_image_copy(&s, tmp2);
}
- return true;
+ talloc_free(tmp1);
+ talloc_free(tmp2);
}
// If RGBA parts need scaling, scale them.
diff --git a/sub/img_convert.h b/sub/img_convert.h
index d5baadced2..a0020df497 100644
--- a/sub/img_convert.h
+++ b/sub/img_convert.h
@@ -5,6 +5,7 @@
struct osd_conv_cache;
struct sub_bitmaps;
+struct sub_bitmap;
struct mp_rect;
struct osd_conv_cache *osd_conv_cache_new(void);
@@ -13,8 +14,7 @@ struct osd_conv_cache *osd_conv_cache_new(void);
// the converted image data into c, and change imgs to point to the data.
bool osd_conv_ass_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs);
// Sub postprocessing
-bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs,
- double gblur);
+void mp_blur_rgba_sub_bitmap(struct sub_bitmap *d, double gblur);
bool osd_scale_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs);
bool mp_sub_bitmaps_bb(struct sub_bitmaps *imgs, struct mp_rect *out_bb);
diff --git a/sub/osd.c b/sub/osd.c
index ea33961c9f..a0618aafd9 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -295,10 +295,6 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
bool cached = false; // do we have a copy of all the image data?
- if (out_imgs->format == SUBBITMAP_RGBA && opts->sub_gauss != 0.0f)
- cached |= osd_conv_blur_rgba(obj->cache[2], out_imgs, opts->sub_gauss);
-
- // Do this conversion last to not trigger gauss blurring for ASS
if (formats[SUBBITMAP_RGBA] && out_imgs->format == SUBBITMAP_LIBASS)
cached |= osd_conv_ass_to_rgba(obj->cache[3], out_imgs);
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index a5f093bb54..fca4b611bf 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -32,6 +32,7 @@
#include "options/options.h"
#include "video/mp_image.h"
#include "video/out/bitmap_packer.h"
+#include "img_convert.h"
#include "sd.h"
#include "dec_sub.h"
@@ -209,8 +210,14 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
packer_set_size(priv->packer, avsub->num_rects);
+ // If we blur, we want a transparent region around the bitmap data to
+ // avoid "cut off" artifacts on the borders.
+ bool apply_blur = opts->sub_gauss != 0.0f;
+ int extend = apply_blur ? 5 : 0;
// Assume consumers may use bilinear scaling on it (2x2 filter)
- priv->packer->padding = 1;
+ int padding = 1 + extend;
+
+ priv->packer->padding = padding;
for (int i = 0; i < avsub->num_rects; i++) {
struct AVSubtitleRect *r = avsub->rects[i];
@@ -278,11 +285,12 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
memcpy(pal, data[1], r->nb_colors * 4);
convert_pal(pal, 256, opts->sub_gray);
- int padding = priv->packer->padding;
- for (int y = 0; y < b->h + padding; y++) {
+ for (int y = -padding; y < b->h + padding; y++) {
uint32_t *out = (uint32_t*)((char*)b->bitmap + y * b->stride);
int start = 0;
- if (y < b->h) {
+ for (int x = -padding; x < 0; x++)
+ out[x] = 0;
+ if (y >= 0 && y < b->h) {
uint8_t *in = data[0] + y * linesize[0];
for (int x = 0; x < b->w; x++)
*out++ = pal[*in++];
@@ -291,6 +299,15 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
for (int x = start; x < b->w + padding; x++)
*out++ = 0;
}
+
+ b->bitmap = (char*)b->bitmap - extend * b->stride - extend * 4;
+ b->x -= extend;
+ b->y -= extend;
+ b->w += extend * 2;
+ b->h += extend * 2;
+
+ if (apply_blur)
+ mp_blur_rgba_sub_bitmap(b, opts->sub_gauss);
}
}