diff options
-rw-r--r-- | DOCS/man/en/changes.rst | 2 | ||||
-rw-r--r-- | DOCS/man/en/options.rst | 6 | ||||
-rw-r--r-- | core/cfg-mplayer.h | 1 | ||||
-rw-r--r-- | core/options.h | 1 | ||||
-rw-r--r-- | sub/img_convert.c | 35 | ||||
-rw-r--r-- | sub/img_convert.h | 2 | ||||
-rw-r--r-- | sub/sub.c | 7 |
7 files changed, 51 insertions, 3 deletions
diff --git a/DOCS/man/en/changes.rst b/DOCS/man/en/changes.rst index b46691c888..eeafd537a9 100644 --- a/DOCS/man/en/changes.rst +++ b/DOCS/man/en/changes.rst @@ -64,7 +64,7 @@ General changes for mplayer2 to mpv handle these use cases. For yuv4mpeg, for example, use: ``mpv input.mkv -o output.y4m --no-audio``. * Image subtitles (DVDs etc.) are rendered in color and use more correct - positioning + positioning (color can be disabled with ``--sub-gray``) * General code cleanups * Many more changes diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index f0d9ddb57b..15007e03fc 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1889,6 +1889,12 @@ *NOTE*: never applied to text subtitles. +--sub-gray + Convert image subtitles to grayscale. Can help making yellow DVD/Vobsubs + look nicer. + + *NOTE*: never affects text subtitles. + --sub-pos=<0-100> Specify the position of subtitles on the screen. The value is the vertical position of the subtitle in % of the screen height. diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index ded7245f83..23b937f91a 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -507,6 +507,7 @@ const m_option_t common_opts[] = { M_CHOICES(({"exact", 0}, {"fuzzy", 1}, {"all", 2}))}, {"sub-pos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL}, OPT_FLOATRANGE("sub-gauss", sub_gauss, 0, 0.0, 3.0), + OPT_MAKE_FLAGS("sub-gray", sub_gray, 0), OPT_MAKE_FLAGS("ass", ass_enabled, 0), OPT_FLOATRANGE("sub-scale", sub_scale, 0, 0, 100), OPT_FLOATRANGE("ass-line-spacing", ass_line_spacing, 0, -1000, 1000), diff --git a/core/options.h b/core/options.h index 58d6a64e70..47f4593b9b 100644 --- a/core/options.h +++ b/core/options.h @@ -114,6 +114,7 @@ typedef struct MPOpts { struct osd_style_opts *osd_style; float sub_scale; float sub_gauss; + int sub_gray; int ass_enabled; float ass_line_spacing; int ass_top_margin; diff --git a/sub/img_convert.c b/sub/img_convert.c index 274a83d833..578a20b646 100644 --- a/sub/img_convert.c +++ b/sub/img_convert.c @@ -128,3 +128,38 @@ bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs, } return true; } + +static void rgba_to_gray(uint32_t *colors, size_t count) +{ + for (int n = 0; n < count; n++) { + uint32_t c = colors[n]; + int b = c & 0xFF; + int g = (c >> 8) & 0xFF; + int r = (c >> 16) & 0xFF; + int a = (c >> 24) & 0xFF; + r = g = b = (r + g + b) / 3; + colors[n] = b | (g << 8) | (r << 16) | (a << 24); + } +} + +bool osd_conv_idx_to_gray(struct osd_conv_cache *c, struct sub_bitmaps *imgs) +{ + struct sub_bitmaps src = *imgs; + if (src.format != SUBBITMAP_INDEXED) + 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]; + struct osd_bmp_indexed sb = *(struct osd_bmp_indexed *)s->bitmap; + + rgba_to_gray(sb.palette, 256); + + *d = *s; + d->bitmap = talloc_memdup(c->parts, &sb, sizeof(sb)); + } + return true; +} diff --git a/sub/img_convert.h b/sub/img_convert.h index eab543051c..2ea17ef889 100644 --- a/sub/img_convert.h +++ b/sub/img_convert.h @@ -11,7 +11,9 @@ 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); +// Sub postprocessing bool osd_conv_blur_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs, double gblur); +bool osd_conv_idx_to_gray(struct osd_conv_cache *c, struct sub_bitmaps *imgs); #endif @@ -221,11 +221,14 @@ 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_INDEXED && opts->sub_gray) + cached |= osd_conv_idx_to_gray(obj->cache[0], out_imgs); + if (formats[SUBBITMAP_RGBA] && out_imgs->format == SUBBITMAP_INDEXED) - cached |= osd_conv_idx_to_rgba(obj->cache[0], out_imgs); + cached |= osd_conv_idx_to_rgba(obj->cache[1], 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); + cached |= osd_conv_blur_rgba(obj->cache[2], out_imgs, opts->sub_gauss); if (cached) obj->cached = *out_imgs; |