sub: add --sub-gray option to display image subs in grayscale

MPlayer/mplayer2 still show DVD subtitles in gray. Depending on who you
ask, this can be considered a bug or a feature. Include rendering in
gray as explicit feature, so the user can decide what is better.

This affects all indexed sub bitmaps entering the OSD rendering path.
Currently, this means all image subs are affected by this option, but
nothing else.
This commit is contained in:
wm4 2012-11-25 23:32:35 +01:00
parent 24bfa82a91
commit 5d5ddb2ad0
7 changed files with 51 additions and 3 deletions

View File

@ -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

View File

@ -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.

View File

@ -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),

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;