1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-28 01:52:19 +00:00

sub/osd: fix rounding when rescaling bitmap subtitle rects

With multiple rects touching each other without any gaps, the current
scale method can cause gaps or overlaps between rects. To make sure that
this does not happen, scale on the edges of the rects instead, and then
calculate the width and height from the results.

NB: while this is better than the status quo, it does not fix all
scaling artifacts because of the following:

- When two rects share a vertical edge but have different heights,
  misalignment will occur: after rounding rect heights to pixels,
  the height scale factor for the two rects will be slightly different.
  As a result, there will be misalignment between the scaled images.
- With a GPU renderer, different bitmap subtitle parts are rendered as
  different textures. This means that the pixel contents of the parts have
  different boundary conditions from the whole combined image. As a result,
  there will still be small gaps when the subtitle is scaled up.

The only way to properly address these points is to make sure that the
parts are combined to a single image at the native resolution before
being scaled. This can be partly achieved with --blend-subtitles=video.
This commit is contained in:
nanahi 2024-05-01 21:56:01 -04:00 committed by Kacper Michajłow
parent e20ca15b66
commit dec73f503f

View File

@ -515,10 +515,16 @@ void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,
int cy = vidh / 2 - (int)(frame_h * yscale) / 2;
for (int i = 0; i < imgs->num_parts; i++) {
struct sub_bitmap *bi = &imgs->parts[i];
bi->x = (int)(bi->x * xscale) + cx + res.ml;
bi->y = (int)(bi->y * yscale) + cy + res.mt;
bi->dw = (int)(bi->w * xscale + 0.5);
bi->dh = (int)(bi->h * yscale + 0.5);
struct mp_rect rc = {
.x0 = lrint(bi->x * xscale),
.y0 = lrint(bi->y * yscale),
.x1 = lrint((bi->x + bi->w) * xscale),
.y1 = lrint((bi->y + bi->h) * yscale),
};
bi->x = rc.x0 + cx + res.ml;
bi->y = rc.y0 + cy + res.mt;
bi->dw = mp_rect_w(rc);
bi->dh = mp_rect_h(rc);
}
}