mirror of https://github.com/mpv-player/mpv
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:
parent
24bfa82a91
commit
5d5ddb2ad0
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue